polyphony 0.71 → 0.72

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/CHANGELOG.md +18 -4
  4. data/Gemfile.lock +1 -1
  5. data/TODO.md +1 -1
  6. data/bin/pdbg +1 -1
  7. data/bin/polyphony-debug +0 -0
  8. data/bin/stress.rb +0 -0
  9. data/bin/test +0 -0
  10. data/docs/_user-guide/all-about-timers.md +1 -1
  11. data/docs/api-reference/fiber.md +2 -2
  12. data/docs/faq.md +1 -1
  13. data/docs/getting-started/overview.md +8 -8
  14. data/docs/getting-started/tutorial.md +3 -3
  15. data/docs/main-concepts/concurrency.md +1 -1
  16. data/docs/main-concepts/extending.md +3 -3
  17. data/docs/main-concepts/fiber-scheduling.md +1 -1
  18. data/examples/core/calc.rb +37 -0
  19. data/examples/core/calc_with_restart.rb +40 -0
  20. data/examples/core/calc_with_supervise.rb +37 -0
  21. data/examples/core/message_based_supervision.rb +1 -1
  22. data/examples/io/rack_server.rb +1 -1
  23. data/examples/io/tunnel.rb +1 -1
  24. data/examples/performance/fiber_transfer.rb +1 -1
  25. data/examples/performance/line_splitting.rb +1 -1
  26. data/examples/performance/thread-vs-fiber/compare.rb +1 -1
  27. data/ext/polyphony/backend_common.c +8 -8
  28. data/ext/polyphony/backend_io_uring.c +26 -33
  29. data/ext/polyphony/backend_io_uring_context.c +1 -1
  30. data/ext/polyphony/backend_io_uring_context.h +1 -1
  31. data/ext/polyphony/backend_libev.c +11 -11
  32. data/ext/polyphony/extconf.rb +24 -13
  33. data/ext/polyphony/queue.c +2 -2
  34. data/ext/polyphony/runqueue_ring_buffer.c +3 -2
  35. data/lib/polyphony/adapters/irb.rb +11 -1
  36. data/lib/polyphony/core/global_api.rb +3 -3
  37. data/lib/polyphony/core/timer.rb +2 -2
  38. data/lib/polyphony/debugger.rb +3 -3
  39. data/lib/polyphony/extensions/fiber.rb +19 -8
  40. data/lib/polyphony/extensions/io.rb +2 -2
  41. data/lib/polyphony/extensions/openssl.rb +20 -5
  42. data/lib/polyphony/extensions/socket.rb +3 -4
  43. data/lib/polyphony/version.rb +1 -1
  44. data/polyphony.gemspec +1 -1
  45. data/test/coverage.rb +2 -2
  46. data/test/test_backend.rb +12 -12
  47. data/test/test_event.rb +1 -1
  48. data/test/test_ext.rb +1 -1
  49. data/test/test_fiber.rb +31 -7
  50. data/test/test_global_api.rb +2 -2
  51. data/test/test_io.rb +3 -3
  52. data/test/test_queue.rb +6 -6
  53. data/test/test_socket.rb +12 -10
  54. data/test/test_supervise.rb +85 -0
  55. data/test/test_sync.rb +2 -2
  56. data/test/test_thread.rb +22 -2
  57. data/test/test_thread_pool.rb +1 -1
  58. data/test/test_throttler.rb +1 -1
  59. data/test/test_timer.rb +2 -2
  60. data/test/test_trace.rb +1 -1
  61. metadata +7 -3
@@ -130,24 +130,32 @@ class ::OpenSSL::SSL::SSLServer
130
130
  end
131
131
  end
132
132
 
133
+ # STDOUT.puts 'SSLServer#accept'
133
134
  sock, = @svr.accept
135
+ # STDOUT.puts "- raw sock: #{sock.inspect}"
134
136
  begin
135
137
  ssl = OpenSSL::SSL::SSLSocket.new(sock, @ctx)
