polyphony 0.39 → 0.43.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +11 -2
- data/.gitignore +2 -2
- data/.rubocop.yml +30 -0
- data/CHANGELOG.md +23 -4
- data/Gemfile.lock +15 -12
- data/README.md +2 -1
- data/Rakefile +3 -3
- data/TODO.md +27 -97
- data/docs/_config.yml +56 -7
- data/docs/_sass/custom/custom.scss +6 -26
- data/docs/_sass/overrides.scss +0 -46
- data/docs/{user-guide → _user-guide}/all-about-timers.md +0 -0
- data/docs/_user-guide/index.md +9 -0
- data/docs/{user-guide → _user-guide}/web-server.md +0 -0
- data/docs/api-reference/fiber.md +2 -2
- data/docs/api-reference/index.md +9 -0
- data/docs/api-reference/polyphony-process.md +1 -1
- data/docs/api-reference/thread.md +1 -1
- data/docs/faq.md +21 -11
- data/docs/favicon.ico +0 -0
- data/docs/getting-started/index.md +10 -0
- data/docs/getting-started/installing.md +2 -6
- data/docs/getting-started/overview.md +486 -0
- data/docs/getting-started/tutorial.md +27 -19
- data/docs/index.md +6 -2
- data/docs/main-concepts/concurrency.md +0 -5
- data/docs/main-concepts/design-principles.md +69 -21
- data/docs/main-concepts/extending.md +1 -1
- data/docs/main-concepts/index.md +9 -0
- data/docs/polyphony-logo.png +0 -0
- data/examples/core/01-spinning-up-fibers.rb +1 -0
- data/examples/core/03-interrupting.rb +4 -1
- data/examples/core/04-handling-signals.rb +19 -0
- data/examples/core/xx-agent.rb +102 -0
- data/examples/core/xx-sleeping.rb +14 -6
- data/examples/io/tunnel.rb +48 -0
- data/examples/io/xx-irb.rb +1 -1
- data/examples/performance/thread-vs-fiber/polyphony_mt_server.rb +7 -6
- data/examples/performance/thread-vs-fiber/polyphony_server.rb +13 -36
- data/examples/performance/thread-vs-fiber/polyphony_server_read_loop.rb +58 -0
- data/examples/performance/xx-array.rb +11 -0
- data/examples/performance/xx-fiber-switch.rb +9 -0
- data/examples/performance/xx-snooze.rb +15 -0
- data/ext/{gyro → polyphony}/extconf.rb +2 -2
- data/ext/{gyro → polyphony}/fiber.c +17 -23
- data/ext/{gyro → polyphony}/libev.c +0 -0
- data/ext/{gyro → polyphony}/libev.h +0 -0
- data/ext/polyphony/libev_agent.c +718 -0
- data/ext/polyphony/libev_queue.c +216 -0
- data/ext/polyphony/polyphony.c +73 -0
- data/ext/{gyro/gyro.h → polyphony/polyphony.h} +19 -39
- data/ext/polyphony/polyphony_ext.c +21 -0
- data/ext/polyphony/thread.c +200 -0
- data/ext/{gyro → polyphony}/tracing.c +1 -1
- data/lib/polyphony.rb +19 -14
- data/lib/polyphony/adapters/irb.rb +1 -1
- data/lib/polyphony/adapters/postgres.rb +6 -5
- data/lib/polyphony/adapters/process.rb +5 -5
- data/lib/polyphony/adapters/trace.rb +28 -28
- data/lib/polyphony/core/channel.rb +3 -3
- data/lib/polyphony/core/exceptions.rb +1 -1
- data/lib/polyphony/core/global_api.rb +13 -11
- data/lib/polyphony/core/resource_pool.rb +3 -3
- data/lib/polyphony/core/sync.rb +2 -2
- data/lib/polyphony/core/thread_pool.rb +6 -6
- data/lib/polyphony/core/throttler.rb +13 -6
- data/lib/polyphony/event.rb +27 -0
- data/lib/polyphony/extensions/core.rb +22 -14
- data/lib/polyphony/extensions/fiber.rb +4 -4
- data/lib/polyphony/extensions/io.rb +59 -25
- data/lib/polyphony/extensions/openssl.rb +36 -16
- data/lib/polyphony/extensions/socket.rb +28 -10
- data/lib/polyphony/extensions/thread.rb +16 -9
- data/lib/polyphony/net.rb +9 -9
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +4 -4
- data/test/helper.rb +12 -8
- data/test/test_agent.rb +124 -0
- data/test/{test_async.rb → test_event.rb} +15 -7
- data/test/test_ext.rb +25 -4
- data/test/test_fiber.rb +19 -10
- data/test/test_global_api.rb +11 -11
- data/test/test_io.rb +44 -29
- data/test/test_queue.rb +74 -0
- data/test/test_signal.rb +3 -40
- data/test/test_socket.rb +34 -0
- data/test/test_thread.rb +38 -17
- data/test/test_thread_pool.rb +2 -2
- data/test/test_throttler.rb +5 -3
- data/test/test_trace.rb +6 -5
- metadata +41 -43
- data/docs/_includes/nav.html +0 -51
- data/docs/_includes/prevnext.html +0 -17
- data/docs/_layouts/default.html +0 -106
- data/docs/api-reference.md +0 -11
- data/docs/api-reference/gyro-async.md +0 -57
- data/docs/api-reference/gyro-child.md +0 -29
- data/docs/api-reference/gyro-queue.md +0 -44
- data/docs/api-reference/gyro-timer.md +0 -51
- data/docs/api-reference/gyro.md +0 -25
- data/docs/getting-started.md +0 -10
- data/docs/main-concepts.md +0 -10
- data/docs/user-guide.md +0 -10
- data/examples/core/forever_sleep.rb +0 -19
- data/ext/gyro/async.c +0 -162
- data/ext/gyro/child.c +0 -141
- data/ext/gyro/gyro.c +0 -103
- data/ext/gyro/gyro_ext.c +0 -33
- data/ext/gyro/io.c +0 -489
- data/ext/gyro/queue.c +0 -142
- data/ext/gyro/selector.c +0 -228
- data/ext/gyro/signal.c +0 -133
- data/ext/gyro/socket.c +0 -210
- data/ext/gyro/thread.c +0 -308
- data/ext/gyro/timer.c +0 -151
- data/test/test_timer.rb +0 -32
data/test/test_global_api.rb
CHANGED
@@ -106,7 +106,7 @@ class MoveOnAfterTest < MiniTest::Test
|
|
106
106
|
end
|
107
107
|
t1 = Time.now
|
108
108
|
|
109
|
-
|
109
|
+
assert t1 - t0 < 0.03
|
110
110
|
assert_nil v
|
111
111
|
end
|
112
112
|
|
@@ -118,7 +118,7 @@ class MoveOnAfterTest < MiniTest::Test
|
|
118
118
|
end
|
119
119
|
t1 = Time.now
|
120
120
|
|
121
|
-
|
121
|
+
assert t1 - t0 < 0.02
|
122
122
|
assert_equal :bar, v
|
123
123
|
end
|
124
124
|
|
@@ -129,7 +129,7 @@ class MoveOnAfterTest < MiniTest::Test
|
|
129
129
|
assert_equal Fiber.current, f.parent
|
130
130
|
v = sleep 1
|
131
131
|
t1 = Time.now
|
132
|
-
|
132
|
+
assert t1 - t0 < 0.02
|
133
133
|
assert_equal 'foo', v
|
134
134
|
end
|
135
135
|
end
|
@@ -145,7 +145,7 @@ class CancelAfterTest < MiniTest::Test
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
t1 = Time.now
|
148
|
-
|
148
|
+
assert t1 - t0 < 0.02
|
149
149
|
end
|
150
150
|
|
151
151
|
def test_cancel_after_without_block
|
@@ -157,7 +157,7 @@ class CancelAfterTest < MiniTest::Test
|
|
157
157
|
sleep 1
|
158
158
|
end
|
159
159
|
t1 = Time.now
|
160
|
-
|
160
|
+
assert t1 - t0 < 0.02
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
@@ -202,9 +202,9 @@ class SpinLoopTest < MiniTest::Test
|
|
202
202
|
buffer = []
|
203
203
|
counter = 0
|
204
204
|
f = spin_loop(rate: 50) { buffer << (counter += 1) }
|
205
|
-
sleep 0.
|
205
|
+
sleep 0.2
|
206
206
|
f.stop
|
207
|
-
|
207
|
+
assert counter >= 9 && counter <= 11
|
208
208
|
end
|
209
209
|
end
|
210
210
|
|
@@ -215,9 +215,9 @@ class ThrottledLoopTest < MiniTest::Test
|
|
215
215
|
f = spin do
|
216
216
|
throttled_loop(50) { buffer << (counter += 1) }
|
217
217
|
end
|
218
|
-
sleep 0.
|
218
|
+
sleep 0.2
|
219
219
|
f.stop
|
220
|
-
|
220
|
+
assert counter >= 9 && counter <= 11
|
221
221
|
end
|
222
222
|
|
223
223
|
def test_throttled_loop_with_count
|
@@ -248,14 +248,14 @@ class GlobalAPIEtcTest < MiniTest::Test
|
|
248
248
|
end
|
249
249
|
sleep 0.05
|
250
250
|
f.stop
|
251
|
-
|
251
|
+
assert (4..5).include?(buffer.size)
|
252
252
|
end
|
253
253
|
|
254
254
|
def test_sleep
|
255
255
|
t0 = Time.now
|
256
256
|
sleep 0.05
|
257
257
|
elapsed = Time.now - t0
|
258
|
-
|
258
|
+
assert (0.045..0.08).include? elapsed
|
259
259
|
|
260
260
|
f = spin { sleep }
|
261
261
|
snooze
|
data/test/test_io.rb
CHANGED
@@ -2,30 +2,6 @@
|
|
2
2
|
|
3
3
|
require_relative 'helper'
|
4
4
|
|
5
|
-
class GyroIOTest < MiniTest::Test
|
6
|
-
def test_that_reading_works
|
7
|
-
i, o = IO.pipe
|
8
|
-
data = +''
|
9
|
-
sequence = []
|
10
|
-
watcher = Gyro::IO.new(i, :r)
|
11
|
-
spin {
|
12
|
-
sequence << 1
|
13
|
-
watcher.await
|
14
|
-
sequence << 2
|
15
|
-
i.read_nonblock(8192, data)
|
16
|
-
}
|
17
|
-
snooze
|
18
|
-
sequence << 3
|
19
|
-
spin do
|
20
|
-
o << 'hello'
|
21
|
-
sequence << 4
|
22
|
-
end
|
23
|
-
suspend
|
24
|
-
assert_equal 'hello', data
|
25
|
-
assert_equal [1, 3, 4, 2], sequence
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
5
|
class IOTest < MiniTest::Test
|
30
6
|
def setup
|
31
7
|
super
|
@@ -62,11 +38,50 @@ class IOTest < MiniTest::Test
|
|
62
38
|
assert_equal 'foobarbaz', @i.read
|
63
39
|
end
|
64
40
|
|
65
|
-
def
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
41
|
+
def test_wait_io
|
42
|
+
results = []
|
43
|
+
i, o = IO.pipe
|
44
|
+
f = spin do
|
45
|
+
loop do
|
46
|
+
result = i.orig_read_nonblock(8192, exception: false)
|
47
|
+
results << result
|
48
|
+
case result
|
49
|
+
when :wait_readable
|
50
|
+
Thread.current.agent.wait_io(i, false)
|
51
|
+
else
|
52
|
+
break result
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
snooze
|
58
|
+
o.write('foo')
|
59
|
+
o.close
|
60
|
+
|
61
|
+
result = f.await
|
62
|
+
|
63
|
+
assert_equal 'foo', f.await
|
64
|
+
assert_equal [:wait_readable, 'foo'], results
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_readpartial
|
68
|
+
i, o = IO.pipe
|
69
|
+
|
70
|
+
o << 'hi'
|
71
|
+
assert_equal 'hi', i.readpartial(3)
|
72
|
+
|
73
|
+
o << 'hi'
|
74
|
+
assert_equal 'h', i.readpartial(1)
|
75
|
+
assert_equal 'i', i.readpartial(1)
|
76
|
+
|
77
|
+
spin {
|
78
|
+
sleep 0.01
|
79
|
+
o << 'hi'
|
80
|
+
}
|
81
|
+
assert_equal 'hi', i.readpartial(2)
|
82
|
+
o.close
|
83
|
+
|
84
|
+
assert_raises(EOFError) { i.readpartial(1) }
|
70
85
|
end
|
71
86
|
end
|
72
87
|
|
data/test/test_queue.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
|
5
|
+
class QueueTest < MiniTest::Test
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@queue = Polyphony::Queue.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_pop
|
12
|
+
spin {
|
13
|
+
@queue << 42
|
14
|
+
}
|
15
|
+
v = @queue.shift
|
16
|
+
assert_equal 42, v
|
17
|
+
|
18
|
+
(1..4).each { |i| @queue << i }
|
19
|
+
buf = []
|
20
|
+
4.times { buf << @queue.shift }
|
21
|
+
assert_equal [1, 2, 3, 4], buf
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_multiple_waiters
|
25
|
+
a = spin { @queue.shift }
|
26
|
+
b = spin { @queue.shift }
|
27
|
+
|
28
|
+
@queue << :foo
|
29
|
+
@queue << :bar
|
30
|
+
|
31
|
+
assert_equal [:foo, :bar], Fiber.await(a, b)
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_multi_thread_usage
|
35
|
+
t = Thread.new { @queue.push :foo }
|
36
|
+
assert_equal :foo, @queue.shift
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_shift_each
|
40
|
+
(1..4).each { |i| @queue << i }
|
41
|
+
buf = []
|
42
|
+
@queue.shift_each { |i| buf << i }
|
43
|
+
assert_equal [1, 2, 3, 4], buf
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_empty?
|
47
|
+
assert @queue.empty?
|
48
|
+
|
49
|
+
@queue << :foo
|
50
|
+
assert !@queue.empty?
|
51
|
+
|
52
|
+
assert_equal :foo, @queue.shift
|
53
|
+
assert @queue.empty?
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_fiber_removal_from_queue
|
57
|
+
f1 = spin { @queue.shift }
|
58
|
+
f2 = spin { @queue.shift }
|
59
|
+
f3 = spin { @queue.shift }
|
60
|
+
|
61
|
+
# let fibers run
|
62
|
+
snooze
|
63
|
+
|
64
|
+
f2.stop
|
65
|
+
snooze
|
66
|
+
|
67
|
+
@queue << :foo
|
68
|
+
@queue << :bar
|
69
|
+
|
70
|
+
assert_equal :foo, f1.await
|
71
|
+
assert_nil f2.await
|
72
|
+
assert_equal :bar, f3.await
|
73
|
+
end
|
74
|
+
end
|
data/test/test_signal.rb
CHANGED
@@ -2,41 +2,6 @@
|
|
2
2
|
|
3
3
|
require_relative 'helper'
|
4
4
|
|
5
|
-
class SignalTest < MiniTest::Test
|
6
|
-
def test_Gyro_Signal_constructor
|
7
|
-
sig = Signal.list['USR1']
|
8
|
-
count = 0
|
9
|
-
w = Gyro::Signal.new(sig)
|
10
|
-
|
11
|
-
spin {
|
12
|
-
loop {
|
13
|
-
w.await
|
14
|
-
count += 1
|
15
|
-
break
|
16
|
-
}
|
17
|
-
}
|
18
|
-
Thread.new do
|
19
|
-
orig_sleep 0.001
|
20
|
-
Process.kill(:USR1, Process.pid)
|
21
|
-
end
|
22
|
-
suspend
|
23
|
-
assert_equal 1, count
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_wait_for_signal_api
|
27
|
-
count = 0
|
28
|
-
spin do
|
29
|
-
Polyphony.wait_for_signal 'SIGHUP'
|
30
|
-
count += 1
|
31
|
-
end
|
32
|
-
|
33
|
-
snooze
|
34
|
-
Process.kill(:HUP, Process.pid)
|
35
|
-
snooze
|
36
|
-
assert_equal 1, count
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
5
|
class SignalTrapTest < Minitest::Test
|
41
6
|
def test_signal_exception_handling
|
42
7
|
i, o = IO.pipe
|
@@ -57,9 +22,8 @@ class SignalTrapTest < Minitest::Test
|
|
57
22
|
end
|
58
23
|
sleep 0.01
|
59
24
|
o.close
|
60
|
-
watcher = Gyro::Child.new(pid)
|
61
25
|
Process.kill('INT', pid)
|
62
|
-
|
26
|
+
Thread.current.agent.waitpid(pid)
|
63
27
|
buffer = i.read
|
64
28
|
assert_equal "3-interrupt\n", buffer
|
65
29
|
end
|
@@ -86,9 +50,8 @@ class SignalTrapTest < Minitest::Test
|
|
86
50
|
end
|
87
51
|
sleep 0.02
|
88
52
|
o.close
|
89
|
-
watcher = Gyro::Child.new(pid)
|
90
53
|
Process.kill('INT', pid)
|
91
|
-
|
54
|
+
Thread.current.agent.waitpid(pid)
|
92
55
|
buffer = i.read
|
93
56
|
assert_equal "3 - interrupted\n2 - terminated\n1 - terminated\n", buffer
|
94
57
|
end
|
@@ -130,7 +93,7 @@ class SignalTrapTest < Minitest::Test
|
|
130
93
|
o.close
|
131
94
|
sleep 0.1
|
132
95
|
Process.kill('INT', pid)
|
133
|
-
|
96
|
+
Thread.current.agent.waitpid(pid)
|
134
97
|
buffer = i.read
|
135
98
|
assert_equal "3-interrupt\n", buffer
|
136
99
|
end
|
data/test/test_socket.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'helper'
|
4
|
+
|
5
|
+
class SocketTest < MiniTest::Test
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_tcp
|
11
|
+
port = rand(1234..5678)
|
12
|
+
server = TCPServer.new('127.0.0.1', port)
|
13
|
+
|
14
|
+
server_fiber = spin do
|
15
|
+
while (socket = server.accept)
|
16
|
+
spin do
|
17
|
+
while (data = socket.gets(8192))
|
18
|
+
socket << data
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
snooze
|
25
|
+
client = TCPSocket.new('127.0.0.1', port)
|
26
|
+
client.write("1234\n")
|
27
|
+
assert_equal "1234\n", client.readpartial(8192)
|
28
|
+
client.close
|
29
|
+
ensure
|
30
|
+
server_fiber&.stop
|
31
|
+
server_fiber&.await
|
32
|
+
server&.close
|
33
|
+
end
|
34
|
+
end
|
data/test/test_thread.rb
CHANGED
@@ -8,14 +8,20 @@ class ThreadTest < MiniTest::Test
|
|
8
8
|
buffer = []
|
9
9
|
f = spin { (1..3).each { |i| snooze; buffer << i } }
|
10
10
|
t = Thread.new do
|
11
|
+
sleep 0.01
|
11
12
|
s1 = spin { (11..13).each { |i| snooze; buffer << i } }
|
12
13
|
s2 = spin { (21..23).each { |i| snooze; buffer << i } }
|
14
|
+
sleep 0.02
|
13
15
|
Fiber.current.await_all_children
|
14
16
|
end
|
15
17
|
f.join
|
16
18
|
t.join
|
19
|
+
t = nil
|
17
20
|
|
18
21
|
assert_equal [1, 2, 3, 11, 12, 13, 21, 22, 23], buffer.sort
|
22
|
+
ensure
|
23
|
+
t&.kill
|
24
|
+
t&.join
|
19
25
|
end
|
20
26
|
|
21
27
|
def test_thread_join
|
@@ -24,11 +30,13 @@ class ThreadTest < MiniTest::Test
|
|
24
30
|
t = Thread.new { sleep 0.01; buffer << 4; :foo }
|
25
31
|
|
26
32
|
r = t.join
|
33
|
+
t = nil
|
27
34
|
|
28
|
-
assert_equal [1, 2, 3, 4], buffer
|
29
35
|
assert_equal :foo, r
|
36
|
+
assert_equal [1, 2, 3, 4], buffer
|
30
37
|
ensure
|
31
|
-
t
|
38
|
+
t&.kill
|
39
|
+
t&.join
|
32
40
|
end
|
33
41
|
|
34
42
|
def test_thread_join_with_timeout
|
@@ -37,14 +45,16 @@ class ThreadTest < MiniTest::Test
|
|
37
45
|
t = Thread.new { sleep 1; buffer << 4 }
|
38
46
|
t0 = Time.now
|
39
47
|
r = t.join(0.01)
|
48
|
+
t = nil
|
40
49
|
|
41
|
-
|
50
|
+
assert Time.now - t0 < 0.2
|
42
51
|
assert_equal [1, 2, 3], buffer
|
43
52
|
assert_nil r
|
44
53
|
ensure
|
45
54
|
# killing the thread will prevent stopping the sleep timer, as well as the
|
46
55
|
# thread's event selector, leading to a memory leak.
|
47
|
-
t&.kill
|
56
|
+
t&.kill
|
57
|
+
t&.join
|
48
58
|
end
|
49
59
|
|
50
60
|
def test_thread_await_alias_method
|
@@ -52,11 +62,13 @@ class ThreadTest < MiniTest::Test
|
|
52
62
|
spin { (1..3).each { |i| snooze; buffer << i } }
|
53
63
|
t = Thread.new { sleep 0.01; buffer << 4; :foo }
|
54
64
|
r = t.await
|
65
|
+
t = nil
|
55
66
|
|
56
67
|
assert_equal [1, 2, 3, 4], buffer
|
57
68
|
assert_equal :foo, r
|
58
69
|
ensure
|
59
|
-
t
|
70
|
+
t&.kill
|
71
|
+
t&.join
|
60
72
|
end
|
61
73
|
|
62
74
|
def test_join_race_condition_on_thread_spawning
|
@@ -65,27 +77,33 @@ class ThreadTest < MiniTest::Test
|
|
65
77
|
:foo
|
66
78
|
end
|
67
79
|
r = t.join
|
80
|
+
t = nil
|
68
81
|
assert_equal :foo, r
|
82
|
+
ensure
|
83
|
+
t&.kill
|
84
|
+
t&.join
|
69
85
|
end
|
70
86
|
|
71
87
|
def test_thread_uncaught_exception_propagation
|
72
|
-
|
73
|
-
sleep 1
|
74
|
-
end
|
75
|
-
snooze
|
76
|
-
t.kill
|
77
|
-
t.await
|
88
|
+
ready = Polyphony::Event.new
|
78
89
|
|
79
90
|
t = Thread.new do
|
91
|
+
ready.signal
|
92
|
+
sleep 0.01
|
80
93
|
raise 'foo'
|
81
94
|
end
|
82
95
|
e = nil
|
83
96
|
begin
|
84
|
-
|
97
|
+
ready.await
|
98
|
+
r = t.await
|
85
99
|
rescue Exception => e
|
86
100
|
end
|
101
|
+
t = nil
|
87
102
|
assert_kind_of RuntimeError, e
|
88
103
|
assert_equal 'foo', e.message
|
104
|
+
ensure
|
105
|
+
t&.kill
|
106
|
+
t&.join
|
89
107
|
end
|
90
108
|
|
91
109
|
def test_thread_inspect
|
@@ -102,9 +120,8 @@ class ThreadTest < MiniTest::Test
|
|
102
120
|
p e
|
103
121
|
puts e.backtrace.join("\n")
|
104
122
|
ensure
|
105
|
-
t
|
106
|
-
|
107
|
-
t.join
|
123
|
+
t&.kill
|
124
|
+
t&.join
|
108
125
|
end
|
109
126
|
|
110
127
|
def test_that_suspend_returns_immediately_if_no_watchers
|
@@ -113,14 +130,14 @@ class ThreadTest < MiniTest::Test
|
|
113
130
|
records << r if r[:event] =~ /^fiber_/
|
114
131
|
end
|
115
132
|
t.enable
|
116
|
-
|
133
|
+
Polyphony.trace(true)
|
117
134
|
|
118
135
|
suspend
|
119
136
|
t.disable
|
120
137
|
assert_equal [:fiber_switchpoint], records.map { |r| r[:event] }
|
121
138
|
ensure
|
122
139
|
t&.disable
|
123
|
-
|
140
|
+
Polyphony.trace(false)
|
124
141
|
end
|
125
142
|
|
126
143
|
def test_thread_child_fiber_termination
|
@@ -143,7 +160,11 @@ class ThreadTest < MiniTest::Test
|
|
143
160
|
assert_equal 2, t.main_fiber.children.size
|
144
161
|
t.kill
|
145
162
|
t.join
|
163
|
+
t = nil
|
146
164
|
|
147
165
|
assert_equal [:foo, :bar], buffer
|
166
|
+
ensure
|
167
|
+
t&.kill
|
168
|
+
t&.join
|
148
169
|
end
|
149
170
|
end
|