polyphony 1.4 → 1.6

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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +22 -0
  4. data/TODO.md +5 -14
  5. data/examples/pipes/http_server.rb +42 -12
  6. data/examples/pipes/http_server2.rb +45 -0
  7. data/ext/polyphony/backend_common.h +5 -0
  8. data/ext/polyphony/backend_io_uring.c +174 -121
  9. data/ext/polyphony/backend_io_uring_context.c +24 -18
  10. data/ext/polyphony/backend_io_uring_context.h +4 -2
  11. data/ext/polyphony/backend_libev.c +46 -22
  12. data/ext/polyphony/event.c +21 -0
  13. data/ext/polyphony/extconf.rb +25 -19
  14. data/ext/polyphony/fiber.c +0 -2
  15. data/ext/polyphony/pipe.c +1 -1
  16. data/ext/polyphony/polyphony.c +2 -20
  17. data/ext/polyphony/polyphony.h +5 -5
  18. data/ext/polyphony/ring_buffer.c +1 -0
  19. data/ext/polyphony/runqueue_ring_buffer.c +1 -0
  20. data/ext/polyphony/thread.c +63 -0
  21. data/ext/polyphony/win_uio.h +18 -0
  22. data/lib/polyphony/adapters/open3.rb +190 -0
  23. data/lib/polyphony/core/sync.rb +83 -13
  24. data/lib/polyphony/core/timer.rb +7 -25
  25. data/lib/polyphony/extensions/exception.rb +15 -0
  26. data/lib/polyphony/extensions/fiber.rb +14 -13
  27. data/lib/polyphony/extensions/io.rb +56 -14
  28. data/lib/polyphony/extensions/kernel.rb +1 -1
  29. data/lib/polyphony/extensions/object.rb +1 -13
  30. data/lib/polyphony/extensions/process.rb +76 -1
  31. data/lib/polyphony/extensions/socket.rb +0 -14
  32. data/lib/polyphony/extensions/thread.rb +19 -27
  33. data/lib/polyphony/extensions/timeout.rb +5 -1
  34. data/lib/polyphony/version.rb +1 -1
  35. data/lib/polyphony.rb +11 -5
  36. data/test/helper.rb +46 -4
  37. data/test/open3/envutil.rb +380 -0
  38. data/test/open3/find_executable.rb +24 -0
  39. data/test/stress.rb +11 -7
  40. data/test/test_backend.rb +11 -4
  41. data/test/test_event.rb +10 -3
  42. data/test/test_ext.rb +16 -1
  43. data/test/test_fiber.rb +16 -4
  44. data/test/test_global_api.rb +17 -16
  45. data/test/test_io.rb +39 -0
  46. data/test/test_kernel.rb +2 -2
  47. data/test/test_monitor.rb +356 -0
  48. data/test/test_open3.rb +338 -0
  49. data/test/test_signal.rb +5 -1
  50. data/test/test_socket.rb +6 -98
  51. data/test/test_sync.rb +46 -0
  52. data/test/test_thread.rb +10 -1
  53. data/test/test_thread_pool.rb +5 -0
  54. data/test/test_throttler.rb +1 -1
  55. data/test/test_timer.rb +8 -2
  56. data/test/test_trace.rb +2 -0
  57. data/vendor/liburing/.github/workflows/build.yml +8 -0
  58. data/vendor/liburing/.gitignore +1 -0
  59. data/vendor/liburing/CHANGELOG +8 -0
  60. data/vendor/liburing/configure +17 -25
  61. data/vendor/liburing/debian/liburing-dev.manpages +2 -0
  62. data/vendor/liburing/debian/rules +2 -1
  63. data/vendor/liburing/examples/Makefile +2 -1
  64. data/vendor/liburing/examples/io_uring-udp.c +11 -3
  65. data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
  66. data/vendor/liburing/liburing.spec +1 -1
  67. data/vendor/liburing/make-debs.sh +4 -2
  68. data/vendor/liburing/src/Makefile +5 -5
  69. data/vendor/liburing/src/arch/aarch64/lib.h +1 -1
  70. data/vendor/liburing/src/include/liburing/io_uring.h +41 -16
  71. data/vendor/liburing/src/include/liburing.h +86 -11
  72. data/vendor/liburing/src/int_flags.h +1 -0
  73. data/vendor/liburing/src/liburing-ffi.map +12 -0
  74. data/vendor/liburing/src/liburing.map +8 -0
  75. data/vendor/liburing/src/register.c +7 -2
  76. data/vendor/liburing/src/setup.c +373 -81
  77. data/vendor/liburing/test/232c93d07b74.c +3 -3
  78. data/vendor/liburing/test/Makefile +10 -3
  79. data/vendor/liburing/test/accept.c +2 -1
  80. data/vendor/liburing/test/buf-ring.c +35 -75
  81. data/vendor/liburing/test/connect-rep.c +204 -0
  82. data/vendor/liburing/test/coredump.c +59 -0
  83. data/vendor/liburing/test/fallocate.c +9 -0
  84. data/vendor/liburing/test/fd-pass.c +34 -3
  85. data/vendor/liburing/test/file-verify.c +27 -6
  86. data/vendor/liburing/test/helpers.c +3 -1
  87. data/vendor/liburing/test/io_uring_register.c +25 -28
  88. data/vendor/liburing/test/io_uring_setup.c +1 -1
  89. data/vendor/liburing/test/poll-cancel-all.c +29 -5
  90. data/vendor/liburing/test/poll-race-mshot.c +6 -22
  91. data/vendor/liburing/test/read-write.c +53 -0
  92. data/vendor/liburing/test/recv-msgall.c +21 -23
  93. data/vendor/liburing/test/reg-fd-only.c +55 -0
  94. data/vendor/liburing/test/reg-hint.c +56 -0
  95. data/vendor/liburing/test/regbuf-merge.c +91 -0
  96. data/vendor/liburing/test/ringbuf-read.c +2 -10
  97. data/vendor/liburing/test/send_recvmsg.c +5 -16
  98. data/vendor/liburing/test/shutdown.c +2 -1
  99. data/vendor/liburing/test/socket-io-cmd.c +215 -0
  100. data/vendor/liburing/test/socket-rw-eagain.c +2 -1
  101. data/vendor/liburing/test/socket-rw-offset.c +2 -1
  102. data/vendor/liburing/test/socket-rw.c +2 -1
  103. data/vendor/liburing/test/timeout.c +276 -0
  104. data/vendor/liburing/test/xattr.c +38 -25
  105. metadata +20 -7
  106. data/vendor/liburing/test/timeout-overflow.c +0 -204
