uringmachine 0.25.0 → 0.27.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.
data/ext/um/um_class.c CHANGED
@@ -5,6 +5,8 @@
5
5
  #include <unistd.h>
6
6
  #include <sys/socket.h>
7
7
  #include <sys/inotify.h>
8
+ #include <linux/prctl.h>
9
+ #include <sys/prctl.h>
8
10
 
9
11
  VALUE cUM;
10
12
  VALUE eUMError;
@@ -328,6 +330,8 @@ VALUE UM_schedule(VALUE self, VALUE fiber, VALUE value) {
328
330
  /* Runs the given block, interrupting its execution if its runtime exceeds the
329
331
  * given timeout interval (in seconds).
330
332
  *
333
+ * - https://www.man7.org/linux/man-pages//man3/io_uring_prep_timeoute.3.html
334
+ *
331
335
  * @param interval [Number] timeout interval in seconds
332
336
  * @param exception_class [any] timeout exception class
333
337
  * @return [any] block's return value
@@ -340,6 +344,8 @@ VALUE UM_timeout(VALUE self, VALUE interval, VALUE exception_class) {
340
344
  /* Puts the current fiber to sleep for the given time duration (in seconds),
341
345
  * yielding control to the next fiber in the runqueue.
342
346
  *
347
+ * - https://www.man7.org/linux/man-pages//man3/io_uring_prep_timeoute.3.html
348
+ *
343
349
  * @param duration [Number] sleep duration in seconds
344
350
  * @return [void]
345
351
  */
@@ -349,6 +355,8 @@ VALUE UM_sleep(VALUE self, VALUE duration) {
349
355
  }
350
356
 
351
357
  /* Runs the given block at regular time intervals in an infinite loop.
358
+ *
359
+ * - https://www.man7.org/linux/man-pages//man3/io_uring_prep_timeoute.3.html
352
360
  *
353
361
  * @param interval [Number] time interval (in seconds) between consecutive invocations
354
362
  * @return [void]
@@ -359,21 +367,23 @@ VALUE UM_periodically(VALUE self, VALUE interval) {
359
367
  }
360
368
 
361
369
  /* call-seq:
362
- * machine.read(fd, buffer, maxlen[, buffer_offset[, file_offset]]) -> bytes_read
370
+ * machine.read(fd, buffer, maxlen, buffer_offset = nil, file_offset = nil) -> bytes_read
363
371
  *
364
372
  * Reads up to `maxlen` bytes from the given `fd` into the given buffer. The
365
373
  * optional `buffer_offset` parameter determines the position in the buffer into
366
374
  * which the data will be read. A negative `buffer_offset` denotes a position
367
375
  * relative to the end of the buffer, e.g. a value of `-1` means the data will
368
376
  * be appended to the buffer.
377
+ *
378
+ * - https://www.man7.org/linux/man-pages/man2/read.2.html
379
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_read.3.html
369
380
  *
370
- * @overload read(fd, buffer, maxlen, buffer_offset: nil, file_offset: nil)
371
- * @param fd [Integer] file descriptor
372
- * @param buffer [String, IO::Buffer] buffer
373
- * @param maxlen [Integer] maximum number of bytes to read
374
- * @param buffer_offset [Integer] optional buffer offset to read into
375
- * @param file_offset [Integer] optional file offset to read from
376
- * @return [Integer] number of bytes read
381
+ * @param fd [Integer] file descriptor
382
+ * @param buffer [String, IO::Buffer] buffer
383
+ * @param maxlen [Integer] maximum number of bytes to read
384
+ * @param buffer_offset [Integer] optional buffer offset to read into
385
+ * @param file_offset [Integer] optional file offset to read from
386
+ * @return [Integer] number of bytes read
377
387
  */
378
388
  VALUE UM_read(int argc, VALUE *argv, VALUE self) {
379
389
  struct um *machine = um_get_machine(self);
@@ -398,6 +408,8 @@ VALUE UM_read(int argc, VALUE *argv, VALUE self) {
398
408
  * buffer group should have been previously setup using `#setup_buffer_ring`.
399
409
  * Read data is yielded in an infinite loop to the given block.
400
410
  *
411
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_read_multishot.3.html
412
+ *
401
413
  * @param fd [Integer] file descriptor
402
414
  * @param bgid [Integer] buffer group id
403
415
  * @return [void]
@@ -408,17 +420,19 @@ VALUE UM_read_each(VALUE self, VALUE fd, VALUE bgid) {
408
420
  }
409
421
 
410
422
  /* call-seq:
411
- * machine.write(fd, buffer[, len[, file_offset]]) -> bytes_written
423
+ * machine.write(fd, buffer, len = nil, file_offset = nil) -> bytes_written
412
424
  *
413
425
  * Writes up to `len` bytes from the given buffer to the given `fd`. If `len`,
414
426
  * is not given, the entire buffer length is used.
415
427
  *
416
- * @overload write(fd, buffer, len: nil, file_offset: nil)
417
- * @param fd [Integer] file descriptor
418
- * @param buffer [String, IO::Buffer] buffer
419
- * @param len [Integer] maximum number of bytes to write
420
- * @param file_offset [Integer] optional file offset to write to
421
- * @return [Integer] number of bytes written
428
+ * - https://man7.org/linux/man-pages/man2/write.2.html
429
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_write.3.html
430
+ *
431
+ * @param fd [Integer] file descriptor
432
+ * @param buffer [String, IO::Buffer] buffer
433
+ * @param len [Integer] maximum number of bytes to write
434
+ * @param file_offset [Integer] optional file offset to write to
435
+ * @return [Integer] number of bytes written
422
436
  */
423
437
  VALUE UM_write(int argc, VALUE *argv, VALUE self) {
424
438
  struct um *machine = um_get_machine(self);
@@ -435,7 +449,7 @@ VALUE UM_write(int argc, VALUE *argv, VALUE self) {
435
449
  }
436
450
 
437
451
  /* call-seq:
438
- * machine.writev(fd, *buffers[, file_offset]) -> bytes_written
452
+ * machine.writev(fd, *buffers, file_offset = nil) -> bytes_written
439
453
  *
440
454
  * Writes from the given buffers into the given fd. This method does not
441
455
  * guarantee that all data will be written. The application code should check
@@ -443,11 +457,13 @@ VALUE UM_write(int argc, VALUE *argv, VALUE self) {
443
457
  * repeat the operation after adjusting the buffers accordingly. See also
444
458
  * `#sendv`.
445
459
  *
446
- * @overload writev(fd, *buffers, file_offset: nil)
447
- * @param fd [Integer] file descriptor
448
- * @param *buffers [Array<String, IO::Buffer>] data buffers
449
- * @param file_offset [Integer] optional file offset to write to
450
- * @return [Integer] number of bytes written
460
+ * - https://man7.org/linux/man-pages/man2/writev.2.html
461
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_writev.3.html
462
+ *
463
+ * @param fd [Integer] file descriptor
464
+ * @param *buffers [Array<String, IO::Buffer>] data buffers
465
+ * @param file_offset [Integer] optional file offset to write to
466
+ * @return [Integer] number of bytes written
451
467
  */
452
468
  VALUE UM_writev(int argc, VALUE *argv, VALUE self) {
453
469
  struct um *machine = um_get_machine(self);
@@ -460,7 +476,7 @@ VALUE UM_writev(int argc, VALUE *argv, VALUE self) {
460
476
  }
461
477
 
462
478
  /* call-seq:
463
- * machine.write_async(fd, buffer[, len[, file_offset]]) -> buffer
479
+ * machine.write_async(fd, buffer, len = nil, file_offset = nil) -> buffer
464
480
  *
465
481
  * Writes up to `len` bytes from the given buffer to the given `fd`. If `len`,
466
482
  * is not given, the entire buffer length is used. This method submits the
@@ -468,12 +484,14 @@ VALUE UM_writev(int argc, VALUE *argv, VALUE self) {
468
484
  * improve performance in situations where the application does not care about
469
485
  * whether the I/O operation succeeds or not.
470
486
  *
471
- * @overload write_async(fd, buffer, len: nil, file_offset: nil)
472
- * @param fd [Integer] file descriptor
473
- * @param buffer [String, IO::Buffer] buffer
474
- * @param len [Integer] maximum number of bytes to write
475
- * @param file_offset [Integer] optional file offset to write to
476
- * @return [String, IO::Buffer] buffer
487
+ * - https://man7.org/linux/man-pages/man2/write.2.html
488
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_write.3.html
489
+ *
490
+ * @param fd [Integer] file descriptor
491
+ * @param buffer [String, IO::Buffer] buffer
492
+ * @param len [Integer] maximum number of bytes to write
493
+ * @param file_offset [Integer] optional file offset to write to
494
+ * @return [String, IO::Buffer] buffer
477
495
  */
478
496
  VALUE UM_write_async(int argc, VALUE *argv, VALUE self) {
479
497
  struct um *machine = um_get_machine(self);
@@ -496,6 +514,9 @@ VALUE UM_write_async(int argc, VALUE *argv, VALUE self) {
496
514
  *
497
515
  * Returns information about a file.
498
516
  *
517
+ * - https://www.man7.org/linux/man-pages/man2/statx.2.html
518
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_statx.3.html
519
+ *
499
520
  * @param dirfd [Integer] file or directory descriptor
500
521
  * @param path [String, nil] file path
501
522
  * @param flags [Integer] flags
@@ -512,6 +533,9 @@ VALUE UM_statx(VALUE self, VALUE dirfd, VALUE path, VALUE flags, VALUE mask) {
512
533
  *
513
534
  * Closes the given file descriptor.
514
535
  *
536
+ * - https://www.man7.org/linux/man-pages/man2/close.2.html
537
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_close.3.html
538
+ *
515
539
  * @param fd [Integer] file descriptor
516
540
  * @return [0] success
517
541
  */
@@ -527,6 +551,9 @@ VALUE UM_close(VALUE self, VALUE fd) {
527
551
  * not wait for it to complete. This method may be used to improve performance
528
552
  * in cases where the application des not care whether it succeeds or not.
529
553
  *
554
+ * - https://www.man7.org/linux/man-pages/man2/close.2.html
555
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_close.3.html
556
+ *
530
557
  * @param fd [Integer] file descriptor
531
558
  * @return [Integer] file descriptor
532
559
  */
@@ -540,6 +567,9 @@ VALUE UM_close_async(VALUE self, VALUE fd) {
540
567
  *
541
568
  * Accepts an incoming TCP connection.
542
569
  *
570
+ * - https://www.man7.org/linux/man-pages/man2/accept4.2.html
571
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_accept.3.html
572
+ *
543
573
  * @param server_fd [Integer] listening socket file descriptor
544
574
  * @return [Integer] connection file descriptor
545
575
  */
@@ -554,6 +584,9 @@ VALUE UM_accept(VALUE self, VALUE server_fd) {
554
584
  * Repeatedly accepts incoming TCP connections in a loop, yielding the
555
585
  * connection file descriptors to the given block.
556
586
  *
587
+ * - https://www.man7.org/linux/man-pages/man2/accept4.2.html
588
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_accept.3.html
589
+ *
557
590
  * @param server_fd [Integer] listening socket file descriptor
558
591
  * @return [void]
559
592
  */
@@ -563,11 +596,14 @@ VALUE UM_accept_each(VALUE self, VALUE server_fd) {
563
596
  }
564
597
 
565
598
  /* call-seq:
566
- * machine.accept_each(server_fd, queue)
599
+ * machine.accept_into_queue(server_fd, queue)
567
600
  *
568
601
  * Repeatedly accepts incoming TCP connections in a loop, pushing the connection
569
602
  * file descriptors into the given queue.
570
603
  *
604
+ * - https://www.man7.org/linux/man-pages/man2/accept4.2.html
605
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_accept.3.html
606
+ *
571
607
  * @param server_fd [Integer] listening socket file descriptor
572
608
  * @param queue [UM::Queue] connection queue
573
609
  * @return [void]
@@ -582,6 +618,9 @@ VALUE UM_accept_into_queue(VALUE self, VALUE server_fd, VALUE queue) {
582
618
  *
583
619
  * Creates a socket.
584
620
  *
621
+ * - https://www.man7.org/linux/man-pages/man2/socket.2.html
622
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_socket.3.html
623
+ *
585
624
  * @param domain [Integer] socket domain
586
625
  * @param type [Integer] socket type
587
626
  * @param protocol [Integer] socket protocol
@@ -598,6 +637,9 @@ VALUE UM_socket(VALUE self, VALUE domain, VALUE type, VALUE protocol, VALUE flag
598
637
  *
599
638
  * Shuts down a socket for sending and/or receiving.
600
639
  *
640
+ * - https://man7.org/linux/man-pages/man2/shutdown.2.html
641
+ * - https://man7.org/linux/man-pages/man3/io_uring_prep_shutdown.3.html
642
+ *
601
643
  * @param fd [Integer] file descriptor
602
644
  * @param how [Integer] how the socket should be shutdown
603
645
  * @return [0] success
@@ -614,6 +656,9 @@ VALUE UM_shutdown(VALUE self, VALUE fd, VALUE how) {
614
656
  * improve performance in situations where the application does not care about
615
657
  * whether the operation succeeds or not.
616
658
  *
659
+ * - https://man7.org/linux/man-pages/man2/shutdown.2.html
660
+ * - https://man7.org/linux/man-pages/man3/io_uring_prep_shutdown.3.html
661
+ *
617
662
  * @param fd [Integer] file descriptor
618
663
  * @param how [Integer] how the socket should be shutdown
619
664
  * @return [0] success
@@ -623,11 +668,47 @@ VALUE UM_shutdown_async(VALUE self, VALUE fd, VALUE how) {
623
668
  return um_shutdown_async(machine, NUM2INT(fd), NUM2INT(how));
624
669
  }
625
670
 
671
+ /* call-seq:
672
+ * machine.send_fd(sock_fd, fd) -> fd
673
+ *
674
+ * Sends the given file descriptor over the given socket.
675
+ *
676
+ * - https://www.man7.org/linux/man-pages/man3/sendmsg.3p.html
677
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_sendmsg.3.html
678
+ *
679
+ * @param sock_fd [Integer] socket file descriptor
680
+ * @param fd [Integer] file descriptor to send
681
+ * @return [Integer] file descriptor to send
682
+ */
683
+ VALUE UM_send_fd(VALUE self, VALUE sock_fd, VALUE fd) {
684
+ struct um *machine = um_get_machine(self);
685
+ return um_send_fd(machine, NUM2INT(sock_fd), NUM2INT(fd));
686
+ }
687
+
688
+ /* call-seq:
689
+ * machine.recv_fd(sock_fd) -> fd
690
+ *
691
+ * Receives a file descriptor over the given socket.
692
+ *
693
+ * - https://www.man7.org/linux/man-pages/man3/recvmsg.3p.html
694
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_recvmsg.3.html
695
+ *
696
+ * @param sock_fd [Integer] socket file descriptor
697
+ * @return [Integer] rececived file descriptor
698
+ */
699
+ VALUE UM_recv_fd(VALUE self, VALUE sock_fd) {
700
+ struct um *machine = um_get_machine(self);
701
+ return um_recv_fd(machine, NUM2INT(sock_fd));
702
+ }
703
+
626
704
  /* call-seq:
627
705
  * machine.connect(fd, host, port) -> 0
628
706
  *
629
707
  * Connects the given socket to the given host and port.
630
708
  *
709
+ * - https://www.man7.org/linux/man-pages/man2/connect.2.html
710
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_connect.3.html
711
+ *
631
712
  * @param fd [Integer] file descriptor
632
713
  * @param host [String] hostname or IP address
633
714
  * @param port [Integer] port number
@@ -652,6 +733,9 @@ VALUE UM_connect(VALUE self, VALUE fd, VALUE host, VALUE port) {
652
733
  * the data in the buffer, unless `UM::MSG_WAITALL` is specified in the flags
653
734
  * mask.
654
735
  *
736
+ * - https://www.man7.org/linux/man-pages/man2/send.2.html
737
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_send.3.html
738
+ *
655
739
  * @param fd [Integer] file descriptor
656
740
  * @param buffer [String, IO::Buffer] buffer
657
741
  * @param len [Integer] number of bytes to send
@@ -671,6 +755,9 @@ VALUE UM_send(VALUE self, VALUE fd, VALUE buffer, VALUE len, VALUE flags) {
671
755
  * Sends data on the given socket from the given buffers. This method is only
672
756
  * available on Linux kernel >= 6.17. This method is guaranteed to send
673
757
  *
758
+ * - https://www.man7.org/linux/man-pages/man2/send.2.html
759
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_send.3.html
760
+ *
674
761
  * @overload sendv(fd, *buffers)
675
762
  * @param fd [Integer] file descriptor
676
763
  * @param *buffers [Array<String, IO::Buffer>] buffers
@@ -695,6 +782,9 @@ VALUE UM_sendv(int argc, VALUE *argv, VALUE self) {
695
782
  * buffer group. The buffer group should have been previously registered using
696
783
  * `#setup_buffer_ring`.
697
784
  *
785
+ * - https://www.man7.org/linux/man-pages/man2/send.2.html
786
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_send.3.html
787
+ *
698
788
  * @overload send_bundle(fd, bgid, *buffers)
699
789
  * @param fd [Integer] file descriptor
700
790
  * @param bgid [Integer] buffer group id
@@ -722,6 +812,9 @@ VALUE UM_send_bundle(int argc, VALUE *argv, VALUE self) {
722
812
  *
723
813
  * Receives data from the given socket.
724
814
  *
815
+ * - https://www.man7.org/linux/man-pages/man2/recv.2.html
816
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_recv.3.html
817
+ *
725
818
  * @param fd [Integer] file descriptor
726
819
  * @param buffer [String, IO::Buffer] buffer
727
820
  * @param maxlen [Integer] maximum number of bytes to receive
@@ -740,6 +833,9 @@ VALUE UM_recv(VALUE self, VALUE fd, VALUE buffer, VALUE maxlen, VALUE flags) {
740
833
  * given buffer group id. The buffer group should have been previously setup
741
834
  * using `#setup_buffer_ring`.
742
835
  *
836
+ * - https://www.man7.org/linux/man-pages/man2/recv.2.html
837
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_recv.3.html
838
+ *
743
839
  * @param fd [Integer] file descriptor
744
840
  * @param bgid [Integer] buffer group id
745
841
  * @param flags [Integer] flags mask
@@ -755,6 +851,9 @@ VALUE UM_recv_each(VALUE self, VALUE fd, VALUE bgid, VALUE flags) {
755
851
  *
756
852
  * Binds the given socket to the given host and port.
757
853
  *
854
+ * - https://www.man7.org/linux/man-pages/man2/bind.2.html
855
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_bind.3.html
856
+ *
758
857
  * @param fd [Integer] file descriptor
759
858
  * @param host [String] hostname or IP address
760
859
  * @param port [Integer] port number
@@ -783,6 +882,9 @@ VALUE UM_bind(VALUE self, VALUE fd, VALUE host, VALUE port) {
783
882
  *
784
883
  * Starts listening for incoming connections on the given socket.
785
884
  *
885
+ * - https://www.man7.org/linux/man-pages/man2/listen.2.html
886
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_listen.3.html
887
+ *
786
888
  * @param fd [Integer] file descriptor
787
889
  * @param backlog [String] pending connection queue length
788
890
  * @return [0] success
@@ -815,6 +917,9 @@ static inline int numeric_value(VALUE value) {
815
917
  *
816
918
  * Returns the value of a socket option.
817
919
  *
920
+ * - https://www.man7.org/linux/man-pages//man2/getsockopt.2.html
921
+ * - https://www.man7.org/linux/man-pages//man3/io_uring_prep_cmd.3.html
922
+ *
818
923
  * @param fd [Integer] file descriptor
819
924
  * @param level [Integer] level
820
925
  * @param opt [Integer] level
@@ -826,10 +931,13 @@ VALUE UM_getsockopt(VALUE self, VALUE fd, VALUE level, VALUE opt) {
826
931
  }
827
932
 
828
933
  /* call-seq:
829
- * machine.getsockopt(fd, level, opt, value) -> 0
934
+ * machine.setsockopt(fd, level, opt, value) -> 0
830
935
  *
831
936
  * Sets the value of a socket option.
832
937
  *
938
+ * - https://www.man7.org/linux/man-pages//man2/setsockopt.2.html
939
+ * - https://www.man7.org/linux/man-pages//man3/io_uring_prep_cmd.3.html
940
+ *
833
941
  * @param fd [Integer] file descriptor
834
942
  * @param level [Integer] level
835
943
  * @param opt [Integer] level
@@ -847,6 +955,9 @@ VALUE UM_setsockopt(VALUE self, VALUE fd, VALUE level, VALUE opt, VALUE value) {
847
955
  * Synchronizes access to the given mutex. The mutex is locked, the given block
848
956
  * is executed and finally the mutex is unlocked.
849
957
  *
958
+ * - https://www.man7.org/linux/man-pages/man2/futex.2.html
959
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_futex_wait.3.html
960
+ *
850
961
  * @param mutex [UM::Mutex] mutex
851
962
  * @return [any] block return value
852
963
  */
@@ -861,6 +972,9 @@ VALUE UM_mutex_synchronize(VALUE self, VALUE mutex) {
861
972
  *
862
973
  * Pushes a value to the tail of the given queue.
863
974
  *
975
+ * - https://www.man7.org/linux/man-pages/man2/futex.2.html
976
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_futex_wait.3.html
977
+ *
864
978
  * @param queue [UM::Queue] queue
865
979
  * @param value [any] value
866
980
  * @return [UM::Queue] queue
@@ -876,6 +990,9 @@ VALUE UM_queue_push(VALUE self, VALUE queue, VALUE value) {
876
990
  *
877
991
  * removes a value from the tail of the given queue.
878
992
  *
993
+ * - https://www.man7.org/linux/man-pages/man2/futex.2.html
994
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_futex_wait.3.html
995
+ *
879
996
  * @param queue [UM::Queue] queue
880
997
  * @return [any] value
881
998
  */
@@ -890,6 +1007,9 @@ VALUE UM_queue_pop(VALUE self, VALUE queue) {
890
1007
  *
891
1008
  * Pushes a value to the head of the given queue.
892
1009
  *
1010
+ * - https://www.man7.org/linux/man-pages/man2/futex.2.html
1011
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_futex_wait.3.html
1012
+ *
893
1013
  * @param queue [UM::Queue] queue
894
1014
  * @param value [any] value
895
1015
  * @return [UM::Queue] queue
@@ -905,6 +1025,9 @@ VALUE UM_queue_unshift(VALUE self, VALUE queue, VALUE value) {
905
1025
  *
906
1026
  * removes a value from the head of the given queue.
907
1027
  *
1028
+ * - https://www.man7.org/linux/man-pages/man2/futex.2.html
1029
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_futex_wait.3.html
1030
+ *
908
1031
  * @param queue [UM::Queue] queue
909
1032
  * @return [any] value
910
1033
  */
@@ -933,6 +1056,9 @@ VALUE UM_open_complete(VALUE arg) {
933
1056
  * file descriptor is passed to the block, and the file is automatically closed
934
1057
  * when the block returns.
935
1058
  *
1059
+ * - https://www.man7.org/linux/man-pages/man2/open.2.html
1060
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_openat.3.html
1061
+ *
936
1062
  * @param pathname [String] file path
937
1063
  * @param flags [Integer] flags mask
938
1064
  * @return [Integer] fd
@@ -955,6 +1081,9 @@ VALUE UM_open(VALUE self, VALUE pathname, VALUE flags) {
955
1081
  * Waits for readiness of the given file descriptor according to the given event
956
1082
  * mask.
957
1083
  *
1084
+ * - https://www.man7.org/linux/man-pages/man2/poll.2.html
1085
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_poll_add.3.html
1086
+ *
958
1087
  * @param fd [Integer] file descriptor
959
1088
  * @param mask [Integer] events mask
960
1089
  * @return [Integer] fd
@@ -970,6 +1099,9 @@ VALUE UM_poll(VALUE self, VALUE fd, VALUE mask) {
970
1099
  * Waits for readyness of at least one fd for read, write or exception condition
971
1100
  * from the given fds. This method provides a similar interface to `IO#select`.
972
1101
  *
1102
+ * - https://www.man7.org/linux/man-pages/man2/select.2.html
1103
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_poll_add.3.html
1104
+ *
973
1105
  * @param read_fds [Array<Integer>] file descriptors for reading
974
1106
  * @param write_fds [Array<Integer>] file descriptors for writing
975
1107
  * @param except_fds [Array<Integer>] file descriptors for exception
@@ -986,6 +1118,9 @@ VALUE UM_select(VALUE self, VALUE read_fds, VALUE write_fds, VALUE except_fds) {
986
1118
  * Waits for a process to change state. The process to wait for can be specified
987
1119
  * as a pid or as a pidfd, according to the given `idtype` and `id`.
988
1120
  *
1121
+ * - https://www.man7.org/linux/man-pages/man2/waitid.2.html
1122
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_waitid.3.html
1123
+ *
989
1124
  * @param idtype [Integer] id type
990
1125
  * @param id [Integer] id
991
1126
  * @param options [Integer] options
@@ -1077,6 +1212,8 @@ VALUE UM_ssl_write(VALUE self, VALUE ssl, VALUE buf, VALUE len) {
1077
1212
  *
1078
1213
  * Creates a pipe, returning the file descriptors for the read and write ends.
1079
1214
  *
1215
+ * - https://www.man7.org/linux/man-pages/man2/pipe.2.html
1216
+ *
1080
1217
  * @return [Array<Integer>] array containing the read and write file descriptors
1081
1218
  */
1082
1219
  VALUE UM_pipe(VALUE self) {
@@ -1095,6 +1232,8 @@ VALUE UM_pipe(VALUE self) {
1095
1232
  *
1096
1233
  * Creates a pair of connected sockets, returning the two file descriptors.
1097
1234
  *
1235
+ * - https://www.man7.org/linux/man-pages/man2/socketpair.2.html
1236
+ *
1098
1237
  * @param domain [Integer] domain
1099
1238
  * @param type [Integer] type
1100
1239
  * @param protocol [Integer] protocol
@@ -1117,6 +1256,8 @@ VALUE UM_socketpair(VALUE self, VALUE domain, VALUE type, VALUE protocol) {
1117
1256
  * Creates a file descriptor representing the given process pid. The file
1118
1257
  * descriptor can then be used with methods such as `#waitid` or `.pidfd_open`.
1119
1258
  *
1259
+ * - https://www.man7.org/linux/man-pages/man2/pidfd_open.2.html
1260
+ *
1120
1261
  * @param pid [Integer] process pid
1121
1262
  * @return [Integer] file descriptor
1122
1263
  */
@@ -1135,6 +1276,8 @@ VALUE UM_pidfd_open(VALUE self, VALUE pid) {
1135
1276
  *
1136
1277
  * Sends a signal to a pidfd.
1137
1278
  *
1279
+ * - https://www.man7.org/linux/man-pages/man2/pidfd_send_signal.2.html
1280
+ *
1138
1281
  * @param fd [Integer] pidfd
1139
1282
  * @param sig [Integer] signal
1140
1283
  * @return [Integer] pidfd
@@ -1151,38 +1294,6 @@ VALUE UM_pidfd_send_signal(VALUE self, VALUE fd, VALUE sig) {
1151
1294
  return fd;
1152
1295
  }
1153
1296
 
1154
- /* :nodoc:
1155
- */
1156
- VALUE UM_io_nonblock_p(VALUE self, VALUE io) {
1157
- int fd = rb_io_descriptor(io);
1158
- int oflags = fcntl(fd, F_GETFL);
1159
- if (oflags == -1) return Qnil;
1160
-
1161
- return (oflags & O_NONBLOCK) ? Qtrue : Qfalse;
1162
- }
1163
-
1164
- /* :nodoc:
1165
- */
1166
- VALUE UM_io_set_nonblock(VALUE self, VALUE io, VALUE nonblock) {
1167
- int fd = rb_io_descriptor(io);
1168
- int oflags = fcntl(fd, F_GETFL);
1169
- if (oflags == -1) return Qnil;
1170
-
1171
- if (RTEST(nonblock)) {
1172
- if (!(oflags & O_NONBLOCK)) {
1173
- oflags |= O_NONBLOCK;
1174
- fcntl(fd, F_SETFL, oflags);
1175
- }
1176
- }
1177
- else {
1178
- if (oflags & O_NONBLOCK) {
1179
- oflags &= ~O_NONBLOCK;
1180
- fcntl(fd, F_SETFL, oflags);
1181
- }
1182
- }
1183
- return nonblock;
1184
- }
1185
-
1186
1297
  /* call-seq:
1187
1298
  * UringMachine.kernel_version -> version
1188
1299
  *
@@ -1212,6 +1323,8 @@ VALUE UM_debug(VALUE self, VALUE str) {
1212
1323
  *
1213
1324
  * Creates an inotify file descriptor.
1214
1325
  *
1326
+ * - https://www.man7.org/linux/man-pages/man2/inotify_init.2.html
1327
+ *
1215
1328
  * @return [Integer] file descriptor
1216
1329
  */
1217
1330
  VALUE UM_inotify_init(VALUE self) {
@@ -1228,6 +1341,8 @@ VALUE UM_inotify_init(VALUE self) {
1228
1341
  *
1229
1342
  * Adds a watch on the given inotify file descriptor.
1230
1343
  *
1344
+ * - https://www.man7.org/linux/man-pages/man2/inotify_add_watch.2.html
1345
+ *
1231
1346
  * @param fd [Integer] inotify file descriptor
1232
1347
  * @param path [String] file/directory path
1233
1348
  * @param mask [Integer] inotify event mask
@@ -1269,6 +1384,8 @@ static inline VALUE inotify_get_events(char *buf, size_t len) {
1269
1384
  * descriptor. Each event is returned as a hash containing the watch descriptor,
1270
1385
  * the file name, and the event mask.
1271
1386
  *
1387
+ * - https://www.man7.org/linux/man-pages/man7/inotify.7.html
1388
+ *
1272
1389
  * @param fd [Integer] inotify file descriptor
1273
1390
  * @return [Array<Hash>] array of one or more events
1274
1391
  */
@@ -1281,12 +1398,46 @@ VALUE UM_inotify_get_events(VALUE self, VALUE fd) {
1281
1398
  return inotify_get_events(buf, ret);
1282
1399
  }
1283
1400
 
1401
+ /* call-seq:
1402
+ * UringMachine.pr_set_child_subreaper(vaule) -> value
1403
+ *
1404
+ * Sets/unsets the "child subreaper" attribute of the calling process.
1405
+ *
1406
+ * - https://man7.org/linux/man-pages/man2/PR_SET_CHILD_SUBREAPER.2const.html
1407
+ *
1408
+ * @param value [bool] set/unset value
1409
+ * @return [bool] set/unset value
1410
+ */
1411
+ VALUE UM_pr_set_child_subreaper(VALUE self, VALUE set) {
1412
+ int ret = prctl(PR_SET_CHILD_SUBREAPER, RTEST(set) ? 1 : 0);
1413
+ if (ret) {
1414
+ int e = errno;
1415
+ rb_syserr_fail(e, strerror(e));
1416
+ }
1417
+
1418
+ return set;
1419
+ }
1420
+
1284
1421
  void Init_UM(void) {
1285
1422
  rb_ext_ractor_safe(true);
1286
1423
 
1287
1424
  cUM = rb_define_class("UringMachine", rb_cObject);
1288
1425
  rb_define_alloc_func(cUM, UM_allocate);
1289
1426
 
1427
+ rb_define_singleton_method(cUM, "pipe", UM_pipe, 0);
1428
+ rb_define_singleton_method(cUM, "socketpair", UM_socketpair, 3);
1429
+ rb_define_singleton_method(cUM, "pidfd_open", UM_pidfd_open, 1);
1430
+ rb_define_singleton_method(cUM, "pidfd_send_signal", UM_pidfd_send_signal, 2);
1431
+
1432
+ rb_define_singleton_method(cUM, "kernel_version", UM_kernel_version, 0);
1433
+ rb_define_singleton_method(cUM, "debug", UM_debug, 1);
1434
+
1435
+ rb_define_singleton_method(cUM, "inotify_init", UM_inotify_init, 0);
1436
+ rb_define_singleton_method(cUM, "inotify_add_watch", UM_inotify_add_watch, 3);
1437
+
1438
+ rb_define_singleton_method(cUM, "pr_set_child_subreaper", UM_pr_set_child_subreaper, 1);
1439
+
1440
+
1290
1441
  rb_define_method(cUM, "initialize", UM_initialize, -1);
1291
1442
  rb_define_method(cUM, "size", UM_size, 0);
1292
1443
  rb_define_method(cUM, "mark", UM_mark_m, 1);
@@ -1302,19 +1453,6 @@ void Init_UM(void) {
1302
1453
 
1303
1454
  rb_define_method(cUM, "setup_buffer_ring", UM_setup_buffer_ring, 2);
1304
1455
 
1305
- rb_define_singleton_method(cUM, "pipe", UM_pipe, 0);
1306
- rb_define_singleton_method(cUM, "socketpair", UM_socketpair, 3);
1307
- rb_define_singleton_method(cUM, "pidfd_open", UM_pidfd_open, 1);
1308
- rb_define_singleton_method(cUM, "pidfd_send_signal", UM_pidfd_send_signal, 2);
1309
-
1310
- rb_define_singleton_method(cUM, "io_nonblock?", UM_io_nonblock_p, 1);
1311
- rb_define_singleton_method(cUM, "io_set_nonblock", UM_io_set_nonblock, 2);
1312
- rb_define_singleton_method(cUM, "kernel_version", UM_kernel_version, 0);
1313
- rb_define_singleton_method(cUM, "debug", UM_debug, 1);
1314
-
1315
- rb_define_singleton_method(cUM, "inotify_init", UM_inotify_init, 0);
1316
- rb_define_singleton_method(cUM, "inotify_add_watch", UM_inotify_add_watch, 3);
1317
-
1318
1456
  rb_define_method(cUM, "schedule", UM_schedule, 2);
1319
1457
  rb_define_method(cUM, "snooze", UM_snooze, 0);
1320
1458
  rb_define_method(cUM, "timeout", UM_timeout, 2);
@@ -1364,6 +1502,8 @@ void Init_UM(void) {
1364
1502
  rb_define_method(cUM, "socket", UM_socket, 4);
1365
1503
  rb_define_method(cUM, "shutdown", UM_shutdown, 2);
1366
1504
  rb_define_method(cUM, "shutdown_async", UM_shutdown_async, 2);
1505
+ rb_define_method(cUM, "send_fd", UM_send_fd, 2);
1506
+ rb_define_method(cUM, "recv_fd", UM_recv_fd, 1);
1367
1507
 
1368
1508
  rb_define_method(cUM, "prep_timeout", UM_prep_timeout, 1);
1369
1509