138
+ # STDOUT.puts "- ssl sock: #{ssl.inspect}"
136
139
  ssl.sync_close = true
137
140
  if @use_accept_worker
141
+ # STDOUT.puts "- send to accept worker"
138
142
  @accept_worker_fiber << [ssl, Fiber.current]
139
- receive
143
+ # STDOUT.puts "- wait for accept worker"
144
+ r = receive
145
+ # STDOUT.puts "- got reply from accept worker: #{r.inspect}"
146
+ r.invoke if r.is_a?(Exception)
140
147
  else
141
148
  ssl.accept
142
149
  end
143
150
  ssl
144
- rescue Exception => ex
151
+ rescue Exception => e
152
+ # STDOUT.puts "- accept exception: #{e.inspect}"
145
153
  if ssl
146
154
  ssl.close
147
155
  else
148
156
  sock.close
149
157
  end
150
- raise ex
158
+ raise e
151
159
  end
152
160
  end
153
161
 
@@ -156,11 +164,18 @@ class ::OpenSSL::SSL::SSLServer
156
164
  @accept_worker_thread = Thread.new do
157
165
  fiber << Fiber.current
158
166
  loop do
167
+ # STDOUT.puts "- accept_worker wait for work"
159
168
  socket, peer = receive
169
+ # STDOUT.puts "- accept_worker got socket from peer #{peer.inspect}"
160
170
  socket.accept
171
+ # STDOUT.puts "- accept_worker accept returned"
161
172
  peer << socket
162
- rescue => e
163
- peer.schedule(e) if fiber
173
+ # STDOUT.puts "- accept_worker sent socket back to peer"
174
+ rescue Polyphony::BaseException
175
+ raise
176
+ rescue Exception => e
177
+ # STDOUT.puts "- accept_worker error: #{e}"
178
+ peer << e if peer
164
179
  end
165
180
  end
166
181
  @accept_worker_fiber = receive
@@ -32,7 +32,7 @@ class ::Socket
32
32
  def read(maxlen = nil, buf = nil, buf_pos = 0)
33
33
  return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
34
34
  return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
35
-
35
+
36
36
  buf = +''
37
37
  len = buf.bytesize
38
38
  while true
@@ -168,7 +168,7 @@ class ::TCPSocket
168
168
  def read(maxlen = nil, buf = nil, buf_pos = 0)
169
169
  return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
170
170
  return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
171
-
171
+
172
172
  buf = +''
173
173
  len = buf.bytesize
174
174
  while true
@@ -232,7 +232,6 @@ class ::TCPServer
232
232
  alias_method :orig_accept, :accept
233
233
  def accept
234
234
  Polyphony.backend_accept(@io, TCPSocket)
235
- # @io.accept
236
235
  end
237
236
 
238
237
  def accept_loop(&block)
@@ -261,7 +260,7 @@ class ::UNIXSocket
261
260
  def read(maxlen = nil, buf = nil, buf_pos = 0)
262
261
  return Polyphony.backend_recv(self, buf, maxlen, buf_pos) if buf
263
262
  return Polyphony.backend_recv(self, buf || +'', maxlen, 0) if maxlen
264
-
263
+
265
264
  buf = +''
266
265
  len = buf.bytesize
267
266
  while true
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Polyphony
4
- VERSION = '0.71'
4
+ VERSION = '0.72'
5
5
  end
data/polyphony.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.add_development_dependency 'simplecov', '0.17.1'
28
28
  s.add_development_dependency 'rubocop', '0.85.1'
29
29
  s.add_development_dependency 'pry', '0.13.1'
30
-
30
+
31
31
  s.add_development_dependency 'msgpack', '1.4.2'
32
32
  s.add_development_dependency 'httparty', '0.17.1'
33
33
  s.add_development_dependency 'localhost', '~>1.1.4'
data/test/coverage.rb CHANGED
@@ -24,10 +24,10 @@ module Coverage
24
24
  @result = {}
25
25
  trace = TracePoint.new(:line) do |tp|