@@ -0,0 +1,338 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'helper'
4
+
5
+ # Adapted from: https://github.com/ruby/open3/blob/master/test/test_open3.rb
6
+
7
+ require_relative 'open3/envutil'
8
+
9
+ class TestOpen3 < MiniTest::Test
10
+ RUBY = EnvUtil.rubybin
11
+
12
+ def test_exit_status
13
+ Open3.popen3(RUBY, '-e', 'exit true') {|i,o,e,t|
14
+ assert_equal(true, t.value.success?)
15
+ }
16
+ Open3.popen3(RUBY, '-e', 'exit false') {|i,o,e,t|
17
+ assert_equal(false, t.value.success?)
18
+ }
19
+ end
20
+
21
+ def test_stdin
22
+ Open3.popen3(RUBY, '-e', 'exit STDIN.gets.chomp == "t"') {|i,o,e,t|
23
+ i.puts 't'
24
+ assert_equal(true, t.value.success?)
25
+ }
26
+ Open3.popen3(RUBY, '-e', 'exit STDIN.gets.chomp == "t"') {|i,o,e,t|
27
+ i.puts 'f'
28
+ assert_equal(false, t.value.success?)
29
+ }
30
+ end
31
+
32
+ def test_stdout
33
+ Open3.popen3(RUBY, '-e', 'STDOUT.print "foo"') {|i,o,e,t|
34
+ assert_equal("foo", o.read)
35
+ }
36
+ end
37
+
38
+ def test_stderr
39
+ Open3.popen3(RUBY, '-e', 'STDERR.print "bar"') {|i,o,e,t|
40
+ assert_equal("bar", e.read)
41
+ }
42
+ end
43
+
44
+ def test_block
45
+ r = Open3.popen3(RUBY, '-e', 'STDOUT.print STDIN.read') {|i,o,e,t|
46
+ i.print "baz"
47
+ i.close
48
+ assert_equal("baz", o.read)
49
+ "qux"
50
+ }
51
+ assert_equal("qux", r)
52
+ end
53
+
54
+ def test_noblock
55
+ i,o,e,t = Open3.popen3(RUBY, '-e', 'STDOUT.print STDIN.read')
56
+ i.print "baz"
57
+ i.close
58
+ assert_equal("baz", o.read)
59
+ ensure
60
+ i.close
61
+ o.close
62
+ e.close
63
+ t.join
64
+ end
65
+
66
+ def test_commandline
67
+ commandline = "echo quux\n"
68
+ Open3.popen3(commandline) {|i,o,e,t|
69
+ assert_equal("quux\n", o.read)
70
+ }
71
+ end
72
+
73
+ def test_pid
74
+ Open3.popen3(RUBY, '-e', 'print $$') {|i,o,e,t|
75
+ pid = o.read.to_i
76
+ # assert_equal(pid, t[:pid])
77
+ assert_equal(pid, t.pid)
78
+ }
79
+ end
80
+
81
+ def test_env
82
+ Open3.popen3({'A' => 'B', 'C' => 'D'}, RUBY, '-e' 'p ENV["A"]') do |i, out, err, thr|
83
+ output = out.read
84
+ assert_equal("\"B\"\n", output)
85
+ end
86
+ end
87
+
88
+ def test_numeric_file_descriptor2
89
+ with_pipe {|r, w|
90
+ Open3.popen2(RUBY, '-e', 'STDERR.puts "foo"', 2 => w) {|i,o,t|
91
+ assert_equal("foo\n", r.gets)
92
+ }
93
+ }
94
+ end
95
+
96
+ def test_numeric_file_descriptor3
97
+ omit "passing FDs bigger than 2 is not supported on Windows" if /mswin|mingw/ =~ RbConfig::CONFIG['host_os']
98
+ with_pipe {|r, w|
99
+ Open3.popen3(RUBY, '-e', 'IO.open(3).puts "foo"', 3 => w) {|i,o,e,t|
100
+ assert_equal("foo\n", r.gets, "[GH-808] [ruby-core:67347] [Bug #10699]")
101
+ }
102
+ }
103
+ end
104
+
105
+ def with_pipe
106
+ r, w = IO.pipe
107
+ yield r, w
108
+ ensure
109
+ r.close
110
+ w.close
111
+ end
112
+
113
+ def with_reopen(io, arg)
114
+ old = io.dup
115
+ io.reopen(arg)
116
+ yield old
117
+ ensure
118
+ io.reopen(old)
119
+ old.close
120
+ end
121
+
122
+ def test_popen2
123
+ with_pipe {|r, w|
124
+ with_reopen(STDERR, w) {|old|
125
+ w.close
126
+ Open3.popen2(RUBY, '-e', 's=STDIN.read; STDOUT.print s+"o"; STDERR.print s+"e"') {|i,o,t|
127
+ assert_kind_of(Fiber, t)
128
+ i.print "z"
129
+ i.close
130
+ STDERR.reopen(old)
131
+ assert_equal("zo", o.read)
132
+ assert_equal("ze", r.read)
133
+ }
134
+ }
135
+ }
136
+ end
137
+
138
+ def test_popen2e
139
+ with_pipe {|r, w|
140
+ with_reopen(STDERR, w) {|old|
141
+ w.close
142
+ Open3.popen2e(RUBY, '-e', 's=STDIN.read; STDOUT.print s+"o"; STDOUT.flush; STDERR.print s+"e"') {|i,o,t|
143
+ assert_kind_of(Fiber, t)
144
+ i.print "y"
145
+ i.close
146
+ STDERR.reopen(old)
147
+ assert_equal("yoye", o.read)
148
+ assert_equal("", r.read)
149
+ }
150
+ }
151
+ }
152
+ end
153
+
154
+ def test_popen2e_noblock
155
+ i, o, t = Open3.popen2e(RUBY, '-e', 'STDOUT.print STDIN.read')
156
+ i.print "baz"
157
+ i.close
158
+ assert_equal("baz", o.read)
159
+ ensure
160
+ i.close
161
+ o.close
162
+ t.join
163
+ end
164
+
165
+ def test_capture3
166
+ o, e, s = Open3.capture3(RUBY, '-e', 'i=STDIN.read; print i+"o"; STDOUT.flush; STDERR.print i+"e"', :stdin_data=>"i")
167
+ assert_equal("io", o)
168
+ assert_equal("ie", e)
169
+ assert(s.success?)
170
+ end
171
+
172
+ def test_capture3_stdin_data_io
173
+ IO.pipe {|r, w|
174
+ w.write "i"
175
+ w.close
176
+ o, e, s = Open3.capture3(RUBY, '-e', 'i=STDIN.read; print i+"o"; STDOUT.flush; STDERR.print i+"e"', :stdin_data=>r)
177
+ assert_equal("io", o)
178
+ assert_equal("ie", e)
179
+ assert(s.success?)
180
+ }
181
+ end
182
+
183
+ def test_capture3_flip
184
+ o, e, s = Open3.capture3(RUBY, '-e', 'STDOUT.sync=true; 1000.times { print "o"*1000; STDERR.print "e"*1000 }')
185
+ assert_equal("o"*1000000, o)
186
+ assert_equal("e"*1000000, e)
187
+ assert(s.success?)
188
+ end
189
+
190
+ def test_capture2
191
+ o, s = Open3.capture2(RUBY, '-e', 'i=STDIN.read; print i+"o"', :stdin_data=>"i")
192
+ assert_equal("io", o)
193
+ assert(s.success?)
194
+ end
195
+
196
+ def test_capture2_stdin_data_io
197
+ IO.pipe {|r, w|
198
+ w.write "i"
199
+ w.close
200
+ o, s = Open3.capture2(RUBY, '-e', 'i=STDIN.read; print i+"o"', :stdin_data=>r)
201
+ assert_equal("io", o)
202
+ assert(s.success?)
203
+ }
204
+ end
205
+
206
+ def test_capture2e
207
+ oe, s = Open3.capture2e(RUBY, '-e', 'i=STDIN.read; print i+"o"; STDOUT.flush; STDERR.print i+"e"', :stdin_data=>"i")
208
+ assert_equal("ioie", oe)
209
+ assert(s.success?)
210
+ end
211
+
212
+ def test_capture2e_stdin_data_io
213
+ IO.pipe {|r, w|
214
+ w.write "i"
215
+ w.close
216
+ oe, s = Open3.capture2e(RUBY, '-e', 'i=STDIN.read; print i+"o"; STDOUT.flush; STDERR.print i+"e"', :stdin_data=>r)
217
+ assert_equal("ioie", oe)
218
+ assert(s.success?)
219
+ }
220
+ end
221
+
222
+ def test_capture3_stdin_data
223
+ o, e, s = Open3.capture3(RUBY, '-e', '', :stdin_data=>"z"*(1024*1024))
224
+ assert_equal("", o)
225
+ assert_equal("", e)
226
+ assert(s.success?)
227
+ end
228
+
229
+ def test_capture2_stdin_data
230
+ o, s = Open3.capture2(RUBY, '-e', '', :stdin_data=>"z"*(1024*1024))
231
+ assert_equal("", o)
232
+ assert(s.success?)
233
+ end
234
+
235
+ def test_capture2e_stdin_data
236
+ oe, s = Open3.capture2e(RUBY, '-e', '', :stdin_data=>"z"*(1024*1024))
237
+ assert_equal("", oe)
238
+ assert(s.success?)
239
+ end
240
+
241
+ def test_pipeline_rw
242
+ Open3.pipeline_rw([RUBY, '-e', 'print STDIN.read + "1"'],
243
+ [RUBY, '-e', 'print STDIN.read + "2"']) {|i,o,ts|
244
+ assert_kind_of(IO, i)
245
+ assert_kind_of(IO, o)
246
+ assert_kind_of(Array, ts)
247
+ assert_equal(2, ts.length)
248
+ ts.each {|t| assert_kind_of(Fiber, t) }
249
+ i.print "0"
250
+ i.close
251
+ assert_equal("012", o.read)
252
+ ts.each {|t|
253
+ assert(t.value.success?)
254
+ }
255
+ }
256
+ end
257
+
258
+ def test_pipeline_r
259
+ Open3.pipeline_r([RUBY, '-e', 'print "1"'],
260
+ [RUBY, '-e', 'print STDIN.read + "2"']) {|o,ts|
261
+ assert_kind_of(IO, o)
262
+ assert_kind_of(Array, ts)
263
+ assert_equal(2, ts.length)
264
+ ts.each {|t| assert_kind_of(Fiber, t) }
265
+ assert_equal("12", o.read)
266
+ ts.each {|t|
267
+ assert(t.value.success?)
268
+ }
269
+ }
270
+ end
271
+
272
+ def test_pipeline_w
273
+ command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
274
+ str = 'ttftff'
275
+ Open3.pipeline_w(*[command]*str.length) {|i,ts|
276
+ assert_kind_of(IO, i)
277
+ assert_kind_of(Array, ts)
278
+ assert_equal(str.length, ts.length)
279
+ ts.each {|t| assert_kind_of(Fiber, t) }
280
+ i.print str
281
+ i.close
282
+ ts.each_with_index {|t, ii|
283
+ assert_equal(str[ii] == ?t, t.value.success?)
284
+ }
285
+ }
286
+ end
287
+
288
+ def test_pipeline_start
289
+ command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
290
+ str = 'ttftff'
291
+ Open3.pipeline_start([RUBY, '-e', 'print ARGV[0]', str],
292
+ *([command]*str.length)) {|ts|
293
+ assert_kind_of(Array, ts)
294
+ assert_equal(str.length+1, ts.length)
295
+ ts.each {|t| assert_kind_of(Fiber, t) }
296
+ ts.each_with_index {|t, i|
297
+ if i == 0
298
+ assert(t.value.success?)
299
+ else
300
+ assert_equal(str[i-1] == ?t, t.value.success?)
301
+ end
302
+ }
303
+ }
304
+ end
305
+
306
+ def test_pipeline_start_noblock
307
+ ts = Open3.pipeline_start([RUBY, '-e', ''])
308
+ assert_kind_of(Array, ts)
309
+ assert_equal(1, ts.length)
310
+ ts.each {|t| assert_kind_of(Fiber, t) }
311
+ t = ts[0]
312
+ assert(t.value.success?)
313
+ end
314
+
315
+ def test_pipeline
316
+ command = [RUBY, '-e', 's=STDIN.read; print s[1..-1]; exit s[0] == ?t']
317
+ str = 'ttftff'
318
+ ss = Open3.pipeline([RUBY, '-e', 'print ARGV[0]', str],
319
+ *([command]*str.length))
320
+ assert_kind_of(Array, ss)
321
+ assert_equal(str.length+1, ss.length)
322
+ ss.each {|s| assert_kind_of(Process::Status, s) }
323
+ ss.each_with_index {|s, i|
324
+ if i == 0
325
+ assert(s.success?)
326
+ else
327
+ assert_equal(str[i-1] == ?t, s.success?)
328
+ end
329
+ }
330
+ end
331
+
332
+ def test_integer_and_symbol_key
333
+ command = [RUBY, '-e', 'puts "test_integer_and_symbol_key"']
334
+ out, status = Open3.capture2(*command, :chdir => '.', 2 => IO::NULL)
335
+ assert_equal("test_integer_and_symbol_key\n", out)
336
+ assert_predicate(status, :success?)
337
+ end
338
+ end
data/test/test_signal.rb CHANGED
@@ -4,10 +4,14 @@ require_relative 'helper'
4
4
 
