polyphony 0.59.1 → 0.63
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/Gemfile.lock +15 -29
- data/Rakefile +1 -1
- data/examples/core/message_based_supervision.rb +51 -0
- data/examples/io/echo_server.rb +16 -7
- data/ext/polyphony/backend_common.c +83 -16
- data/ext/polyphony/backend_common.h +15 -3
- data/ext/polyphony/backend_io_uring.c +58 -25
- data/ext/polyphony/backend_io_uring_context.c +10 -1
- data/ext/polyphony/backend_io_uring_context.h +5 -3
- data/ext/polyphony/backend_libev.c +52 -20
- data/ext/polyphony/extconf.rb +2 -2
- data/ext/polyphony/fiber.c +1 -32
- data/ext/polyphony/polyphony.c +12 -12
- data/ext/polyphony/polyphony.h +4 -5
- data/ext/polyphony/queue.c +12 -12
- data/ext/polyphony/runqueue.c +11 -19
- data/ext/polyphony/runqueue.h +2 -2
- data/ext/polyphony/thread.c +0 -18
- data/lib/polyphony/extensions/fiber.rb +100 -80
- data/lib/polyphony/extensions/io.rb +15 -10
- data/lib/polyphony/extensions/openssl.rb +28 -4
- data/lib/polyphony/extensions/socket.rb +66 -15
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +0 -7
- data/test/test_backend.rb +69 -6
- data/test/test_ext.rb +1 -1
- data/test/test_fiber.rb +106 -18
- data/test/test_global_api.rb +1 -1
- data/test/test_io.rb +49 -0
- data/test/test_socket.rb +39 -1
- data/test/test_supervise.rb +100 -100
- data/test/test_thread_pool.rb +1 -1
- data/test/test_trace.rb +5 -4
- metadata +4 -107
@@ -101,16 +101,20 @@ class ::IO
|
|
101
101
|
return @read_buffer.slice!(0) if @read_buffer && !@read_buffer.empty?
|
102
102
|
|
103
103
|
@read_buffer ||= +''
|
104
|
-
Polyphony.backend_read(self, @read_buffer, 8192, false)
|
104
|
+
Polyphony.backend_read(self, @read_buffer, 8192, false, -1)
|
105
105
|
return @read_buffer.slice!(0) if !@read_buffer.empty?
|
106
106
|
|
107
107
|
nil
|
108
108
|
end
|
109
109
|
|
110
110
|
alias_method :orig_read, :read
|
111
|
-
def read(len = nil)
|
111
|
+
def read(len = nil, buf = nil, buf_pos = 0)
|
112
|
+
if buf
|
113
|
+
return Polyphony.backend_read(self, buf, len, true, buf_pos)
|
114
|
+
end
|
115
|
+
|
112
116
|
@read_buffer ||= +''
|
113
|
-
result = Polyphony.backend_read(self, @read_buffer, len, true)
|
117
|
+
result = Polyphony.backend_read(self, @read_buffer, len, true, -1)
|
114
118
|
return nil unless result
|
115
119
|
|
116
120
|
already_read = @read_buffer
|
@@ -119,8 +123,8 @@ class ::IO
|
|
119
123
|
end
|
120
124
|
|
121
125
|
alias_method :orig_readpartial, :read
|
122
|
-
def readpartial(len, str = +'')
|
123
|
-
result = Polyphony.backend_read(self, str, len, false)
|
126
|
+
def readpartial(len, str = +'', buffer_pos = 0)
|
127
|
+
result = Polyphony.backend_read(self, str, len, false, buffer_pos)
|
124
128
|
raise EOFError unless result
|
125
129
|
|
126
130
|
result
|
@@ -151,9 +155,10 @@ class ::IO
|
|
151
155
|
idx = @read_buffer.index(sep)
|
152
156
|
return @read_buffer.slice!(0, idx + sep_size) if idx
|
153
157
|
|
154
|
-
|
155
|
-
|
156
|
-
@read_buffer
|
158
|
+
result = readpartial(8192, @read_buffer, -1)
|
159
|
+
|
160
|
+
#Polyphony.backend_read(self, @read_buffer, 8192, false, -1)
|
161
|
+
return nil unless result
|
157
162
|
end
|
158
163
|
rescue EOFError
|
159
164
|
return nil
|
@@ -216,8 +221,8 @@ class ::IO
|
|
216
221
|
buf ? readpartial(maxlen, buf) : readpartial(maxlen)
|
217
222
|
end
|
218
223
|
|
219
|
-
def read_loop(&block)
|
220
|
-
Polyphony.backend_read_loop(self, &block)
|
224
|
+
def read_loop(maxlen = 8192, &block)
|
225
|
+
Polyphony.backend_read_loop(self, maxlen, &block)
|
221
226
|
end
|
222
227
|
|
223
228
|
def feed_loop(receiver, method = :call, &block)
|
@@ -64,13 +64,37 @@ class ::OpenSSL::SSL::SSLSocket
|
|
64
64
|
# @sync = osync
|
65
65
|
end
|
66
66
|
|
67
|
-
|
68
|
-
|
67
|
+
alias_method :orig_read, :read
|
68
|
+
def read(maxlen = nil, buf = nil, buf_pos = 0)
|
69
|
+
return readpartial(maxlen, buf, buf_pos) if buf
|
70
|
+
|
71
|
+
buf = +''
|
72
|
+
return readpartial(maxlen, buf) if maxlen
|
73
|
+
|
74
|
+
while true
|
75
|
+
readpartial(4096, buf, -1)
|
76
|
+
end
|
77
|
+
rescue EOFError
|
78
|
+
buf
|
79
|
+
end
|
80
|
+
|
81
|
+
def readpartial(maxlen, buf = +'', buffer_pos = 0)
|
82
|
+
if buffer_pos != 0
|
83
|
+
if (result = sysread(maxlen, +''))
|
84
|
+
if buffer_pos == -1
|
85
|
+
result = buf + result
|
86
|
+
else
|
87
|
+
result = buf[0...buffer_pos] + result
|
88
|
+
end
|
89
|
+
end
|
90
|
+
else
|
91
|
+
result = sysread(maxlen, buf)
|
92
|
+
end
|
69
93
|
result || (raise EOFError)
|
70
94
|
end
|
71
95
|
|
72
|
-
def read_loop
|
73
|
-
while (data = sysread(
|
96
|
+
def read_loop(maxlen = 8192)
|
97
|
+
while (data = sysread(maxlen))
|
74
98
|
yield data
|
75
99
|
end
|
76
100
|
end
|
@@ -22,12 +22,29 @@ class ::Socket
|
|
22
22
|
Polyphony.backend_connect(self, addr.ip_address, addr.ip_port)
|
23
23
|
end
|
24
24
|
|
25
|
+
alias_method :orig_read, :read
|
26
|
+
def read(maxlen = nil, buf = nil, buf_pos = 0)
|
27
|
+
return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
|
28
|
+
return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
|
29
|
+
|
30
|
+
buf = +''
|
31
|
+
len = buf.bytesize
|
32
|
+
while true
|
33
|
+
Polyphony.backend_recv(self, buf, maxlen || 4096, -1)
|
34
|
+
new_len = buf.bytesize
|
35
|
+
break if new_len == len
|
36
|
+
|
37
|
+
len = new_len
|
38
|
+
end
|
39
|
+
buf
|
40
|
+
end
|
41
|
+
|
25
42
|
def recv(maxlen, flags = 0, outbuf = nil)
|
26
|
-
Polyphony.backend_recv(self, outbuf || +'', maxlen)
|
43
|
+
Polyphony.backend_recv(self, outbuf || +'', maxlen, 0)
|
27
44
|
end
|
28
45
|
|
29
|
-
def recv_loop(&block)
|
30
|
-
Polyphony.backend_recv_loop(self, &block)
|
46
|
+
def recv_loop(maxlen = 8192, &block)
|
47
|
+
Polyphony.backend_recv_loop(self, maxlen, &block)
|
31
48
|
end
|
32
49
|
alias_method :read_loop, :recv_loop
|
33
50
|
|
@@ -60,8 +77,8 @@ class ::Socket
|
|
60
77
|
# Polyphony.backend_send(self, mesg, 0)
|
61
78
|
# end
|
62
79
|
|
63
|
-
def readpartial(maxlen, str = +'')
|
64
|
-
Polyphony.backend_recv(self, str, maxlen)
|
80
|
+
def readpartial(maxlen, str = +'', buffer_pos = 0)
|
81
|
+
Polyphony.backend_recv(self, str, maxlen, buffer_pos)
|
65
82
|
end
|
66
83
|
|
67
84
|
ZERO_LINGER = [0, 0].pack('ii').freeze
|
@@ -140,12 +157,29 @@ class ::TCPSocket
|
|
140
157
|
setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_REUSEPORT, 1)
|
141
158
|
end
|
142
159
|
|
160
|
+
alias_method :orig_read, :read
|
161
|
+
def read(maxlen = nil, buf = nil, buf_pos = 0)
|
162
|
+
return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
|
163
|
+
return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
|
164
|
+
|
165
|
+
buf = +''
|
166
|
+
len = buf.bytesize
|
167
|
+
while true
|
168
|
+
Polyphony.backend_recv(self, buf, maxlen || 4096, -1)
|
169
|
+
new_len = buf.bytesize
|
170
|
+
break if new_len == len
|
171
|
+
|
172
|
+
len = new_len
|
173
|
+
end
|
174
|
+
buf
|
175
|
+
end
|
176
|
+
|
143
177
|
def recv(maxlen, flags = 0, outbuf = nil)
|
144
|
-
Polyphony.backend_recv(self, outbuf || +'', maxlen)
|
178
|
+
Polyphony.backend_recv(self, outbuf || +'', maxlen, 0)
|
145
179
|
end
|
146
180
|
|
147
|
-
def recv_loop(&block)
|
148
|
-
Polyphony.backend_recv_loop(self, &block)
|
181
|
+
def recv_loop(maxlen = 8192, &block)
|
182
|
+
Polyphony.backend_recv_loop(self, maxlen, &block)
|
149
183
|
end
|
150
184
|
alias_method :read_loop, :recv_loop
|
151
185
|
|
@@ -165,8 +199,8 @@ class ::TCPSocket
|
|
165
199
|
# Polyphony.backend_send(self, mesg, 0)
|
166
200
|
# end
|
167
201
|
|
168
|
-
def readpartial(maxlen, str = +'')
|
169
|
-
result = Polyphony.backend_recv(self, str, maxlen)
|
202
|
+
def readpartial(maxlen, str = +'', buffer_pos = 0)
|
203
|
+
result = Polyphony.backend_recv(self, str, maxlen, buffer_pos)
|
170
204
|
raise EOFError unless result
|
171
205
|
|
172
206
|
str
|
@@ -217,12 +251,29 @@ class ::UNIXServer
|
|
217
251
|
end
|
218
252
|
|
219
253
|
class ::UNIXSocket
|
254
|
+
alias_method :orig_read, :read
|
255
|
+
def read(maxlen = nil, buf = nil, buf_pos = 0)
|
256
|
+
return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
|
257
|
+
return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
|
258
|
+
|
259
|
+
buf = +''
|
260
|
+
len = buf.bytesize
|
261
|
+
while true
|
262
|
+
Polyphony.backend_recv(self, buf, maxlen || 4096, -1)
|
263
|
+
new_len = buf.bytesize
|
264
|
+
break if new_len == len
|
265
|
+
|
266
|
+
len = new_len
|
267
|
+
end
|
268
|
+
buf
|
269
|
+
end
|
270
|
+
|
220
271
|
def recv(maxlen, flags = 0, outbuf = nil)
|
221
|
-
Polyphony.backend_recv(self, outbuf || +'', maxlen)
|
272
|
+
Polyphony.backend_recv(self, outbuf || +'', maxlen, 0)
|
222
273
|
end
|
223
274
|
|
224
|
-
def recv_loop(&block)
|
225
|
-
Polyphony.backend_recv_loop(self, &block)
|
275
|
+
def recv_loop(maxlen = 8192, &block)
|
276
|
+
Polyphony.backend_recv_loop(self, maxlen, &block)
|
226
277
|
end
|
227
278
|
alias_method :read_loop, :recv_loop
|
228
279
|
|
@@ -242,8 +293,8 @@ class ::UNIXSocket
|
|
242
293
|
Polyphony.backend_send(self, mesg, 0)
|
243
294
|
end
|
244
295
|
|
245
|
-
def readpartial(maxlen, str = +'')
|
246
|
-
result = Polyphony.backend_recv(self, str, maxlen)
|
296
|
+
def readpartial(maxlen, str = +'', buffer_pos = 0)
|
297
|
+
result = Polyphony.backend_recv(self, str, maxlen, buffer_pos)
|
247
298
|
raise EOFError unless result
|
248
299
|
|
249
300
|
str
|
data/lib/polyphony/version.rb
CHANGED
data/polyphony.gemspec
CHANGED
@@ -29,13 +29,6 @@ Gem::Specification.new do |s|
|
|
29
29
|
s.add_development_dependency 'pry', '0.13.1'
|
30
30
|
|
31
31
|
s.add_development_dependency 'msgpack', '1.4.2'
|
32
|
-
s.add_development_dependency 'pg', '1.1.4'
|
33
|
-
s.add_development_dependency 'redis', '4.1.0'
|
34
|
-
s.add_development_dependency 'hiredis', '0.6.3'
|
35
|
-
s.add_development_dependency 'http_parser.rb', '~>0.6.0'
|
36
|
-
s.add_development_dependency 'rack', '>=2.0.8', '<2.3.0'
|
37
|
-
s.add_development_dependency 'mysql2', '0.5.3'
|
38
|
-
s.add_development_dependency 'sequel', '5.34.0'
|
39
32
|
s.add_development_dependency 'httparty', '0.17.1'
|
40
33
|
s.add_development_dependency 'localhost', '~>1.1.4'
|
41
34
|
|
data/test/test_backend.rb
CHANGED
@@ -26,14 +26,14 @@ class BackendTest < MiniTest::Test
|
|
26
26
|
@backend.sleep 0.01
|
27
27
|
count += 1
|
28
28
|
}.await
|
29
|
-
|
29
|
+
assert_in_range 0.02..0.04, Time.now - t0
|
30
30
|
assert_equal 3, count
|
31
31
|
end
|
32
32
|
|
33
33
|
def test_write_read_partial
|
34
34
|
i, o = IO.pipe
|
35
35
|
buf = +''
|
36
|
-
f = spin { @backend.read(i, buf, 5, false) }
|
36
|
+
f = spin { @backend.read(i, buf, 5, false, 0) }
|
37
37
|
@backend.write(o, 'Hello world')
|
38
38
|
return_value = f.await
|
39
39
|
|
@@ -44,7 +44,7 @@ class BackendTest < MiniTest::Test
|
|
44
44
|
def test_write_read_to_eof_limited_buffer
|
45
45
|
i, o = IO.pipe
|
46
46
|
buf = +''
|
47
|
-
f = spin { @backend.read(i, buf, 5, true) }
|
47
|
+
f = spin { @backend.read(i, buf, 5, true, 0) }
|
48
48
|
@backend.write(o, 'Hello')
|
49
49
|
snooze
|
50
50
|
@backend.write(o, ' world')
|
@@ -59,7 +59,7 @@ class BackendTest < MiniTest::Test
|
|
59
59
|
def test_write_read_to_eof
|
60
60
|
i, o = IO.pipe
|
61
61
|
buf = +''
|
62
|
-
f = spin { @backend.read(i, buf, 10**6, true) }
|
62
|
+
f = spin { @backend.read(i, buf, 10**6, true, 0) }
|
63
63
|
@backend.write(o, 'Hello')
|
64
64
|
snooze
|
65
65
|
@backend.write(o, ' world')
|
@@ -71,6 +71,59 @@ class BackendTest < MiniTest::Test
|
|
71
71
|
assert_equal return_value, buf
|
72
72
|
end
|
73
73
|
|
74
|
+
def test_write_read_with_buffer_position
|
75
|
+
i, o = IO.pipe
|
76
|
+
buf = +'abcdefghij'
|
77
|
+
f = spin { @backend.read(i, buf, 20, false, 0) }
|
78
|
+
@backend.write(o, 'blah')
|
79
|
+
return_value = f.await
|
80
|
+
|
81
|
+
assert_equal 'blah', buf
|
82
|
+
assert_equal return_value, buf
|
83
|
+
|
84
|
+
buf = +'abcdefghij'
|
85
|
+
f = spin { @backend.read(i, buf, 20, false, -1) }
|
86
|
+
@backend.write(o, 'klmn')
|
87
|
+
return_value = f.await
|
88
|
+
|
89
|
+
assert_equal 'abcdefghijklmn', buf
|
90
|
+
assert_equal return_value, buf
|
91
|
+
|
92
|
+
buf = +'abcdefghij'
|
93
|
+
f = spin { @backend.read(i, buf, 20, false, 3) }
|
94
|
+
@backend.write(o, 'DEF')
|
95
|
+
return_value = f.await
|
96
|
+
|
97
|
+
assert_equal 'abcDEF', buf
|
98
|
+
assert_equal return_value, buf
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_read_concat_big
|
102
|
+
i, o = IO.pipe
|
103
|
+
|
104
|
+
body = " " * 4000
|
105
|
+
|
106
|
+
data = "post /?q=time&blah=blah HTTP/1\r\nHost: dev.realiteq.net\r\n\r\n" +
|
107
|
+
"get /?q=time HTTP/1.1\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}" +
|
108
|
+
"get /?q=time HTTP/1.1\r\nCookie: foo\r\nCookie: bar\r\n\r\n"
|
109
|
+
|
110
|
+
o << data
|
111
|
+
o.close
|
112
|
+
|
113
|
+
buf = +''
|
114
|
+
|
115
|
+
@backend.read(i, buf, 4096, false, -1)
|
116
|
+
assert_equal 4096, buf.bytesize
|
117
|
+
|
118
|
+
@backend.read(i, buf, 1, false, -1)
|
119
|
+
assert_equal 4097, buf.bytesize
|
120
|
+
|
121
|
+
@backend.read(i, buf, 4096, false, -1)
|
122
|
+
|
123
|
+
assert_equal data.bytesize, buf.bytesize
|
124
|
+
assert_equal data, buf
|
125
|
+
end
|
126
|
+
|
74
127
|
def test_waitpid
|
75
128
|
pid = fork do
|
76
129
|
@backend.post_fork
|
@@ -87,7 +140,7 @@ class BackendTest < MiniTest::Test
|
|
87
140
|
buf = []
|
88
141
|
f = spin do
|
89
142
|
buf << :ready
|
90
|
-
@backend.read_loop(i) { |d| buf << d }
|
143
|
+
@backend.read_loop(i, 8192) { |d| buf << d }
|
91
144
|
buf << :done
|
92
145
|
end
|
93
146
|
|
@@ -107,7 +160,7 @@ class BackendTest < MiniTest::Test
|
|
107
160
|
parent = spin do
|
108
161
|
f = spin do
|
109
162
|
buf << :ready
|
110
|
-
@backend.read_loop(i) { |d| buf << d }
|
163
|
+
@backend.read_loop(i, 8192) { |d| buf << d }
|
111
164
|
buf << :done
|
112
165
|
end
|
113
166
|
suspend
|
@@ -125,6 +178,16 @@ class BackendTest < MiniTest::Test
|
|
125
178
|
assert_equal [:ready, 'foo', 'bar'], buf
|
126
179
|
end
|
127
180
|
|
181
|
+
def test_read_loop_with_max_len
|
182
|
+
r, w = IO.pipe
|
183
|
+
|
184
|
+
w << 'foobar'
|
185
|
+
w.close
|
186
|
+
buf = []
|
187
|
+
@backend.read_loop(r, 3) { |data| buf << data }
|
188
|
+
assert_equal ['foo', 'bar'], buf
|
189
|
+
end
|
190
|
+
|
128
191
|
Net = Polyphony::Net
|
129
192
|
|
130
193
|
def test_accept
|
data/test/test_ext.rb
CHANGED
data/test/test_fiber.rb
CHANGED
@@ -43,6 +43,14 @@ class FiberTest < MiniTest::Test
|
|
43
43
|
f&.stop
|
44
44
|
end
|
45
45
|
|
46
|
+
def test_await_dead_children
|
47
|
+
f1 = spin { :foo }
|
48
|
+
f2 = spin { :bar }
|
49
|
+
2.times { snooze }
|
50
|
+
|
51
|
+
assert_equal [:foo, :bar], Fiber.await(f1, f2)
|
52
|
+
end
|
53
|
+
|
46
54
|
def test_await_from_multiple_fibers
|
47
55
|
buffer = []
|
48
56
|
f1 = spin {
|
@@ -348,12 +356,12 @@ class FiberTest < MiniTest::Test
|
|
348
356
|
assert_equal [:foo, :terminate], buffer
|
349
357
|
end
|
350
358
|
|
351
|
-
|
352
|
-
ruby -rbundler/setup -rpolyphony -e
|
359
|
+
CMD_TERMINATE_CHILD_FIBER = <<~BASH
|
360
|
+
ruby -rbundler/setup -rpolyphony -e'f = spin { sleep }; spin { sleep 0.1; f.terminate }; f.await' 2>&1
|
353
361
|
BASH
|
354
362
|
|
355
|
-
|
356
|
-
ruby -rbundler/setup -rpolyphony -e"
|
363
|
+
CMD_TERMINATE_MAIN_FIBER = <<~BASH
|
364
|
+
ruby -rbundler/setup -rpolyphony -e"spin { sleep 0.1; Thread.current.main_fiber.terminate }; begin; sleep; rescue Polyphony::Terminate; STDOUT << 'terminated'; end" 2>&1
|
357
365
|
BASH
|
358
366
|
|
359
367
|
def test_terminate_main_fiber
|
@@ -547,24 +555,38 @@ class FiberTest < MiniTest::Test
|
|
547
555
|
assert f.location =~ location
|
548
556
|
end
|
549
557
|
|
550
|
-
def
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
558
|
+
def test_monitor
|
559
|
+
child = nil
|
560
|
+
parent = spin do
|
561
|
+
child = spin { receive }
|
562
|
+
child.await
|
555
563
|
end
|
556
|
-
f.when_done { values << 42 }
|
557
564
|
|
558
565
|
snooze
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
566
|
+
child.monitor
|
567
|
+
spin { child << :foo }
|
568
|
+
|
569
|
+
msg = receive
|
570
|
+
assert_equal [child, :foo], msg
|
571
|
+
end
|
564
572
|
|
573
|
+
def test_unmonitor
|
574
|
+
child = nil
|
575
|
+
parent = spin(:parent) do
|
576
|
+
child = spin(:child) { receive }
|
577
|
+
child.await
|
578
|
+
end
|
579
|
+
|
580
|
+
snooze
|
581
|
+
child.monitor
|
582
|
+
spin { child << :foo }
|
565
583
|
snooze
|
566
|
-
|
567
|
-
|
584
|
+
|
585
|
+
child.unmonitor
|
586
|
+
|
587
|
+
Fiber.current << :bar
|
588
|
+
msg = receive
|
589
|
+
assert_equal :bar, msg
|
568
590
|
end
|
569
591
|
|
570
592
|
def test_children
|
@@ -732,6 +754,72 @@ class FiberTest < MiniTest::Test
|
|
732
754
|
assert_equal ['bar'], buffer
|
733
755
|
snooze
|
734
756
|
end
|
757
|
+
|
758
|
+
def test_detach
|
759
|
+
buf = []
|
760
|
+
child = nil
|
761
|
+
parent = spin(:parent) do
|
762
|
+
buf << :hi_from_parent
|
763
|
+
child = spin(:child) do
|
764
|
+
buf << :hi_from_child
|
765
|
+
# wait for message (from main fiber)
|
766
|
+
buf << receive
|
767
|
+
end
|
768
|
+
snooze
|
769
|
+
buf << :bye_from_parent
|
770
|
+
end
|
771
|
+
|
772
|
+
snooze
|
773
|
+
assert_equal parent, child.parent
|
774
|
+
child.detach
|
775
|
+
assert_equal Fiber.current, child.parent
|
776
|
+
parent.await
|
777
|
+
|
778
|
+
child << :bye
|
779
|
+
child.await
|
780
|
+
|
781
|
+
assert_equal [
|
782
|
+
:hi_from_parent,
|
783
|
+
:hi_from_child,
|
784
|
+
:bye_from_parent,
|
785
|
+
:bye
|
786
|
+
], buf
|
787
|
+
end
|
788
|
+
|
789
|
+
def test_attach
|
790
|
+
buf = []
|
791
|
+
child = nil
|
792
|
+
parent = spin(:parent) do
|
793
|
+
buf << :hi_from_parent
|
794
|
+
child = spin(:child) do
|
795
|
+
buf << :hi_from_child
|
796
|
+
# wait for message (from main fiber)
|
797
|
+
buf << receive
|
798
|
+
end
|
799
|
+
snooze
|
800
|
+
buf << :bye_from_parent
|
801
|
+
end
|
802
|
+
|
803
|
+
new_parent = spin(:new_parent) { buf << receive }
|
804
|
+
|
805
|
+
snooze
|
806
|
+
assert_equal parent, child.parent
|
807
|
+
child.attach(new_parent)
|
808
|
+
assert_equal new_parent, child.parent
|
809
|
+
parent.await
|
810
|
+
|
811
|
+
child << :bye
|
812
|
+
new_parent << :bye_new_parent
|
813
|
+
snooze
|
814
|
+
|
815
|
+
assert_equal [
|
816
|
+
:hi_from_parent,
|
817
|
+
:hi_from_child,
|
818
|
+
:bye_from_parent,
|
819
|
+
:bye,
|
820
|
+
:bye_new_parent
|
821
|
+
], buf
|
822
|
+
end
|
735
823
|
end
|
736
824
|
|
737
825
|
class MailboxTest < MiniTest::Test
|
@@ -964,7 +1052,7 @@ class FiberControlTest < MiniTest::Test
|
|
964
1052
|
assert_equal 'foo', result.message
|
965
1053
|
assert_equal f1, result.source_fiber
|
966
1054
|
assert_equal :dead, f1.state
|
967
|
-
assert_equal :
|
1055
|
+
assert_equal :waiting, f2.state
|
968
1056
|
end
|
969
1057
|
|
970
1058
|
def test_select_with_interruption
|