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
| | require_relative 'helper'
class TestKqueue < Test::Unit::TestCase
include SleepyPenguin
def test_kqueue
kq = Kqueue.new
assert_kind_of IO, kq.to_io
assert_predicate kq.to_io, :close_on_exec?
rd, wr = IO.pipe
ev = Kevent[rd.fileno, EvFilt::READ, Ev::ADD|Ev::ONESHOT, 0, 0, rd]
thr = Thread.new do
kq.kevent(ev)
wr.syswrite "."
end
events = []
n = kq.kevent(nil, 1) do |kevent|
assert_kind_of Kevent, kevent
events << kevent
end
assert_equal 1, events.size
assert_equal rd.fileno, events[0][0]
assert_equal EvFilt::READ, events[0][1]
assert_equal 1, n
# we should be drained
events = []
n = kq.kevent(nil, 1, 0) do |kevent|
assert_kind_of Kevent, kevent
events << kevent
end
assert_equal 0, events.size
assert_equal 0, n
thr.join
# synchronous add
events = []
ev = Kevent[wr.fileno, EvFilt::WRITE, Ev::ADD|Ev::ONESHOT, 0, 0, wr]
kq.kevent(ev)
n = kq.kevent(nil, 1, 0) do |kevent|
assert_kind_of Kevent, kevent
events << kevent
end
assert_equal 1, events.size
assert_equal wr.fileno, events[0][0]
assert_equal EvFilt::WRITE, events[0][1]
assert_equal 1, n
ensure
kq.close
rd.close if rd
wr.close if wr
end
def test_usable_after_fork
kq = Kqueue.new
pid = fork do
begin
ok = false
assert_equal(0, kq.kevent(nil, 1, 0.1) { exit!(false) })
ok = true
ensure
exit!(ok)
end
end
assert_equal(0, kq.kevent(nil, 1, 0.1) { exit!(false) })
_, status = Process.waitpid2(pid)
assert status.success?, status.inspect
ensure
kq.close
end
def test_epoll_nest
kq1 = Kqueue.new
kq2 = Kqueue.new
r1, w1 = IO.pipe
r2, w2 = IO.pipe
w1.write '.'
w2.write '.'
kq1.kevent([
Kevent[r1.fileno, EvFilt::READ, Ev::ADD, 0, 0, r1],
Kevent[w1.fileno, EvFilt::WRITE, Ev::ADD, 0, 0, w1]
])
kq2.kevent([
Kevent[r2.fileno, EvFilt::READ, Ev::ADD, 0, 0, r2],
Kevent[w2.fileno, EvFilt::WRITE, Ev::ADD, 0, 0, w2]
])
outer = []
inner = []
nr = 0
kq1.kevent(nil, 2) do |kev1|
outer << kev1.udata
kq2.kevent(nil, 2) do |kev2|
(inner[nr] ||= []) << kev2.udata
end
nr += 1
end
assert_equal [ r1, w1 ].sort_by(&:fileno), outer.sort_by(&:fileno)
exp = [ r2, w2 ].sort_by(&:fileno)
assert_equal [ exp, exp ], inner.map { |x| x.sort_by(&:fileno) }
ensure
[ r1, w1, r2, w2, kq1, kq2 ].compact.each(&:close)
end
end if defined?(SleepyPenguin::Kqueue)
|