5
5
  class SignalTrapTest < Minitest::Test
6
6
  def test_signal_handler_trace
7
+ skip # tracing system to be overhauled
8
+
7
9
  if Thread.current.backend.kind != :io_uring
8
10
  skip "Skipping signal handler trace because Backend_close on libev behaves differently"
9
11
  end
10
12
 
13
+ skip
14
+
11
15
  i1, o1 = IO.pipe
12
16
  i2, o2 = IO.pipe
13
17
  pid = Process.pid
@@ -86,10 +90,10 @@ class SignalTrapTest < Minitest::Test
86
90
  def test_signal_exception_handling
87
91
  i, o = IO.pipe
88
92
  pid = Polyphony.fork do
89
- i.close
90
93
  sleep 5
91
94
  rescue ::Interrupt => e
92
95
  o.puts "3-interrupt"
96
+ o.flush
93
97
  ensure
94
98
  o.close
95
99
  end
data/test/test_socket.rb CHANGED
@@ -41,9 +41,12 @@ class TCPSocketTest < MiniTest::Test
41
41
  client = TCPSocket.open('ipinfo.io', 80)
42
42
  client.write("GET / HTTP/1.0\r\nHost: ipinfo.io\r\n\r\n")
43
43
  result = nil
44
- move_on_after(3) {
45
- result = client.read
46
- }
44
+ 3.times do
45
+ move_on_after(3) {
46
+ result = client.read
47
+ }
48
+ break if result
49
+ end
47
50
  assert result =~ /HTTP\/1.0 200 OK/
