uringmachine 0.19.1 → 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 +12 -1
- data/TODO.md +0 -1
- 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 +57 -41
- 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 +427 -34
- 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
|
@@ -164,7 +164,7 @@ class ScheduleTest < UMBaseTest
|
|
|
164
164
|
}
|
|
165
165
|
machine.join(*fs)
|
|
166
166
|
ensure
|
|
167
|
-
GC.stress = false
|
|
167
|
+
GC.stress = false
|
|
168
168
|
end
|
|
169
169
|
|
|
170
170
|
def test_timeout_with_raising_block
|
|
@@ -327,7 +327,7 @@ class PeriodicallyTest < UMBaseTest
|
|
|
327
327
|
rescue Cancel
|
|
328
328
|
cancel = 1
|
|
329
329
|
end
|
|
330
|
-
|
|
330
|
+
20.times { machine.snooze }
|
|
331
331
|
assert_equal 0, machine.pending_count
|
|
332
332
|
t1 = monotonic_clock
|
|
333
333
|
assert_in_range 0.05..0.08, t1 - t0
|
|
@@ -419,6 +419,51 @@ class ReadTest < UMBaseTest
|
|
|
419
419
|
assert_equal 3, result
|
|
420
420
|
assert_equal 'baz', sio.read
|
|
421
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
|
|
422
467
|
end
|
|
423
468
|
|
|
424
469
|
class ReadEachTest < UMBaseTest
|
|
@@ -586,6 +631,54 @@ class WriteTest < UMBaseTest
|
|
|
586
631
|
end
|
|
587
632
|
assert_equal 0, machine.pending_count
|
|
588
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
|
|
589
682
|
end
|
|
590
683
|
|
|
591
684
|
class WriteAsyncTest < UMBaseTest
|
|
@@ -626,6 +719,28 @@ class WriteAsyncTest < UMBaseTest
|
|
|
626
719
|
machine.snooze
|
|
627
720
|
assert_equal 0, machine.pending_count
|
|
628
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
|
|
629
744
|
end
|
|
630
745
|
|
|
631
746
|
class CloseTest < UMBaseTest
|
|
@@ -643,7 +758,7 @@ class CloseTest < UMBaseTest
|
|
|
643
758
|
end
|
|
644
759
|
|
|
645
760
|
def test_close_bad_fd
|
|
646
|
-
|
|
761
|
+
_r, w = IO.pipe
|
|
647
762
|
machine.close(w.fileno)
|
|
648
763
|
|
|
649
764
|
assert_raises(Errno::EBADF) { machine.close(w.fileno) }
|
|
@@ -902,6 +1017,78 @@ class SendTest < UMBaseTest
|
|
|
902
1017
|
ensure
|
|
903
1018
|
t&.kill
|
|
904
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
|
|
905
1092
|
end
|
|
906
1093
|
|
|
907
1094
|
class RecvTest < UMBaseTest
|
|
@@ -934,6 +1121,25 @@ class RecvTest < UMBaseTest
|
|
|
934
1121
|
ensure
|
|
935
1122
|
t&.kill
|
|
936
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
|
|
937
1143
|
end
|
|
938
1144
|
|
|
939
1145
|
class RecvEachTest < UMBaseTest
|
|
@@ -1119,6 +1325,25 @@ class SynchronizeTest < UMBaseTest
|
|
|
1119
1325
|
assert_equal [11, 12, 13, 21, 22, 23], buf
|
|
1120
1326
|
assert_equal 0, machine.pending_count
|
|
1121
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
|
|
1122
1347
|
end
|
|
1123
1348
|
|
|
1124
1349
|
class QueueTest < UMBaseTest
|
|
@@ -1335,12 +1560,67 @@ class PipeTest < UMBaseTest
|
|
|
1335
1560
|
end
|
|
1336
1561
|
end
|
|
1337
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
|
+
|
|
1338
1618
|
class PollTest < UMBaseTest
|
|
1339
1619
|
def test_poll
|
|
1340
1620
|
rfd, wfd = UM.pipe
|
|
1341
1621
|
|
|
1342
1622
|
events = []
|
|
1343
|
-
|
|
1623
|
+
machine.spin do
|
|
1344
1624
|
events << :pre
|
|
1345
1625
|
events << machine.poll(rfd, UM::POLLIN)
|
|
1346
1626
|
events << :post
|
|
@@ -1366,38 +1646,81 @@ class PollTest < UMBaseTest
|
|
|
1366
1646
|
end
|
|
1367
1647
|
end
|
|
1368
1648
|
|
|
1369
|
-
class
|
|
1370
|
-
def
|
|
1371
|
-
skip if UM.kernel_version < 607
|
|
1372
|
-
|
|
1649
|
+
class WaitidTest < UMBaseTest
|
|
1650
|
+
def test_waitid
|
|
1373
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
|
|
1374
1659
|
|
|
1375
|
-
|
|
1376
|
-
|
|
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
|
|
1377
1689
|
m = UM.new
|
|
1378
1690
|
m.write(wfd, msg)
|
|
1379
1691
|
m.close(wfd)
|
|
1380
1692
|
exit 42
|
|
1381
1693
|
end
|
|
1382
1694
|
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
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
|
|
1386
1701
|
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
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
|
|
1391
1715
|
ensure
|
|
1392
|
-
Process.wait(
|
|
1716
|
+
Process.wait(child_pid) rescue nil
|
|
1393
1717
|
end
|
|
1394
1718
|
|
|
1395
|
-
def
|
|
1396
|
-
skip if
|
|
1719
|
+
def test_waitid_status
|
|
1720
|
+
skip if !machine.respond_to?(:waitid_status)
|
|
1397
1721
|
|
|
1398
1722
|
msg = 'hello from child'
|
|
1399
|
-
|
|
1400
|
-
rfd, wfd = UM.pipe
|
|
1723
|
+
_rfd, wfd = UM.pipe
|
|
1401
1724
|
pid = fork do
|
|
1402
1725
|
m = UM.new
|
|
1403
1726
|
m.write(wfd, msg)
|
|
@@ -1405,23 +1728,76 @@ class WaitTest < UMBaseTest
|
|
|
1405
1728
|
exit 42
|
|
1406
1729
|
end
|
|
1407
1730
|
|
|
1408
|
-
|
|
1409
|
-
assert_kind_of
|
|
1410
|
-
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
|
|
1411
1738
|
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
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
|
|
1416
1746
|
|
|
1747
|
+
def test_waitid_status_invalid_idtype
|
|
1748
|
+
skip if !machine.respond_to?(:waitid_status)
|
|
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
|
|
1417
1779
|
ensure
|
|
1418
|
-
Process.wait(pid) rescue
|
|
1780
|
+
Process.wait(pid) rescue nil
|
|
1419
1781
|
end
|
|
1420
1782
|
|
|
1421
|
-
def
|
|
1422
|
-
skip if
|
|
1783
|
+
def test_waitid_status_P_PGID
|
|
1784
|
+
skip if !machine.respond_to?(:waitid_status)
|
|
1423
1785
|
|
|
1424
|
-
|
|
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
|
|
1794
|
+
|
|
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
|
|
1425
1801
|
end
|
|
1426
1802
|
end
|
|
1427
1803
|
|
|
@@ -1509,7 +1885,7 @@ class ForkTest < UMBaseTest
|
|
|
1509
1885
|
assert_equal 3, ret
|
|
1510
1886
|
assert_equal 'foo', buf
|
|
1511
1887
|
ensure
|
|
1512
|
-
Process.wait(child_pid) rescue
|
|
1888
|
+
Process.wait(child_pid) rescue nil
|
|
1513
1889
|
end
|
|
1514
1890
|
end
|
|
1515
1891
|
|
|
@@ -1573,3 +1949,20 @@ class SendBundleTest < UMBaseTest
|
|
|
1573
1949
|
assert_equal strs.map(&:to_s).join, buf
|
|
1574
1950
|
end
|
|
1575
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
|