26
26
  next if tp.path =~ /\(/
27
-
27
+
28
28
  absolute = File.expand_path(tp.path)
29
29
  next unless LIB_FILES.include?(absolute)# =~ /^#{LIB_DIR}/
30
-
30
+
31
31
  @result[absolute] ||= relevant_lines_for_filename(absolute)
32
32
  @result[absolute][tp.lineno - 1] = 1
33
33
  end
data/test/test_backend.rb CHANGED
@@ -36,7 +36,7 @@ class BackendTest < MiniTest::Test
36
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
+
40
40
  assert_equal 'Hello', buf
41
41
  assert_equal return_value, buf
42
42
  end
@@ -51,7 +51,7 @@ class BackendTest < MiniTest::Test
51
51
  snooze
52
52
  o.close
53
53
  return_value = f.await
54
-
54
+
55
55
  assert_equal 'Hello', buf
56
56
  assert_equal return_value, buf
57
57
  end
@@ -66,7 +66,7 @@ class BackendTest < MiniTest::Test
66
66
  snooze
67
67
  o.close
68
68
  return_value = f.await
69
-
69
+
70
70
  assert_equal 'Hello world', buf
71
71
  assert_equal return_value, buf
72
72
  end
@@ -77,7 +77,7 @@ class BackendTest < MiniTest::Test
77
77
  f = spin { @backend.read(i, buf, 20, false, 0) }
78
78
  @backend.write(o, 'blah')
79
79
  return_value = f.await
80
-
80
+
81
81
  assert_equal 'blah', buf
82
82
  assert_equal return_value, buf
83
83
 
@@ -85,7 +85,7 @@ class BackendTest < MiniTest::Test
85
85
  f = spin { @backend.read(i, buf, 20, false, -1) }
86
86
  @backend.write(o, 'klmn')
87
87
  return_value = f.await
88
-
88
+
89
89
  assert_equal 'abcdefghijklmn', buf
90
90
  assert_equal return_value, buf
91
91
 
@@ -93,7 +93,7 @@ class BackendTest < MiniTest::Test
93
93
  f = spin { @backend.read(i, buf, 20, false, 3) }
94
94
  @backend.write(o, 'DEF')
95
95
  return_value = f.await
96
-
96
+
97
97
  assert_equal 'abcDEF', buf
98
98
  assert_equal return_value, buf
99
99
  end
@@ -109,12 +109,12 @@ class BackendTest < MiniTest::Test
109
109
 
110
110
  o << data
111
111
  o.close
112
-
112
+
113
113
  buf = +''
114
114
 
115
115
  @backend.read(i, buf, 4096, false, -1)
116
116
  assert_equal 4096, buf.bytesize
117
-
117
+
118
118
  @backend.read(i, buf, 1, false, -1)
119
119
  assert_equal 4097, buf.bytesize
120
120
 
@@ -129,7 +129,7 @@ class BackendTest < MiniTest::Test
129
129
  @backend.post_fork
130
130
  exit(42)
131
131
  end
132
-
132
+
133
133
  result = @backend.waitpid(pid)
134
134
  assert_equal [pid, 42], result
135
135
  end
@@ -427,7 +427,7 @@ class BackendTest < MiniTest::Test
427
427
  counter = 0
428
428
 
429
429
  @backend.idle_proc = proc { counter += 1 }
430
-
430
+
431
431
  3.times { snooze }
432
432
  assert_equal 0, counter
433
433
 
@@ -488,7 +488,7 @@ class BackendChainTest < MiniTest::Test
488
488
 
489
489
  snooze
490
490
  client = TCPSocket.new('127.0.0.1', port)
491
-
491
+
492
492
  result = Thread.backend.chain(
493
493
  [:send, client, 'hello', 0],
494
494
  [:send, client, " world\n", 0]
@@ -512,7 +512,7 @@ class BackendChainTest < MiniTest::Test
512
512
  while true
513
513
  len = o.splice(from, 8192)
514
514
  break if len == 0
515
-
515
+
516
516
  backend.chain(
517
517
  [:write, to, chunk_header(len)],
518
518
  [:splice, i, to, len]
data/test/test_event.rb CHANGED
@@ -25,7 +25,7 @@ class EventTest < MiniTest::Test
25
25
  def test_that_event_coalesces_signals
26
26
  count = 0
27
27
  a = Polyphony::Event.new
28
-
28
+
29
29
  coproc = spin {
30
30
  loop {
31
31
  a.await
data/test/test_ext.rb CHANGED
@@ -73,7 +73,7 @@ class KernelTest < MiniTest::Test
73
73
  data = `>&2 echo "error"`
74
74
  $stderr.rewind
75
75
  $stderr = prev_stderr
76
-
76
+
77
77
  assert_equal '', data
78
78
  assert_equal "error\n", err_io.read
79
79
  ensure
data/test/test_fiber.rb CHANGED
@@ -47,7 +47,7 @@ class FiberTest < MiniTest::Test
47
47
  f1 = spin { :foo }
48
48
  f2 = spin { :bar }
49
49
  4.times { snooze }
50
-
50
+
51
51
  assert_equal [:foo, :bar], Fiber.await(f1, f2)
52
52
  end
53
53
 
@@ -739,7 +739,7 @@ class FiberTest < MiniTest::Test
739
739
  def test_setup_raw
740
740
  buffer = []
741
741
  f = Fiber.new { buffer << receive }
742
-
742
+
743
743
  assert_nil f.thread
744
744
  snooze
745
745
  f.setup_raw
@@ -771,10 +771,11 @@ class FiberTest < MiniTest::Test
771
771
 
772
772
  snooze
773
773
  assert_equal parent, child.parent
774
- child.detach
774
+ result = child.detach
775
+ assert_equal result, child
775
776
  assert_equal Fiber.current, child.parent
776
777
  parent.await
777
-
778
+
778
779
  child << :bye
779
780
  child.await
780
781
 
@@ -807,7 +808,7 @@ class FiberTest < MiniTest::Test
807
808
  child.attach_to(new_parent)
808
809
  assert_equal new_parent, child.parent
809
810
  parent.await
810
-
811
+
811
812
  child << :bye
812
813
  new_parent << :bye_new_parent
813
814
  snooze
@@ -820,6 +821,29 @@ class FiberTest < MiniTest::Test
820
821
  :bye_new_parent
821
822
  ], buf
822
823
  end
824
+
825
+ def test_attach_all_children_to
826
+ children = []
827
+ f1 = spin do
828
+ 3.times {
829
+ children << spin { receive }
830
+ }
831
+ Fiber.current.parent << :ok
832
+ receive
833
+ end
834
+
835
+ result = receive
836
+ assert_equal :ok, result
837
+ assert_equal 3, children.size
838
+
839
+ f2 = spin { supervise }
840
+ f1.attach_all_children_to(f2)
841
+
842
+ snooze
843
+
844
+ assert_equal [], f1.children
845
+ assert_equal children, f2.children
846
+ end
823
847
  end
824
848
 
825
849
  class MailboxTest < MiniTest::Test
@@ -1126,7 +1150,7 @@ class RestartTest < MiniTest::Test
1126
1150
  assert_equal [1], buffer
1127
1151
  snooze
1128
1152
  assert_equal [1, 1], buffer
1129
-
1153
+
1130
1154
  f << 'foo'
1131
1155
  sleep 0.1
1132
1156
  assert_equal [1, 1, 2], buffer
@@ -1252,7 +1276,7 @@ class DebugTest < MiniTest::Test
1252
1276
  assert_equal true, f.__parked__?
1253
1277
  10.times { snooze }
1254
1278
  assert_equal [], buf
1255
-
1279
+
1256
1280
  f.__unpark__
1257
1281
  assert_nil f.__parked__?
1258
1282
  10.times { snooze }
@@ -280,7 +280,7 @@ class SpinLoopTest < MiniTest::Test
280
280
  def test_spin_loop_location
281
281
  location = /^#{__FILE__}:#{__LINE__ + 1}/
282
282
  f = spin_loop { snooze }
283
-
283
+
284
284
  assert_match location, f.location
285
285
  end
286
286
 
@@ -402,7 +402,7 @@ class ThrottledLoopTest < MiniTest::Test
402
402
  f.await
403
403
  t1 = Time.now
404
404
  assert_in_range 0.075..0.15, t1 - t0 if IS_LINUX
405
- assert_equal [1, 2, 3, 4, 5], buffer
405
+ assert_equal [1, 2, 3, 4, 5], buffer
406
406
  end
407
407
  end
408
408
 
data/test/test_io.rb CHANGED
@@ -107,10 +107,10 @@ class IOTest < MiniTest::Test
107
107
  sleep 0.01
108
108
  o << 'hi'
109
109
  }
110
- assert_equal 'hi', i.readpartial(2)
110
+ assert_equal 'hi', i.readpartial(2)
111
111
  o.close
112
112
 
113
- assert_raises(EOFError) { i.readpartial(1) }
113
+ assert_raises(EOFError) { i.readpartial(1) }
114
114
  end
115
115
 
116
116
  def test_gets
@@ -132,7 +132,7 @@ class IOTest < MiniTest::Test
132
132
  f << Fiber.current
133
133
  sleep 0.05
134
134
  assert_equal [], buf
135
-
135
+
136
136
  o << "ulous\n"
137
137
  receive
138
138
  assert_equal ["fabulous\n"], buf
data/test/test_queue.rb CHANGED
@@ -70,7 +70,7 @@ class QueueTest < MiniTest::Test
70
70
 
71
71
  def test_empty?
72
72
  assert @queue.empty?
73
-
73
+
74
74
  @queue << :foo
75
75
  assert !@queue.empty?
76
76
 
@@ -82,7 +82,7 @@ class QueueTest < MiniTest::Test
82
82
  f1 = spin { @queue.shift }
83
83
  f2 = spin { @queue.shift }
84
84
  f3 = spin { @queue.shift }
85
-
85
+
86
86
  # let fibers run
87
87
  snooze
88
88
 
@@ -99,7 +99,7 @@ class QueueTest < MiniTest::Test
99
99
 
100
100
  def test_fiber_removal_from_queue_simple
101
101
  f1 = spin { @queue.shift }
102
-
102
+
103
103
  # let fibers run
104
104
  snooze
105
105
 
@@ -114,11 +114,11 @@ class QueueTest < MiniTest::Test
114
114
  assert_equal 0, @queue.size
115
115
 
116
116
  @queue.push 1
117
-
117
+
118
118
  assert_equal 1, @queue.size
119
119
 
120
120
  @queue.push 2
121
-
121
+
122
122
  assert_equal 2, @queue.size
123
123
 
124
124
  @queue.shift
@@ -231,7 +231,7 @@ class CappedQueueTest < MiniTest::Test
231
231
  i = 0
232
232
  spin_loop do
233
233
  i += 1
234
- snooze
234
+ snooze
235
235
  end
236
236
 
237
237
  5.times { snooze }
data/test/test_socket.rb CHANGED
@@ -9,9 +9,16 @@ class SocketTest < MiniTest::Test
9
9
  super
10
10
  end
11
11
 
12
- def test_tcp
13
- port = rand(1234..5678)
12
+ def start_tcp_server_on_random_port
13
+ port = rand(1100..60000)
14
14
  server = TCPServer.new('127.0.0.1', port)
15
+ [port, server]
16
+ rescue Errno::EADDRINUSE
17
+ retry
18
+ end
19
+
20
+ def test_tcp
21
+ port, server = start_tcp_server_on_random_port
15
22
  server_fiber = spin do
16
23
  while (socket = server.accept)
17
24
  spin do
@@ -34,8 +41,7 @@ class SocketTest < MiniTest::Test
34
41
  end
35
42
 
36
43
  def test_read
37
- port = rand(1234..5678)
38
- server = TCPServer.new('127.0.0.1', port)
44
+ port, server = start_tcp_server_on_random_port
39
45
  server_fiber = spin do
40
46
  while (socket = server.accept)
41
47
  spin do
@@ -74,9 +80,7 @@ class SocketTest < MiniTest::Test
74
80
 
75
81
  # sending multiple strings at once
76
82
  def test_sendv
77
- port = rand(1234..5678)
78
- server = TCPServer.new('127.0.0.1', port)
79
-
83
+ port, server = start_tcp_server_on_random_port
80
84
  server_fiber = spin do
81
85
  while (socket = server.accept)
82
86
  spin do
@@ -100,9 +104,7 @@ class SocketTest < MiniTest::Test
100
104
 
101
105
 
102
106
  def test_feed_loop
103
- port = rand(1234..5678)
104
- server = TCPServer.new('127.0.0.1', port)
105
-
107
+ port, server = start_tcp_server_on_random_port
106
108
  server_fiber = spin do
107
109
  reader = MessagePack::Unpacker.new
108
110
  while (socket = server.accept)
@@ -135,6 +135,44 @@ class SuperviseTest < MiniTest::Test
135
135
  assert_equal supervisor, f3.parent
136
136
  end
137
137
 
138
+ def test_supervise_with_restart_true
139
+ buffer = []
140
+ f1 = spin(:f1) do
141
+ buffer << receive
142
+ rescue => e
143
+ buffer << e
144
+ e
145
+ end
146
+ supervisor = spin(:supervisor) { supervise(f1, restart: true) }
147
+
148
+ snooze
149
+ f1 << 'foo'
150
+ f1.await
151
+ snooze
152
+ assert_equal ['foo'], buffer
153
+
154
+ 10.times { snooze }
155
+
156
+ assert_equal 1, supervisor.children.size
157
+ f2 = supervisor.children.first
158
+ assert f1 != f2
159
+ assert_equal :f1, f2.tag
160
+ assert_equal supervisor, f2.parent
161
+
162
+ e = RuntimeError.new('bar')
163
+ f2.raise(e)
164
+ f2.await rescue nil
165
+ 3.times { snooze }
166
+ assert_equal ['foo', e], buffer
167
+
168
+ assert_equal 1, supervisor.children.size
169
+ f3 = supervisor.children.first
170
+ assert f2 != f3
171
+ assert f1 != f3
172
+ assert_equal :f1, f3.tag
173
+ assert_equal supervisor, f3.parent
174
+ end
175
+
138
176
  def test_supervise_with_restart_on_error
139
177
  buffer = []
140
178
  f1 = spin(:f1) do
@@ -184,4 +222,51 @@ class SuperviseTest < MiniTest::Test
184
222
 
185
223
  assert_equal [], buffer
186
224
  end
225
+
226
+ def test_supervise_without_explicit_fibers
227
+ buffer = []
228
+ first = nil
229
+ supervisor = spin do
230
+ 3.times do |i|
231
+ f = spin do
232
+ first = Fiber.current if i == 0
233
+ receive
234
+ buffer << i
235
+ end
236
+ end
237
+ Fiber.current.parent << :ok
238
+ supervise(restart: :always)
239
+ end
240
+ msg = receive
241
+ assert_equal :ok, msg
242
+ assert_equal 3, supervisor.children.size
243
+
244
+ sleep 0.1
245
+ assert_equal [], buffer
246
+
247
+ old_first = first
248
+ first << :foo
249
+ first = nil
250
+ snooze
251
+ assert_equal [0], buffer
252
+
253
+ snooze
254
+ assert_equal 3, supervisor.children.size
255
+ snooze
256
+ assert first
257
+ assert first != old_first
258
+ end
259
+
260
+ def test_supervise_with_added_fibers
261
+ buffer = []
262
+ supervisor = spin do
263
+ supervise { |f, r| buffer << [f, r] }
264
+ end
265
+ snooze
266
+ f1 = supervisor.spin { snooze; :foo }
267
+ f2 = supervisor.spin { snooze; :bar }
268
+ Fiber.await(f1, f2)
269
+ snooze
270
+ assert_equal [[f1, :foo], [f2, :bar]], buffer
271
+ end
187
272
  end
data/test/test_sync.rb CHANGED
@@ -104,12 +104,12 @@ class MutexTest < MiniTest::Test
104
104
  snooze
105
105
  assert !lock.locked?
106
106
  a << Fiber.current
107
-
107
+
108
108
  receive
109
109
  assert lock.locked?
110
110
 
111
111
  a << Fiber.current
112
-
112
+
113
113
  receive
114
114
  assert !lock.locked?
115
115
  end
data/test/test_thread.rb CHANGED
@@ -180,7 +180,7 @@ class ThreadTest < MiniTest::Test
180
180
  assert_equal count, GC.count
181
181
  sleep 0.05
182
182
  assert_equal count, GC.count
183
-
183
+
184
184
  return unless IS_LINUX
185
185
 
186
186
  # The idle tasks are ran at most once per fiber switch, before the backend
@@ -207,7 +207,7 @@ class ThreadTest < MiniTest::Test
207
207
  counter = 0
208
208
 
209
209
  Thread.current.on_idle { counter += 1 }
210
-
210
+
211
211
  3.times { snooze }
212
212
  assert_equal 0, counter
213
213
 
@@ -220,4 +220,24 @@ class ThreadTest < MiniTest::Test
220
220
  3.times { snooze }
221
221
  assert_equal 2, counter
222
222
  end
223
+
224
+ def test_cross_thread_receive
225
+ buf = []
226
+ f = Fiber.current
227
+ t = Thread.new do
228
+ f << true
229
+ while (msg = receive)
230
+ buf << msg
231
+ end
232
+ end
233
+
234
+ receive # wait for thread to be ready
235
+ t << 1
236
+ t << 2
237
+ t << 3
238
+ t << nil
239
+
240
+ t.join
241
+ assert_equal [1, 2, 3], buf
242
+ end
223
243
  end
@@ -67,7 +67,7 @@ class ThreadPoolTest < MiniTest::Test
67
67
 
68
68
  assert_in_range 0.0..0.009, elapsed
69
69
  assert buffer.size < 2
70
-
70
+
71
71
  sleep 0.15 # allow time for threads to spawn
72
72
  assert_equal @pool.size, threads.uniq.size
73
73
  assert_equal (0..9).to_a, buffer.sort if IS_LINUX
@@ -34,7 +34,7 @@ class ThrottlerTest < MiniTest::Test
34
34
  f = spin { loop { t.process { buffer << 1 } } }
35
35
  sleep 0.02
36
36
  f.stop
37
- assert_in_range 2..3, buffer.size
37
+ assert_in_range 2..4, buffer.size
38
38
  ensure
39
39
  t.stop
40
40
  end
data/test/test_timer.rb CHANGED
@@ -137,11 +137,11 @@ class TimerMiscTest < MiniTest::Test
137
137
  @timer = Polyphony::Timer.new(resolution: 0.001)
138
138
  sleep 0
139
139
  end
140
-
140
+
141
141
  def teardown
142
142
  @timer.stop
143
143
  end
144
-
144
+
145
145
  def test_timer_after
146
146
  buffer = []
147
147
  f = @timer.after(0.01) { buffer << 2 }
data/test/test_trace.rb CHANGED
@@ -7,7 +7,7 @@ class TraceTest < MiniTest::Test
7
7
  events = []
8
8
  Thread.backend.trace_proc = proc { |*e| events << e }
9
9
  snooze
10
-
10
+
11
11
  assert_equal [
12
12
  [:fiber_schedule, Fiber.current, nil, false],
13
13
  [:fiber_switchpoint, Fiber.current],