48
51
  end
49
52
 
@@ -390,98 +393,3 @@ class SSLSocketTest < MiniTest::Test
390
393
  assert_kind_of OpenSSL::SSL::SSLError, errors.first
391
394
  end
392
395
  end
393
-
394
- class MultishotAcceptTest < MiniTest::Test
395
- def setup
396
- skip if !TCPServer.instance_methods(false).include?(:multishot_accept)
397
- end
398
-
399
- def start_tcp_server_on_random_port(host = '127.0.0.1')
400
- port = rand(1100..60000)
401
- server = TCPServer.new(host, port)
402
- [port, server]
403
- rescue Errno::EADDRINUSE
404
- retry
405
- end
406
-
407
- def test_multishot_accept_while_loop
408
- port, server = start_tcp_server_on_random_port
409
- server_fiber = spin do
410
- server.multishot_accept do
411
- while (socket = server.accept)
412
- spin do
413
- while (data = socket.gets(8192))
414
- socket << data
415
- end
416
- end
417
- end
418
- end
419
- end
420
-
421
- snooze
422
- client = TCPSocket.new('127.0.0.1', port)
423
- client.write("1234\n")
424
- assert_equal "1234\n", client.recv(8192)
425
- client.close
426
-
427
- client = TCPSocket.new('127.0.0.1', port)
428
- client.write("5678\n")
429
- assert_equal "5678\n", client.recv(8192)
430
- client.close
431
-
432
- ensure
433
- server_fiber&.stop
434
- server_fiber&.await
435
- server&.close
436
- end
437
-
438
- def spin_client(socket)
439
- spin do
440
- while (data = socket.gets(8192))
441
- socket << data
442
- end
443
- end
444
- end
445
-
446
- def test_multishot_accept_loop
447
- port, server = start_tcp_server_on_random_port
448
- server_fiber = spin do
449
- server.multishot_accept do
450
- server.accept_loop { |s| spin_client(s) }
451
- end
452
- end
453
-
454
- snooze
455
- client = TCPSocket.new('127.0.0.1', port)
456
- client.write("1234\n")
457
- assert_equal "1234\n", client.recv(8192)
458
- client.close
459
-
460
- client = TCPSocket.new('127.0.0.1', port)
461
- client.write("5678\n")
462
- assert_equal "5678\n", client.recv(8192)
463
- client.close
464
-
465
- ensure
466
- server_fiber&.stop
467
- server_fiber&.await
468
- server&.close
469
- end
470
-
471
- def test_multishot_accept_error
472
- port, server = start_tcp_server_on_random_port
473
- error = nil
474
- server_fiber = spin do
475
- server.multishot_accept do
476
- server.accept_loop { |s| spin_client(s) }
477
- rescue SystemCallError => e
478
- error = e
479
- end
480
- end
481
- snooze
482
- server.close
483
- snooze
484
- server_fiber.await
485
- assert_kind_of Errno::EBADF, error
486
- end
487
- end
data/test/test_sync.rb CHANGED
@@ -155,3 +155,49 @@ class MutexTest < MiniTest::Test
155
155
  assert_equal true, r
