Revert "epoll: avoid EPOLL_CTL_MOD race condition"
[sleepy_penguin.git] / test / test_epoll_optimizations.rb
blobbd773979fa1d9905b418d89b0832dd3ee7f322dd
1 require 'test/unit'
2 begin
3   require 'strace'
4 rescue LoadError
5 end
6 $-w = true
8 require 'sleepy_penguin'
10 class TestEpollOptimizations < Test::Unit::TestCase
11   include SleepyPenguin
12   RBX = defined?(RUBY_ENGINE) && (RUBY_ENGINE == 'rbx')
13   IO_PURGATORY = []
15   def setup
16     @rd, @wr = IO.pipe
17     @ep = Epoll.new
18   end
20   def teardown
21     [ @ep, @rd, @wr ].each { |io| io.close unless io.closed? }
22   end
24   def test_set
25     io, err = Strace.me do
26       @ep.set(@wr, Epoll::OUT)
27       @ep.set(@wr, Epoll::OUT)
28     end
29     assert_nil err
30     lines = io.readlines; io.close
31     assert_equal 1, lines.grep(/^epoll_ctl/).size
32     assert_match(/EPOLL_CTL_ADD/, lines.grep(/^epoll_ctl/)[0])
34     io, err = Strace.me { @ep.set(@wr, Epoll::OUT | Epoll::ONESHOT) }
35     assert_nil err
36     lines = io.readlines; io.close
37     assert_equal 1, lines.grep(/^epoll_ctl/).size
38     assert_match(/EPOLL_CTL_MOD/, lines.grep(/^epoll_ctl/)[0])
40     io, err = Strace.me { @ep.set(@wr, Epoll::OUT) }
41     assert_nil err
42     lines = io.readlines; io.close
43     assert_equal 1, lines.grep(/^epoll_ctl/).size
44     assert_match(/EPOLL_CTL_MOD/, lines.grep(/^epoll_ctl/)[0])
45     @wr.close
46     @rd.close
48     @rd, @wr = IO.pipe
49     io, err = Strace.me { @ep.set(@wr, Epoll::OUT) }
50     assert_nil err
51     lines = io.readlines; io.close
52     assert_equal 1, lines.grep(/^epoll_ctl/).size
53     assert_match(/EPOLL_CTL_ADD/, lines.grep(/^epoll_ctl/)[0])
54   end
56   def test_delete
57     @ep.set(@wr, Epoll::OUT)
58     rv = true
59     io, err = Strace.me { rv = @ep.delete(@wr) }
60     assert_equal @wr, rv
61     assert_nil err
62     lines = io.readlines; io.close
63     assert_equal 1, lines.grep(/^epoll_ctl/).size
64     assert_match(%r{=\s+0$}, lines.grep(/^epoll_ctl/)[0])
66     rv = true
67     io, err = Strace.me { rv = @ep.delete(@wr) }
68     assert_nil rv
69     assert_nil err
70     lines = io.readlines; io.close
71     assert_equal 0, lines.grep(/^epoll_ctl/).size
72   end
74   def test_delete_closed
75     a = @wr.fileno
76     @ep.set(@wr, Epoll::OUT)
77     @rd.close
78     @wr.close
79     @rd, @wr = IO.pipe
80     assert_equal a, @wr.fileno
81     rv = true
82     io, err = Strace.me { rv = @ep.delete(@wr) }
83     lines = io.readlines; io.close
84     assert_nil err
85     assert_nil rv
86     assert_equal 0, lines.grep(/^epoll_ctl/).size
87   end
89   def test_delete_closed_proxy
90     obj = Struct.new(:to_io).new(@wr)
91     rv = nil
92     @ep.add(obj, Epoll::OUT)
93     @wr.close
94     io, err = Strace.me { rv = @ep.delete(obj) }
95     lines = io.readlines; io.close
96     assert_kind_of IOError, err
97     assert_nil rv
98     assert_equal 0, lines.grep(/^epoll_ctl/).size
99   end
101   def test_delete_aliased_a
102     tmp = IO.for_fd @wr.fileno
103     IO_PURGATORY << tmp
104     @ep.set(tmp, Epoll::OUT)
105     rv = nil
106     io, err = Strace.me { rv = @ep.delete(@wr) }
107     lines = io.readlines; io.close
108     assert_equal @wr, rv
109     assert_nil err
110     assert_equal 1, lines.grep(/^epoll_ctl/).size
111     assert_match %r{=\s+0$}, lines.grep(/^epoll_ctl/)[0]
112     assert_equal 0, lines.grep(/ENOENT/).size
113   end
115   def test_delete_aliased_b
116     tmp = IO.for_fd @wr.fileno
117     IO_PURGATORY << tmp
118     @ep.set(@wr, Epoll::OUT)
119     rv = nil
120     io, err = Strace.me { rv = @ep.delete(tmp) }
121     lines = io.readlines; io.close
122     assert_equal tmp, rv
123     assert_nil err
124     assert_equal 1, lines.grep(/^epoll_ctl/).size
125     assert_match(%r{=\s+0$}, lines.grep(/^epoll_ctl/)[0])
126     assert_equal 0, lines.grep(/ENOENT/).size
127   end
129   def test_delete_aliased_closed
130     tmp = IO.for_fd @wr.fileno
131     IO_PURGATORY << tmp
132     @ep.set(tmp, Epoll::OUT)
133     @wr.close
134     rv = nil
135     io, err = Strace.me { rv = @ep.delete(tmp) }
136     lines = io.readlines; io.close
137     assert_nil rv
138     assert_nil err
139     assert_equal 1, lines.grep(/^epoll_ctl/).size
140     assert_equal 1, lines.grep(/EBADF/).size
141   end
142 end if defined?(Strace)