uringmachine 0.19 → 0.20.0
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/CHANGELOG.md +15 -0
- data/TODO.md +40 -0
- data/examples/bm_fileno.rb +33 -0
- data/examples/bm_mutex.rb +85 -0
- data/examples/bm_mutex_single.rb +33 -0
- data/examples/bm_queue.rb +27 -28
- data/examples/bm_send.rb +2 -5
- data/examples/bm_snooze.rb +20 -42
- data/examples/fiber_scheduler_demo.rb +15 -51
- data/examples/fiber_scheduler_fork.rb +24 -0
- data/examples/nc_ssl.rb +71 -0
- data/ext/um/extconf.rb +5 -15
- data/ext/um/um.c +73 -42
- data/ext/um/um.h +21 -11
- data/ext/um/um_async_op_class.c +2 -2
- data/ext/um/um_buffer.c +1 -1
- data/ext/um/um_class.c +94 -23
- data/ext/um/um_const.c +51 -3
- data/ext/um/um_mutex_class.c +1 -1
- data/ext/um/um_queue_class.c +1 -1
- data/ext/um/um_stream.c +5 -5
- data/ext/um/um_stream_class.c +3 -0
- data/ext/um/um_sync.c +22 -27
- data/ext/um/um_utils.c +59 -19
- data/grant-2025/journal.md +229 -0
- data/grant-2025/tasks.md +66 -0
- data/lib/uringmachine/fiber_scheduler.rb +180 -48
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +6 -0
- data/test/test_fiber_scheduler.rb +138 -0
- data/test/test_stream.rb +2 -2
- data/test/test_um.rb +451 -33
- data/vendor/liburing/.github/workflows/ci.yml +94 -1
- data/vendor/liburing/.github/workflows/test_build.c +9 -0
- data/vendor/liburing/configure +27 -0
- data/vendor/liburing/examples/Makefile +6 -0
- data/vendor/liburing/examples/helpers.c +8 -0
- data/vendor/liburing/examples/helpers.h +5 -0
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/Makefile +9 -3
- data/vendor/liburing/src/include/liburing/barrier.h +11 -5
- data/vendor/liburing/src/include/liburing/io_uring/query.h +41 -0
- data/vendor/liburing/src/include/liburing/io_uring.h +50 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +16 -4
- data/vendor/liburing/src/include/liburing.h +445 -121
- data/vendor/liburing/src/liburing-ffi.map +15 -0
- data/vendor/liburing/src/liburing.map +8 -0
- data/vendor/liburing/src/sanitize.c +4 -1
- data/vendor/liburing/src/setup.c +7 -4
- data/vendor/liburing/test/232c93d07b74.c +4 -16
- data/vendor/liburing/test/Makefile +15 -1
- data/vendor/liburing/test/accept.c +2 -13
- data/vendor/liburing/test/conn-unreach.c +132 -0
- data/vendor/liburing/test/fd-pass.c +32 -7
- data/vendor/liburing/test/fdinfo.c +39 -12
- data/vendor/liburing/test/fifo-futex-poll.c +114 -0
- data/vendor/liburing/test/fifo-nonblock-read.c +1 -12
- data/vendor/liburing/test/futex.c +1 -1
- data/vendor/liburing/test/helpers.c +99 -2
- data/vendor/liburing/test/helpers.h +9 -0
- data/vendor/liburing/test/io_uring_passthrough.c +6 -12
- data/vendor/liburing/test/mock_file.c +379 -0
- data/vendor/liburing/test/mock_file.h +47 -0
- data/vendor/liburing/test/nop.c +2 -2
- data/vendor/liburing/test/nop32-overflow.c +150 -0
- data/vendor/liburing/test/nop32.c +126 -0
- data/vendor/liburing/test/pipe.c +166 -0
- data/vendor/liburing/test/poll-race-mshot.c +13 -1
- data/vendor/liburing/test/recv-mshot-fair.c +81 -34
- data/vendor/liburing/test/recvsend_bundle.c +1 -1
- data/vendor/liburing/test/resize-rings.c +2 -0
- data/vendor/liburing/test/ring-query.c +322 -0
- data/vendor/liburing/test/ringbuf-loop.c +87 -0
- data/vendor/liburing/test/runtests.sh +2 -2
- data/vendor/liburing/test/send-zerocopy.c +43 -5
- data/vendor/liburing/test/send_recv.c +102 -32
- data/vendor/liburing/test/shutdown.c +2 -12
- data/vendor/liburing/test/socket-nb.c +3 -14
- data/vendor/liburing/test/socket-rw-eagain.c +2 -12
- data/vendor/liburing/test/socket-rw-offset.c +2 -12
- data/vendor/liburing/test/socket-rw.c +2 -12
- data/vendor/liburing/test/sqe-mixed-bad-wrap.c +87 -0
- data/vendor/liburing/test/sqe-mixed-nop.c +82 -0
- data/vendor/liburing/test/sqe-mixed-uring_cmd.c +153 -0
- data/vendor/liburing/test/timestamp.c +56 -19
- data/vendor/liburing/test/vec-regbuf.c +2 -4
- data/vendor/liburing/test/wq-aff.c +7 -0
- metadata +24 -2
data/test/test_um.rb
CHANGED
|
@@ -142,6 +142,31 @@ class ScheduleTest < UMBaseTest
|
|
|
142
142
|
assert_kind_of TOError, e
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
+
def test_timeout_stress
|
|
146
|
+
skip
|
|
147
|
+
# GC.stress = true
|
|
148
|
+
c = 0
|
|
149
|
+
fs = 100.times.map {
|
|
150
|
+
machine.spin {
|
|
151
|
+
q = UM::Queue.new
|
|
152
|
+
1000.times {
|
|
153
|
+
machine.sleep rand(0.001..0.005)
|
|
154
|
+
begin
|
|
155
|
+
machine.timeout(rand(0.001..0.06), TOError) do
|
|
156
|
+
machine.shift(q)
|
|
157
|
+
end
|
|
158
|
+
rescue => _e
|
|
159
|
+
c += 1
|
|
160
|
+
STDOUT << '*' if c % 1000 == 0
|
|
161
|
+
end
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
machine.join(*fs)
|
|
166
|
+
ensure
|
|
167
|
+
GC.stress = false
|
|
168
|
+
end
|
|
169
|
+
|
|
145
170
|
def test_timeout_with_raising_block
|
|
146
171
|
e = nil
|
|
147
172
|
begin
|
|
@@ -302,7 +327,7 @@ class PeriodicallyTest < UMBaseTest
|
|
|
302
327
|
rescue Cancel
|
|
303
328
|
cancel = 1
|
|
304
329
|
end
|
|
305
|
-
|
|
330
|
+
20.times { machine.snooze }
|
|
306
331
|
assert_equal 0, machine.pending_count
|
|
307
332
|
t1 = monotonic_clock
|
|
308
333
|
assert_in_range 0.05..0.08, t1 - t0
|
|
@@ -394,6 +419,51 @@ class ReadTest < UMBaseTest
|
|
|
394
419
|
assert_equal 3, result
|
|
395
420
|
assert_equal 'baz', sio.read
|
|
396
421
|
end
|
|
422
|
+
|
|
423
|
+
def test_read_io_buffer
|
|
424
|
+
r, w = UM.pipe
|
|
425
|
+
machine.write(w, 'foobar')
|
|
426
|
+
|
|
427
|
+
read_buffer = IO::Buffer.new(3)
|
|
428
|
+
res = machine.read(r, read_buffer, 3)
|
|
429
|
+
assert_equal 3, res
|
|
430
|
+
assert_equal 'foo', read_buffer.get_string(0, 3)
|
|
431
|
+
|
|
432
|
+
machine.close(w)
|
|
433
|
+
|
|
434
|
+
res = machine.read(r, read_buffer)
|
|
435
|
+
assert_equal 3, res
|
|
436
|
+
assert_equal 'bar', read_buffer.get_string(0, 3)
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
def test_read_io_buffer_resize
|
|
440
|
+
r, w = UM.pipe
|
|
441
|
+
machine.write(w, 'foobar')
|
|
442
|
+
machine.close(w)
|
|
443
|
+
|
|
444
|
+
read_buffer = IO::Buffer.new(3)
|
|
445
|
+
res = machine.read(r, read_buffer, 6)
|
|
446
|
+
assert_equal 6, res
|
|
447
|
+
assert_equal 6, read_buffer.size
|
|
448
|
+
assert_equal 'foobar', read_buffer.get_string(0, res)
|
|
449
|
+
|
|
450
|
+
r, w = UM.pipe
|
|
451
|
+
machine.write(w, 'foobar')
|
|
452
|
+
machine.close(w)
|
|
453
|
+
|
|
454
|
+
read_buffer = IO::Buffer.new(3)
|
|
455
|
+
res = machine.read(r, read_buffer, 128, -1)
|
|
456
|
+
assert_equal 6, res
|
|
457
|
+
assert_equal 131, read_buffer.size
|
|
458
|
+
assert_equal 'foobar', read_buffer.get_string(3, res)
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
def test_read_invalid_buffer
|
|
462
|
+
r, _w = UM.pipe
|
|
463
|
+
assert_raises(UM::Error) {
|
|
464
|
+
machine.read(r, [])
|
|
465
|
+
}
|
|
466
|
+
end
|
|
397
467
|
end
|
|
398
468
|
|
|
399
469
|
class ReadEachTest < UMBaseTest
|
|
@@ -561,6 +631,54 @@ class WriteTest < UMBaseTest
|
|
|
561
631
|
end
|
|
562
632
|
assert_equal 0, machine.pending_count
|
|
563
633
|
end
|
|
634
|
+
|
|
635
|
+
def test_write_io_buffer
|
|
636
|
+
r, w = UM.pipe
|
|
637
|
+
|
|
638
|
+
msg = 'Hello world'
|
|
639
|
+
write_buffer = IO::Buffer.new(msg.bytesize)
|
|
640
|
+
write_buffer.set_string(msg, 0)
|
|
641
|
+
|
|
642
|
+
machine.write(w, write_buffer)
|
|
643
|
+
machine.close(w)
|
|
644
|
+
|
|
645
|
+
str = +''
|
|
646
|
+
machine.read(r, str, 8192)
|
|
647
|
+
assert_equal msg, str
|
|
648
|
+
end
|
|
649
|
+
|
|
650
|
+
def test_write_io_buffer_with_len
|
|
651
|
+
r, w = UM.pipe
|
|
652
|
+
msg = 'Hello world'
|
|
653
|
+
write_buffer = IO::Buffer.new(msg.bytesize)
|
|
654
|
+
write_buffer.set_string(msg)
|
|
655
|
+
|
|
656
|
+
machine.write(w, write_buffer, 5)
|
|
657
|
+
machine.close(w)
|
|
658
|
+
|
|
659
|
+
str = +''
|
|
660
|
+
machine.read(r, str, 8192)
|
|
661
|
+
assert_equal 'Hello', str
|
|
662
|
+
|
|
663
|
+
r, w = UM.pipe
|
|
664
|
+
msg = 'Hello world'
|
|
665
|
+
write_buffer = IO::Buffer.new(msg.bytesize)
|
|
666
|
+
write_buffer.set_string(msg)
|
|
667
|
+
|
|
668
|
+
machine.write(w, write_buffer, -1)
|
|
669
|
+
machine.close(w)
|
|
670
|
+
|
|
671
|
+
str = +''
|
|
672
|
+
machine.read(r, str, 8192)
|
|
673
|
+
assert_equal 'Hello world', str
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
def test_write_invalid_buffer
|
|
677
|
+
_r, w = UM.pipe
|
|
678
|
+
assert_raises(UM::Error) {
|
|
679
|
+
machine.write(w, [])
|
|
680
|
+
}
|
|
681
|
+
end
|
|
564
682
|
end
|
|
565
683
|
|
|
566
684
|
class WriteAsyncTest < UMBaseTest
|
|
@@ -601,6 +719,28 @@ class WriteAsyncTest < UMBaseTest
|
|
|
601
719
|
machine.snooze
|
|
602
720
|
assert_equal 0, machine.pending_count
|
|
603
721
|
end
|
|
722
|
+
|
|
723
|
+
def test_write_async_io_buffer
|
|
724
|
+
r, w = UM.pipe
|
|
725
|
+
|
|
726
|
+
msg = 'Hello world'
|
|
727
|
+
write_buffer = IO::Buffer.new(msg.bytesize)
|
|
728
|
+
write_buffer.set_string(msg)
|
|
729
|
+
|
|
730
|
+
machine.write_async(w, write_buffer)
|
|
731
|
+
3.times { machine.snooze }
|
|
732
|
+
machine.close(w)
|
|
733
|
+
|
|
734
|
+
str = +''
|
|
735
|
+
machine.read(r, str, 8192)
|
|
736
|
+
assert_equal msg, str
|
|
737
|
+
end
|
|
738
|
+
|
|
739
|
+
def test_write_async_invalid_buffer
|
|
740
|
+
_r, w = UM.pipe
|
|
741
|
+
|
|
742
|
+
assert_raises(UM::Error) { machine.write_async(w, []) }
|
|
743
|
+
end
|
|
604
744
|
end
|
|
605
745
|
|
|
606
746
|
class CloseTest < UMBaseTest
|
|
@@ -618,7 +758,7 @@ class CloseTest < UMBaseTest
|
|
|
618
758
|
end
|
|
619
759
|
|
|
620
760
|
def test_close_bad_fd
|
|
621
|
-
|
|
761
|
+
_r, w = IO.pipe
|
|
622
762
|
machine.close(w.fileno)
|
|
623
763
|
|
|
624
764
|
assert_raises(Errno::EBADF) { machine.close(w.fileno) }
|
|
@@ -877,6 +1017,78 @@ class SendTest < UMBaseTest
|
|
|
877
1017
|
ensure
|
|
878
1018
|
t&.kill
|
|
879
1019
|
end
|
|
1020
|
+
|
|
1021
|
+
|
|
1022
|
+
def test_send_io_buffer
|
|
1023
|
+
@port = assign_port
|
|
1024
|
+
@server = TCPServer.open('127.0.0.1', @port)
|
|
1025
|
+
|
|
1026
|
+
t = Thread.new do
|
|
1027
|
+
conn = @server.accept
|
|
1028
|
+
str = conn.readpartial(42)
|
|
1029
|
+
conn.write("You said: #{str} (#{str.bytesize})")
|
|
1030
|
+
sleep
|
|
1031
|
+
end
|
|
1032
|
+
|
|
1033
|
+
fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
|
1034
|
+
res = machine.connect(fd, '127.0.0.1', @port)
|
|
1035
|
+
assert_equal 0, res
|
|
1036
|
+
|
|
1037
|
+
buffer = IO::Buffer.new(6)
|
|
1038
|
+
buffer.set_string('foobar')
|
|
1039
|
+
res = machine.send(fd, buffer, 6, 0)
|
|
1040
|
+
assert_equal 6, res
|
|
1041
|
+
|
|
1042
|
+
buf = +''
|
|
1043
|
+
res = machine.read(fd, buf, 42)
|
|
1044
|
+
assert_equal 20, res
|
|
1045
|
+
assert_equal 'You said: foobar (6)', buf
|
|
1046
|
+
ensure
|
|
1047
|
+
t&.kill
|
|
1048
|
+
@server&.close
|
|
1049
|
+
end
|
|
1050
|
+
|
|
1051
|
+
def test_send_io_buffer_negative_len
|
|
1052
|
+
t = Thread.new do
|
|
1053
|
+
conn = @server.accept
|
|
1054
|
+
str = conn.readpartial(42)
|
|
1055
|
+
conn.write("You said: #{str} (#{str.bytesize})")
|
|
1056
|
+
sleep
|
|
1057
|
+
end
|
|
1058
|
+
|
|
1059
|
+
fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
|
1060
|
+
res = machine.connect(fd, '127.0.0.1', @port)
|
|
1061
|
+
assert_equal 0, res
|
|
1062
|
+
|
|
1063
|
+
buffer = IO::Buffer.new(6)
|
|
1064
|
+
buffer.set_string('foobar')
|
|
1065
|
+
res = machine.send(fd, buffer, -1, 0)
|
|
1066
|
+
assert_equal 6, res
|
|
1067
|
+
|
|
1068
|
+
buf = +''
|
|
1069
|
+
res = machine.read(fd, buf, 42)
|
|
1070
|
+
assert_equal 20, res
|
|
1071
|
+
assert_equal 'You said: foobar (6)', buf
|
|
1072
|
+
ensure
|
|
1073
|
+
t&.kill
|
|
1074
|
+
end
|
|
1075
|
+
|
|
1076
|
+
def test_send_invalid_buffer
|
|
1077
|
+
t = Thread.new do
|
|
1078
|
+
conn = @server.accept
|
|
1079
|
+
str = conn.readpartial(42)
|
|
1080
|
+
conn.write("You said: #{str} (#{str.bytesize})")
|
|
1081
|
+
sleep
|
|
1082
|
+
end
|
|
1083
|
+
|
|
1084
|
+
fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
|
1085
|
+
res = machine.connect(fd, '127.0.0.1', @port)
|
|
1086
|
+
assert_equal 0, res
|
|
1087
|
+
|
|
1088
|
+
assert_raises(UM::Error) { machine.send(fd, [], -1, 0) }
|
|
1089
|
+
ensure
|
|
1090
|
+
t&.kill
|
|
1091
|
+
end
|
|
880
1092
|
end
|
|
881
1093
|
|
|
882
1094
|
class RecvTest < UMBaseTest
|
|
@@ -909,6 +1121,25 @@ class RecvTest < UMBaseTest
|
|
|
909
1121
|
ensure
|
|
910
1122
|
t&.kill
|
|
911
1123
|
end
|
|
1124
|
+
|
|
1125
|
+
def test_recv_io_buffer
|
|
1126
|
+
t = Thread.new do
|
|
1127
|
+
conn = @server.accept
|
|
1128
|
+
conn.write('foobar')
|
|
1129
|
+
sleep
|
|
1130
|
+
end
|
|
1131
|
+
|
|
1132
|
+
fd = machine.socket(UM::AF_INET, UM::SOCK_STREAM, 0, 0)
|
|
1133
|
+
res = machine.connect(fd, '127.0.0.1', @port)
|
|
1134
|
+
assert_equal 0, res
|
|
1135
|
+
|
|
1136
|
+
buf = IO::Buffer.new(12)
|
|
1137
|
+
res = machine.recv(fd, buf, 12, 0)
|
|
1138
|
+
assert_equal 6, res
|
|
1139
|
+
assert_equal 'foobar', buf.get_string(0, 6)
|
|
1140
|
+
ensure
|
|
1141
|
+
t&.kill
|
|
1142
|
+
end
|
|
912
1143
|
end
|
|
913
1144
|
|
|
914
1145
|
class RecvEachTest < UMBaseTest
|
|
@@ -1094,6 +1325,25 @@ class SynchronizeTest < UMBaseTest
|
|
|
1094
1325
|
assert_equal [11, 12, 13, 21, 22, 23], buf
|
|
1095
1326
|
assert_equal 0, machine.pending_count
|
|
1096
1327
|
end
|
|
1328
|
+
|
|
1329
|
+
def test_synchronize_multi
|
|
1330
|
+
mutex = UM::Mutex.new
|
|
1331
|
+
buf = []
|
|
1332
|
+
fibers = (1..8).map { |i|
|
|
1333
|
+
machine.spin do
|
|
1334
|
+
machine.synchronize(mutex) do
|
|
1335
|
+
buf << (i * 10) + 1
|
|
1336
|
+
machine.sleep(0.01)
|
|
1337
|
+
buf << (i * 10) + 2
|
|
1338
|
+
end
|
|
1339
|
+
machine.snooze
|
|
1340
|
+
buf << (i * 10) + 3
|
|
1341
|
+
end
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
machine.join(*fibers)
|
|
1345
|
+
assert_equal [11, 12, 21, 13, 22, 31, 23, 32, 41, 33, 42, 51, 43, 52, 61, 53, 62, 71, 63, 72, 81, 73, 82, 83], buf
|
|
1346
|
+
end
|
|
1097
1347
|
end
|
|
1098
1348
|
|
|
1099
1349
|
class QueueTest < UMBaseTest
|
|
@@ -1310,12 +1560,67 @@ class PipeTest < UMBaseTest
|
|
|
1310
1560
|
end
|
|
1311
1561
|
end
|
|
1312
1562
|
|
|
1563
|
+
class PidfdTest < UMBaseTest
|
|
1564
|
+
def test_pidfd_open
|
|
1565
|
+
pid = fork { exit 13 }
|
|
1566
|
+
fd = UM.pidfd_open(pid)
|
|
1567
|
+
assert_kind_of Integer, fd
|
|
1568
|
+
|
|
1569
|
+
pid2, status = machine.waitid(P_PIDFD, fd, UM::WEXITED)
|
|
1570
|
+
assert_equal pid, pid2
|
|
1571
|
+
assert_equal 13, status
|
|
1572
|
+
ensure
|
|
1573
|
+
machine.close(fd) rescue nil
|
|
1574
|
+
Process.wait(pid) rescue nil
|
|
1575
|
+
end
|
|
1576
|
+
|
|
1577
|
+
def test_pidfd_open_invalid_pid
|
|
1578
|
+
assert_raises(SystemCallError) { UM.pidfd_open(Process.pid + 1) }
|
|
1579
|
+
end
|
|
1580
|
+
|
|
1581
|
+
def test_pidfd_send_signal
|
|
1582
|
+
fd = UM.pidfd_open(Process.pid)
|
|
1583
|
+
buf = []
|
|
1584
|
+
trap('SIGUSR1') { buf << :SIGUSR1 }
|
|
1585
|
+
|
|
1586
|
+
ret = UM.pidfd_send_signal(fd, UM::SIGUSR1)
|
|
1587
|
+
assert_equal fd, ret
|
|
1588
|
+
sleep 0.01
|
|
1589
|
+
|
|
1590
|
+
assert_equal [:SIGUSR1], buf
|
|
1591
|
+
ensure
|
|
1592
|
+
machine.close(fd) rescue nil
|
|
1593
|
+
end
|
|
1594
|
+
|
|
1595
|
+
def test_pidfd_send_signal_test
|
|
1596
|
+
fd = UM.pidfd_open(Process.pid)
|
|
1597
|
+
buf = []
|
|
1598
|
+
trap('SIGUSR1') { buf << :SIGUSR1 }
|
|
1599
|
+
|
|
1600
|
+
ret = UM.pidfd_send_signal(fd, 0)
|
|
1601
|
+
assert_equal fd, ret
|
|
1602
|
+
sleep 0.01
|
|
1603
|
+
assert_equal [], buf
|
|
1604
|
+
|
|
1605
|
+
pid = fork { exit 13 }
|
|
1606
|
+
fd2 = UM.pidfd_open(pid)
|
|
1607
|
+
assert_kind_of Integer, fd2
|
|
1608
|
+
|
|
1609
|
+
Process.wait(pid)
|
|
1610
|
+
assert_raises(SystemCallError) { UM.pidfd_send_signal(fd2, 0) }
|
|
1611
|
+
ensure
|
|
1612
|
+
machine.close(fd) rescue nil
|
|
1613
|
+
machine.close(fd2) rescue nil
|
|
1614
|
+
Process.wait(pid) rescue nil
|
|
1615
|
+
end
|
|
1616
|
+
end
|
|
1617
|
+
|
|
1313
1618
|
class PollTest < UMBaseTest
|
|
1314
1619
|
def test_poll
|
|
1315
1620
|
rfd, wfd = UM.pipe
|
|
1316
1621
|
|
|
1317
1622
|
events = []
|
|
1318
|
-
|
|
1623
|
+
machine.spin do
|
|
1319
1624
|
events << :pre
|
|
1320
1625
|
events << machine.poll(rfd, UM::POLLIN)
|
|
1321
1626
|
events << :post
|
|
@@ -1341,38 +1646,81 @@ class PollTest < UMBaseTest
|
|
|
1341
1646
|
end
|
|
1342
1647
|
end
|
|
1343
1648
|
|
|
1344
|
-
class
|
|
1345
|
-
def
|
|
1346
|
-
skip if UM.kernel_version < 607
|
|
1347
|
-
|
|
1649
|
+
class WaitidTest < UMBaseTest
|
|
1650
|
+
def test_waitid
|
|
1348
1651
|
msg = 'hello from child'
|
|
1652
|
+
_rfd, wfd = UM.pipe
|
|
1653
|
+
child_pid = fork do
|
|
1654
|
+
m = UM.new
|
|
1655
|
+
m.write(wfd, msg)
|
|
1656
|
+
m.close(wfd)
|
|
1657
|
+
exit 42
|
|
1658
|
+
end
|
|
1349
1659
|
|
|
1350
|
-
|
|
1351
|
-
|
|
1660
|
+
pid, status = machine.waitid(UM::P_PID, child_pid, UM::WEXITED)
|
|
1661
|
+
assert_equal child_pid, pid
|
|
1662
|
+
assert_equal 42, status
|
|
1663
|
+
ensure
|
|
1664
|
+
Process.wait(child_pid) rescue nil
|
|
1665
|
+
end
|
|
1666
|
+
|
|
1667
|
+
def test_waitid_invalid_pid
|
|
1668
|
+
assert_raises(Errno::ECHILD) {
|
|
1669
|
+
machine.waitid(UM::P_PID, Process.pid + 1, UM::WEXITED)
|
|
1670
|
+
}
|
|
1671
|
+
end
|
|
1672
|
+
|
|
1673
|
+
def test_waitid_invalid_idtype
|
|
1674
|
+
assert_raises(Errno::EINVAL) {
|
|
1675
|
+
machine.waitid(1234, 0, UM::WEXITED)
|
|
1676
|
+
}
|
|
1677
|
+
end
|
|
1678
|
+
|
|
1679
|
+
def test_waitid_invalid_options
|
|
1680
|
+
assert_raises(Errno::EINVAL) {
|
|
1681
|
+
machine.waitid(P_ALL, 0, 1234)
|
|
1682
|
+
}
|
|
1683
|
+
end
|
|
1684
|
+
|
|
1685
|
+
def test_waitid_P_ALL
|
|
1686
|
+
msg = 'hello from child'
|
|
1687
|
+
_rfd, wfd = UM.pipe
|
|
1688
|
+
child_pid = fork do
|
|
1352
1689
|
m = UM.new
|
|
1353
1690
|
m.write(wfd, msg)
|
|
1354
1691
|
m.close(wfd)
|
|
1355
1692
|
exit 42
|
|
1356
1693
|
end
|
|
1357
1694
|
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
assert_equal
|
|
1695
|
+
pid, status = machine.waitid(UM::P_ALL, 0, UM::WEXITED)
|
|
1696
|
+
assert_equal child_pid, pid
|
|
1697
|
+
assert_equal 42, status
|
|
1698
|
+
ensure
|
|
1699
|
+
Process.wait(child_pid) rescue nil
|
|
1700
|
+
end
|
|
1361
1701
|
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1702
|
+
def test_waitid_P_PGID
|
|
1703
|
+
msg = 'hello from child'
|
|
1704
|
+
_rfd, wfd = UM.pipe
|
|
1705
|
+
child_pid = fork do
|
|
1706
|
+
m = UM.new
|
|
1707
|
+
m.write(wfd, msg)
|
|
1708
|
+
m.close(wfd)
|
|
1709
|
+
exit 42
|
|
1710
|
+
end
|
|
1711
|
+
|
|
1712
|
+
pid, status = machine.waitid(UM::P_PGID, Process.getpgrp, UM::WEXITED)
|
|
1713
|
+
assert_equal child_pid, pid
|
|
1714
|
+
assert_equal 42, status
|
|
1366
1715
|
ensure
|
|
1367
|
-
Process.wait(
|
|
1716
|
+
Process.wait(child_pid) rescue nil
|
|
1368
1717
|
end
|
|
1369
1718
|
|
|
1370
|
-
def
|
|
1371
|
-
skip if
|
|
1719
|
+
def test_waitid_status
|
|
1720
|
+
skip if !machine.respond_to?(:waitid_status)
|
|
1372
1721
|
|
|
1373
1722
|
msg = 'hello from child'
|
|
1374
|
-
|
|
1375
|
-
rfd, wfd = UM.pipe
|
|
1723
|
+
_rfd, wfd = UM.pipe
|
|
1376
1724
|
pid = fork do
|
|
1377
1725
|
m = UM.new
|
|
1378
1726
|
m.write(wfd, msg)
|
|
@@ -1380,23 +1728,76 @@ class WaitTest < UMBaseTest
|
|
|
1380
1728
|
exit 42
|
|
1381
1729
|
end
|
|
1382
1730
|
|
|
1383
|
-
|
|
1384
|
-
assert_kind_of
|
|
1385
|
-
assert_equal
|
|
1731
|
+
status = machine.waitid_status(UM::P_PID, pid, UM::WEXITED)
|
|
1732
|
+
assert_kind_of Process::Status, status
|
|
1733
|
+
assert_equal pid, status.pid
|
|
1734
|
+
assert_equal 42, status.exitstatus
|
|
1735
|
+
ensure
|
|
1736
|
+
Process.wait(pid) rescue nil
|
|
1737
|
+
end
|
|
1386
1738
|
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1739
|
+
def test_waitid_status_invalid_pid
|
|
1740
|
+
skip if !machine.respond_to?(:waitid_status)
|
|
1741
|
+
|
|
1742
|
+
assert_raises(Errno::ECHILD) {
|
|
1743
|
+
machine.waitid_status(UM::P_PID, Process.pid + 1, UM::WEXITED)
|
|
1744
|
+
}
|
|
1745
|
+
end
|
|
1746
|
+
|
|
1747
|
+
def test_waitid_status_invalid_idtype
|
|
1748
|
+
skip if !machine.respond_to?(:waitid_status)
|
|
1391
1749
|
|
|
1750
|
+
assert_raises(Errno::EINVAL) {
|
|
1751
|
+
machine.waitid_status(1234, 0, UM::WEXITED)
|
|
1752
|
+
}
|
|
1753
|
+
end
|
|
1754
|
+
|
|
1755
|
+
def test_waitid_status_invalid_options
|
|
1756
|
+
skip if !machine.respond_to?(:waitid_status)
|
|
1757
|
+
|
|
1758
|
+
assert_raises(Errno::EINVAL) {
|
|
1759
|
+
machine.waitid_status(P_ALL, 0, 1234)
|
|
1760
|
+
}
|
|
1761
|
+
end
|
|
1762
|
+
|
|
1763
|
+
def test_waitid_status_P_ALL
|
|
1764
|
+
skip if !machine.respond_to?(:waitid_status)
|
|
1765
|
+
|
|
1766
|
+
msg = 'hello from child'
|
|
1767
|
+
_rfd, wfd = UM.pipe
|
|
1768
|
+
pid = fork do
|
|
1769
|
+
m = UM.new
|
|
1770
|
+
m.write(wfd, msg)
|
|
1771
|
+
m.close(wfd)
|
|
1772
|
+
exit 42
|
|
1773
|
+
end
|
|
1774
|
+
|
|
1775
|
+
status = machine.waitid_status(UM::P_ALL, 0, UM::WEXITED)
|
|
1776
|
+
assert_kind_of Process::Status, status
|
|
1777
|
+
assert_equal pid, status.pid
|
|
1778
|
+
assert_equal 42, status.exitstatus
|
|
1392
1779
|
ensure
|
|
1393
|
-
Process.wait(pid) rescue
|
|
1780
|
+
Process.wait(pid) rescue nil
|
|
1394
1781
|
end
|
|
1395
1782
|
|
|
1396
|
-
def
|
|
1397
|
-
skip if
|
|
1783
|
+
def test_waitid_status_P_PGID
|
|
1784
|
+
skip if !machine.respond_to?(:waitid_status)
|
|
1785
|
+
|
|
1786
|
+
msg = 'hello from child'
|
|
1787
|
+
_rfd, wfd = UM.pipe
|
|
1788
|
+
pid = fork do
|
|
1789
|
+
m = UM.new
|
|
1790
|
+
m.write(wfd, msg)
|
|
1791
|
+
m.close(wfd)
|
|
1792
|
+
exit 42
|
|
1793
|
+
end
|
|
1398
1794
|
|
|
1399
|
-
|
|
1795
|
+
status = machine.waitid_status(UM::P_PGID, Process.getpgrp, UM::WEXITED)
|
|
1796
|
+
assert_kind_of Process::Status, status
|
|
1797
|
+
assert_equal pid, status.pid
|
|
1798
|
+
assert_equal 42, status.exitstatus
|
|
1799
|
+
ensure
|
|
1800
|
+
Process.wait(pid) rescue nil
|
|
1400
1801
|
end
|
|
1401
1802
|
end
|
|
1402
1803
|
|
|
@@ -1484,7 +1885,7 @@ class ForkTest < UMBaseTest
|
|
|
1484
1885
|
assert_equal 3, ret
|
|
1485
1886
|
assert_equal 'foo', buf
|
|
1486
1887
|
ensure
|
|
1487
|
-
Process.wait(child_pid) rescue
|
|
1888
|
+
Process.wait(child_pid) rescue nil
|
|
1488
1889
|
end
|
|
1489
1890
|
end
|
|
1490
1891
|
|
|
@@ -1548,3 +1949,20 @@ class SendBundleTest < UMBaseTest
|
|
|
1548
1949
|
assert_equal strs.map(&:to_s).join, buf
|
|
1549
1950
|
end
|
|
1550
1951
|
end
|
|
1952
|
+
|
|
1953
|
+
class NonBlockTest < UMBaseTest
|
|
1954
|
+
def test_io_nonblock?
|
|
1955
|
+
assert_equal false, UM.io_nonblock?(STDIN)
|
|
1956
|
+
end
|
|
1957
|
+
|
|
1958
|
+
def test_io_set_nonblock
|
|
1959
|
+
r, _w = IO.pipe
|
|
1960
|
+
assert_equal true, UM.io_nonblock?(r)
|
|
1961
|
+
|
|
1962
|
+
UM.io_set_nonblock(r, false)
|
|
1963
|
+
assert_equal false, UM.io_nonblock?(r)
|
|
1964
|
+
|
|
1965
|
+
UM.io_set_nonblock(r, true)
|
|
1966
|
+
assert_equal true, UM.io_nonblock?(r)
|
|
1967
|
+
end
|
|
1968
|
+
end
|