156
156
  end
157
157
  end
158
+
159
+ class MonitorTest < MiniTest::Test
160
+ def test_monitor
161
+ m = Monitor.new
162
+
163
+ assert_kind_of Polyphony::Monitor, m
164
+ end
165
+
166
+ def safe_check_owner(m)
167
+ m.mon_check_owner
168
+ true
169
+ rescue ThreadError
170
+ false
171
+ end
172
+
173
+ def test_monitor_mon_check_owner
174
+ m = Monitor.new
175
+
176
+ assert_equal false, safe_check_owner(m)
177
+
178
+ m.enter
179
+ assert_equal true, safe_check_owner(m)
180
+
181
+ spin do
182
+ assert_equal false, safe_check_owner(m)
183
+ end.join
184
+ end
185
+
186
+ def test_monitor_reentrancy
187
+ m = Monitor.new
188
+
189
+ assert_equal false, safe_check_owner(m)
190
+
191
+ m.enter
192
+ assert_equal true, safe_check_owner(m)
193
+
194
+ m.enter
195
+ assert_equal true, safe_check_owner(m)
196
+
197
+ m.exit
198
+ assert_equal true, safe_check_owner(m)
199
+
200
+ m.exit
201
+ assert_equal false, safe_check_owner(m)
202
+ end
203
+ end
data/test/test_thread.rb CHANGED
@@ -60,7 +60,7 @@ class ThreadTest < MiniTest::Test
60
60
  def test_thread_await_alias_method
