1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
| | require 'test/unit'
$-w = true
require 'kgio'
class TestPoll < Test::Unit::TestCase
def teardown
[ @rd, @wr ].each { |io| io.close unless io.closed? }
end
def setup
@rd, @wr = IO.pipe
end
def test_constants
assert_kind_of Integer, Kgio::POLLIN
assert_kind_of Integer, Kgio::POLLOUT
assert_kind_of Integer, Kgio::POLLPRI
assert_kind_of Integer, Kgio::POLLHUP
assert_kind_of Integer, Kgio::POLLERR
assert_kind_of Integer, Kgio::POLLNVAL
end
def test_poll_symbol
set = { @rd => :wait_readable, @wr => :wait_writable }
res = Kgio.poll(set)
assert_equal({@wr => Kgio::POLLOUT}, res)
assert_equal set.object_id, res.object_id
end
def test_poll_integer
set = { @wr => Kgio::POLLOUT|Kgio::POLLHUP }
res = Kgio.poll(set)
assert_equal({@wr => Kgio::POLLOUT}, res)
assert_equal set.object_id, res.object_id
end
def test_poll_timeout
t0 = Time.now
res = Kgio.poll({}, 10)
diff = Time.now - t0
assert diff >= 0.010, "diff=#{diff}"
assert_nil res
end
def test_poll_close
foo = nil
thr = Thread.new { sleep 0.100; @wr.close }
t0 = Time.now
res = Kgio.poll({@rd => Kgio::POLLIN})
diff = Time.now - t0
thr.join
assert_equal([ @rd ], res.keys)
assert diff >= 0.010, "diff=#{diff}"
end
def test_signal_close
orig = trap(:USR1) { @rd.close }
res = nil
thr = Thread.new { sleep 0.100; Process.kill(:USR1, $$) }
t0 = Time.now
assert_raises(IOError) do
result = Kgio.poll({@rd => Kgio::POLLIN})
result.each_key { |io| io.read_nonblock(1) }
end
diff = Time.now - t0
thr.join
assert diff >= 0.010, "diff=#{diff}"
ensure
trap(:USR1, orig)
end
def test_poll_EINTR
ok = false
orig = trap(:USR1) { ok = true }
thr = Thread.new do
sleep 0.100
Process.kill(:USR1, $$)
end
t0 = Time.now
res = Kgio.poll({@rd => Kgio::POLLIN}, 1000)
diff = Time.now - t0
thr.join
assert_nil res
assert diff >= 1.0, "diff=#{diff}"
assert ok
ensure
trap(:USR1, orig)
end
def test_poll_EINTR_changed
ok = false
orig = trap(:USR1) { ok = true }
pollset = { @rd => Kgio::POLLIN }
thr = Thread.new do
sleep 0.100
pollset[@wr] = Kgio::POLLOUT
Process.kill(:USR1, $$)
end
t0 = Time.now
res = Kgio.poll(pollset, 1000)
diff = Time.now - t0
thr.join
assert_equal({@wr => Kgio::POLLOUT}, res)
assert diff < 1.0, "diff=#{diff}"
assert ok
ensure
trap(:USR1, orig)
end
def test_poll_signal_torture
usr1 = 0
empty = 0
nr = 100
set = { @rd => Kgio::POLLIN }
trap(:USR1) { usr1 += 1 }
pid = fork do
trap(:USR1, "DEFAULT")
sleep 0.1
ppid = Process.ppid
nr.times { Process.kill(:USR1, ppid); sleep 0.05 }
@wr.syswrite('.')
exit!(0)
end
empty += 1 until Kgio.poll(set.dup, 100)
_, status = Process.waitpid2(pid)
assert status.success?, status.inspect
assert usr1 > 0, "usr1: #{usr1}"
rescue Object => err
p [ :err, err ]
ensure
trap(:USR1, "DEFAULT")
end
end if Kgio.respond_to?(:poll)
|