61
61
  buffer = []
62
62
  spin { (1..3).each { |i| snooze; buffer << i } }
63
- t = Thread.new { sleep 0.01; buffer << 4; :foo }
63
+ t = Thread.new { sleep 0.1; buffer << 4; :foo }
64
64
  r = t.await
65
65
  t = nil
66
66
 
@@ -241,4 +241,13 @@ class ThreadTest < MiniTest::Test
241
241
  t.join
242
242
  assert_equal [1, 2, 3], buf
243
243
  end
244
+
245
+ def test_value
246
+ t = Thread.new { sleep 0.01; :foo }
247
+ assert_equal :foo, t.value
248
+
249
+ t = Thread.new { sleep 0.01; raise 'foo' }
250
+ assert_raises { t.value }
251
+ assert !t.alive?
252
+ end
244
253
  end
@@ -8,6 +8,11 @@ class ThreadPoolTest < MiniTest::Test
8
8
  @pool = Polyphony::ThreadPool.new
9
9
  end
10
10
 
11
+ def teardown
12
+ @pool.stop
13
+ super
14
+ end
15
+
11
16
  def test_process
12
17
  current_thread = Thread.current
13
18
 
@@ -30,7 +30,7 @@ class ThrottlerTest < MiniTest::Test
30
30
  f = spin { loop { t.process { buffer << 1 } } }
31
31
  sleep 0.02
32
32
  f.stop
33
- assert_in_range 2..4, buffer.size if IS_LINUX
33
+ assert_in_range 1..4, buffer.size if IS_LINUX
34
34
  end
35
35
 
36
36
  def test_throttler_with_invalid_argument
data/test/test_timer.rb CHANGED
@@ -4,11 +4,13 @@ require_relative 'helper'
4
4
 
5
5
  class TimerMoveOnAfterTest < MiniTest::Test
6
6
  def setup
7
+ super
7
8
  @timer = Polyphony::Timer.new(resolution: 0.01)
8
9
  end
9
10
 
10
11
  def teardown
11
12
  @timer.stop
13
+ super
12
14
  end
13
15
 
14
16
  def test_timer_move_on_after
@@ -56,11 +58,13 @@ end
56
58
 
57
59
  class TimerCancelAfterTest < MiniTest::Test
58
60
  def setup
61
+ super
59
62
  @timer = Polyphony::Timer.new(resolution: 0.01)
60
63
  end
61
64
 
62
65
  def teardown
63
66
  @timer.stop
67
+ super
64
68
  end
65
69
 
66
70
  def test_timer_cancel_after
@@ -134,21 +138,23 @@ end
134
138
 
135
139
  class TimerMiscTest < MiniTest::Test
136
140
  def setup
141
+ super
137
142
  @timer = Polyphony::Timer.new(resolution: 0.001)
138
143
  sleep 0
139
144
  end
140
145
 
141
146
  def teardown
142
147
  @timer.stop
148
+ super
143
149
  end
144
150
 
145
151
  def test_timer_after
146
152
  buffer = []
147
- f = @timer.after(0.01) { buffer << 2 }
153
+ f = @timer.after(0.1) { buffer << 2 }
148
154
  assert_kind_of Fiber, f
149
155
  snooze
150
156
  assert_equal [], buffer
151
- sleep 0.1
157
+ sleep 0.2
152
158
  assert_equal [2], buffer
153
159
  end
154
160
 
data/test/test_trace.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ __END__
4
+
3
5
  require_relative 'helper'
4
6
  require 'polyphony/core/debug'
5
7
 
@@ -85,6 +85,13 @@ jobs:
85
85
  cc: mips-linux-gnu-gcc
86
86
  cxx: mips-linux-gnu-g++
87
87
 
88
+ # hppa
89
+ - arch: hppa
90
+ cc_pkg: gcc-hppa-linux-gnu
91
+ cxx_pkg: g++-hppa-linux-gnu
92
+ cc: hppa-linux-gnu-gcc
93
+ cxx: hppa-linux-gnu-g++
94
+
88
95
  env:
89
96
  FLAGS: -g -O3 -Wall -Wextra -Werror -Wno-sign-compare ${{matrix.extra_flags}}
90
97
 
@@ -99,6 +106,7 @@ jobs:
99
106
  run: |
100
107
  if [[ "${{matrix.cc_pkg}}" == "clang" ]]; then \
101
108
  wget https://apt.llvm.org/llvm.sh -O /tmp/llvm.sh; \
109
+ sudo apt-get purge --auto-remove llvm python3-lldb-14 llvm-14 -y; \
102
110
  sudo bash /tmp/llvm.sh 17; \
103
111
  sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-17 400; \
104
112
  sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-17 400; \
@@ -22,6 +22,7 @@
22
22
  /examples/ucontext-cp
23
23
  /examples/poll-bench
24
24
  /examples/send-zerocopy
25
+ /examples/rsrc-update-bench
25
26
 
26
27
  /test/*.t
27
28
  /test/*.dmesg
@@ -8,6 +8,14 @@ liburing-2.4 release
8
8
  - CONFIG_NOLIBC is always enabled on x86-64, x86, and aarch64.
9
9
  - Add support for IORING_REGISTER_USE_REGISTERED_RING and use if available.
10
10
  - Add io_uring_close_ring_fd() function.
11
+ - Add io_uring_prep_msg_ring_fd_alloc function.
12
+ - Add io_uring_free_buf_ring() and io_uring_setup_buf_ring() functions.
13
+ - Ensure that io_uring_prep_accept_direct(), io_uring_prep_openat_direct(),
14
+ io_uring_prep_openat2_direct(), io_uring_prep_msg_ring_fd(), and
15
+ io_uring_prep_socket_direct() factor in being called with
16
+ IORING_FILE_INDEX_ALLOC for allocating a direct descriptor.
17
+ - Add io_uring_prep_sendto() function.
18
+ - Add io_uring_prep_cmd_sock() function.
11
19
 
12
20
  liburing-2.3 release
13
21