uringmachine 0.26.0 → 0.28.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
@@ -663,14 +747,15 @@ VALUE UM_send(VALUE self, VALUE fd, VALUE buffer, VALUE len, VALUE flags) {
663
747
  return um_send(machine, NUM2INT(fd), buffer, NUM2INT(len), NUM2INT(flags));
664
748
  }
665
749
 
666
- #ifdef HAVE_IO_URING_SEND_VECTORIZED
667
-
668
750
  /* call-seq:
669
751
  * machine.sendv(fd, *buffers) -> bytes_sent
670
752
  *
671
753
  * Sends data on the given socket from the given buffers. This method is only
672
754
  * available on Linux kernel >= 6.17. This method is guaranteed to send
673
755
  *
756
+ * - https://www.man7.org/linux/man-pages/man2/send.2.html
757
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_send.3.html
758
+ *
674
759
  * @overload sendv(fd, *buffers)
675
760
  * @param fd [Integer] file descriptor
676
761
  * @param *buffers [Array<String, IO::Buffer>] buffers
@@ -683,10 +768,13 @@ VALUE UM_sendv(int argc, VALUE *argv, VALUE self) {
683
768
  int fd = NUM2INT(argv[0]);
684
769
  if (argc < 2) return INT2NUM(0);
685
770
 
771
+ #ifdef HAVE_IO_URING_SEND_VECTORIZED
686
772
  return um_sendv(machine, fd, argc - 1, argv + 1);
773
+ #else
774
+ return um_writev(machine, fd, argc - 1, argv + 1);
775
+ #endif
687
776
  }
688
777
 
689
- #endif
690
778
 
691
779
  /* call-seq:
692
780
  * machine.send_bundle(fd, bgid, *buffers) -> bytes_sent
@@ -695,6 +783,9 @@ VALUE UM_sendv(int argc, VALUE *argv, VALUE self) {
695
783
  * buffer group. The buffer group should have been previously registered using
696
784
  * `#setup_buffer_ring`.
697
785
  *
786
+ * - https://www.man7.org/linux/man-pages/man2/send.2.html
787
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_send.3.html
788
+ *
698
789
  * @overload send_bundle(fd, bgid, *buffers)
699
790
  * @param fd [Integer] file descriptor
700
791
  * @param bgid [Integer] buffer group id
@@ -722,6 +813,9 @@ VALUE UM_send_bundle(int argc, VALUE *argv, VALUE self) {
722
813
  *
723
814
  * Receives data from the given socket.
724
815
  *
816
+ * - https://www.man7.org/linux/man-pages/man2/recv.2.html
817
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_recv.3.html
818
+ *
725
819
  * @param fd [Integer] file descriptor
726
820
  * @param buffer [String, IO::Buffer] buffer
727
821
  * @param maxlen [Integer] maximum number of bytes to receive
@@ -740,6 +834,9 @@ VALUE UM_recv(VALUE self, VALUE fd, VALUE buffer, VALUE maxlen, VALUE flags) {
740
834
  * given buffer group id. The buffer group should have been previously setup
741
835
  * using `#setup_buffer_ring`.
742
836
  *
837
+ * - https://www.man7.org/linux/man-pages/man2/recv.2.html
838
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_recv.3.html
839
+ *
743
840
  * @param fd [Integer] file descriptor
744
841
  * @param bgid [Integer] buffer group id
745
842
  * @param flags [Integer] flags mask
@@ -755,6 +852,9 @@ VALUE UM_recv_each(VALUE self, VALUE fd, VALUE bgid, VALUE flags) {
755
852
  *
756
853
  * Binds the given socket to the given host and port.
757
854
  *
855
+ * - https://www.man7.org/linux/man-pages/man2/bind.2.html
856
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_bind.3.html
857
+ *
758
858
  * @param fd [Integer] file descriptor
759
859
  * @param host [String] hostname or IP address
760
860
  * @param port [Integer] port number
@@ -783,6 +883,9 @@ VALUE UM_bind(VALUE self, VALUE fd, VALUE host, VALUE port) {
783
883
  *
784
884
  * Starts listening for incoming connections on the given socket.
785
885
  *
886
+ * - https://www.man7.org/linux/man-pages/man2/listen.2.html
887
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_listen.3.html
888
+ *
786
889
  * @param fd [Integer] file descriptor
787
890
  * @param backlog [String] pending connection queue length
788
891
  * @return [0] success
@@ -815,6 +918,9 @@ static inline int numeric_value(VALUE value) {
815
918
  *
816
919
  * Returns the value of a socket option.
817
920
  *
921
+ * - https://www.man7.org/linux/man-pages//man2/getsockopt.2.html
922
+ * - https://www.man7.org/linux/man-pages//man3/io_uring_prep_cmd.3.html
923
+ *
818
924
  * @param fd [Integer] file descriptor
819
925
  * @param level [Integer] level
820
926
  * @param opt [Integer] level
@@ -826,10 +932,13 @@ VALUE UM_getsockopt(VALUE self, VALUE fd, VALUE level, VALUE opt) {
826
932
  }
827
933
 
828
934
  /* call-seq:
829
- * machine.getsockopt(fd, level, opt, value) -> 0
935
+ * machine.setsockopt(fd, level, opt, value) -> 0
830
936
  *
831
937
  * Sets the value of a socket option.
832
938
  *
939
+ * - https://www.man7.org/linux/man-pages//man2/setsockopt.2.html
940
+ * - https://www.man7.org/linux/man-pages//man3/io_uring_prep_cmd.3.html
941
+ *
833
942
  * @param fd [Integer] file descriptor
834
943
  * @param level [Integer] level
835
944
  * @param opt [Integer] level
@@ -847,6 +956,9 @@ VALUE UM_setsockopt(VALUE self, VALUE fd, VALUE level, VALUE opt, VALUE value) {
847
956
  * Synchronizes access to the given mutex. The mutex is locked, the given block
848
957
  * is executed and finally the mutex is unlocked.
849
958
  *
959
+ * - https://www.man7.org/linux/man-pages/man2/futex.2.html
960
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_futex_wait.3.html
961
+ *
850
962
  * @param mutex [UM::Mutex] mutex
851
963
  * @return [any] block return value
852
964
  */
@@ -861,6 +973,9 @@ VALUE UM_mutex_synchronize(VALUE self, VALUE mutex) {
861
973
  *
862
974
  * Pushes a value to the tail of the given queue.
863
975
  *
976
+ * - https://www.man7.org/linux/man-pages/man2/futex.2.html
977
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_futex_wait.3.html
978
+ *
864
979
  * @param queue [UM::Queue] queue
865
980
  * @param value [any] value
866
981
  * @return [UM::Queue] queue
@@ -876,6 +991,9 @@ VALUE UM_queue_push(VALUE self, VALUE queue, VALUE value) {
876
991
  *
877
992
  * removes a value from the tail of the given queue.
878
993
  *
994
+ * - https://www.man7.org/linux/man-pages/man2/futex.2.html
995
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_futex_wait.3.html
996
+ *
879
997
  * @param queue [UM::Queue] queue
880
998
  * @return [any] value
881
999
  */
@@ -890,6 +1008,9 @@ VALUE UM_queue_pop(VALUE self, VALUE queue) {
890
1008
  *
891
1009
  * Pushes a value to the head of the given queue.
892
1010
  *
1011
+ * - https://www.man7.org/linux/man-pages/man2/futex.2.html
1012
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_futex_wait.3.html
1013
+ *
893
1014
  * @param queue [UM::Queue] queue
894
1015
  * @param value [any] value
895
1016
  * @return [UM::Queue] queue
@@ -905,6 +1026,9 @@ VALUE UM_queue_unshift(VALUE self, VALUE queue, VALUE value) {
905
1026
  *
906
1027
  * removes a value from the head of the given queue.
907
1028
  *
1029
+ * - https://www.man7.org/linux/man-pages/man2/futex.2.html
1030
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_futex_wait.3.html
1031
+ *
908
1032
  * @param queue [UM::Queue] queue
909
1033
  * @return [any] value
910
1034
  */
@@ -933,6 +1057,9 @@ VALUE UM_open_complete(VALUE arg) {
933
1057
  * file descriptor is passed to the block, and the file is automatically closed
934
1058
  * when the block returns.
935
1059
  *
1060
+ * - https://www.man7.org/linux/man-pages/man2/open.2.html
1061
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_openat.3.html
1062
+ *
936
1063
  * @param pathname [String] file path
937
1064
  * @param flags [Integer] flags mask
938
1065
  * @return [Integer] fd
@@ -955,6 +1082,9 @@ VALUE UM_open(VALUE self, VALUE pathname, VALUE flags) {
955
1082
  * Waits for readiness of the given file descriptor according to the given event
956
1083
  * mask.
957
1084
  *
1085
+ * - https://www.man7.org/linux/man-pages/man2/poll.2.html
1086
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_poll_add.3.html
1087
+ *
958
1088
  * @param fd [Integer] file descriptor
959
1089
  * @param mask [Integer] events mask
960
1090
  * @return [Integer] fd
@@ -970,6 +1100,9 @@ VALUE UM_poll(VALUE self, VALUE fd, VALUE mask) {
970
1100
  * Waits for readyness of at least one fd for read, write or exception condition
971
1101
  * from the given fds. This method provides a similar interface to `IO#select`.
972
1102
  *
1103
+ * - https://www.man7.org/linux/man-pages/man2/select.2.html
1104
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_poll_add.3.html
1105
+ *
973
1106
  * @param read_fds [Array<Integer>] file descriptors for reading
974
1107
  * @param write_fds [Array<Integer>] file descriptors for writing
975
1108
  * @param except_fds [Array<Integer>] file descriptors for exception
@@ -986,6 +1119,9 @@ VALUE UM_select(VALUE self, VALUE read_fds, VALUE write_fds, VALUE except_fds) {
986
1119
  * Waits for a process to change state. The process to wait for can be specified
987
1120
  * as a pid or as a pidfd, according to the given `idtype` and `id`.
988
1121
  *
1122
+ * - https://www.man7.org/linux/man-pages/man2/waitid.2.html
1123
+ * - https://www.man7.org/linux/man-pages/man3/io_uring_prep_waitid.3.html
1124
+ *
989
1125
  * @param idtype [Integer] id type
990
1126
  * @param id [Integer] id
991
1127
  * @param options [Integer] options
@@ -1077,6 +1213,8 @@ VALUE UM_ssl_write(VALUE self, VALUE ssl, VALUE buf, VALUE len) {
1077
1213
  *
1078
1214
  * Creates a pipe, returning the file descriptors for the read and write ends.
1079
1215
  *
1216
+ * - https://www.man7.org/linux/man-pages/man2/pipe.2.html
1217
+ *
1080
1218
  * @return [Array<Integer>] array containing the read and write file descriptors
1081
1219
  */
1082
1220
  VALUE UM_pipe(VALUE self) {
@@ -1095,6 +1233,8 @@ VALUE UM_pipe(VALUE self) {
1095
1233
  *
1096
1234
  * Creates a pair of connected sockets, returning the two file descriptors.
1097
1235
  *
1236
+ * - https://www.man7.org/linux/man-pages/man2/socketpair.2.html
1237
+ *
1098
1238
  * @param domain [Integer] domain
1099
1239
  * @param type [Integer] type
1100
1240
  * @param protocol [Integer] protocol
@@ -1117,6 +1257,8 @@ VALUE UM_socketpair(VALUE self, VALUE domain, VALUE type, VALUE protocol) {
1117
1257
  * Creates a file descriptor representing the given process pid. The file
1118
1258
  * descriptor can then be used with methods such as `#waitid` or `.pidfd_open`.
1119
1259
  *
1260
+ * - https://www.man7.org/linux/man-pages/man2/pidfd_open.2.html
1261
+ *
1120
1262
  * @param pid [Integer] process pid
1121
1263
  * @return [Integer] file descriptor
1122
1264
  */
@@ -1135,6 +1277,8 @@ VALUE UM_pidfd_open(VALUE self, VALUE pid) {
1135
1277
  *
1136
1278
  * Sends a signal to a pidfd.
1137
1279
  *
1280
+ * - https://www.man7.org/linux/man-pages/man2/pidfd_send_signal.2.html
1281
+ *
1138
1282
  * @param fd [Integer] pidfd
1139
1283
  * @param sig [Integer] signal
1140
1284
  * @return [Integer] pidfd
@@ -1151,38 +1295,6 @@ VALUE UM_pidfd_send_signal(VALUE self, VALUE fd, VALUE sig) {
1151
1295
  return fd;
1152
1296
  }
1153
1297
 
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
1298
  /* call-seq:
1187
1299
  * UringMachine.kernel_version -> version
1188
1300
  *
@@ -1212,6 +1324,8 @@ VALUE UM_debug(VALUE self, VALUE str) {
1212
1324
  *
1213
1325
  * Creates an inotify file descriptor.
1214
1326
  *
1327
+ * - https://www.man7.org/linux/man-pages/man2/inotify_init.2.html
1328
+ *
1215
1329
  * @return [Integer] file descriptor
1216
1330
  */
1217
1331
  VALUE UM_inotify_init(VALUE self) {
@@ -1228,6 +1342,8 @@ VALUE UM_inotify_init(VALUE self) {
1228
1342
  *
1229
1343
  * Adds a watch on the given inotify file descriptor.
1230
1344
  *
1345
+ * - https://www.man7.org/linux/man-pages/man2/inotify_add_watch.2.html
1346
+ *
1231
1347
  * @param fd [Integer] inotify file descriptor
1232
1348
  * @param path [String] file/directory path
1233
1349
  * @param mask [Integer] inotify event mask
@@ -1269,6 +1385,8 @@ static inline VALUE inotify_get_events(char *buf, size_t len) {
1269
1385
  * descriptor. Each event is returned as a hash containing the watch descriptor,
1270
1386
  * the file name, and the event mask.
1271
1387
  *
1388
+ * - https://www.man7.org/linux/man-pages/man7/inotify.7.html
1389
+ *
1272
1390
  * @param fd [Integer] inotify file descriptor
1273
1391
  * @return [Array<Hash>] array of one or more events
1274
1392
  */
@@ -1281,12 +1399,46 @@ VALUE UM_inotify_get_events(VALUE self, VALUE fd) {
1281
1399
  return inotify_get_events(buf, ret);
1282
1400
  }
1283
1401
 
1402
+ /* call-seq:
1403
+ * UringMachine.pr_set_child_subreaper(vaule) -> value
1404
+ *
1405
+ * Sets/unsets the "child subreaper" attribute of the calling process.
1406
+ *
1407
+ * - https://man7.org/linux/man-pages/man2/PR_SET_CHILD_SUBREAPER.2const.html
1408
+ *
1409
+ * @param value [bool] set/unset value
1410
+ * @return [bool] set/unset value
1411
+ */
1412
+ VALUE UM_pr_set_child_subreaper(VALUE self, VALUE set) {
1413
+ int ret = prctl(PR_SET_CHILD_SUBREAPER, RTEST(set) ? 1 : 0);
1414
+ if (ret) {
1415
+ int e = errno;
1416
+ rb_syserr_fail(e, strerror(e));
1417
+ }
1418
+
1419
+ return set;
1420
+ }
1421
+
1284
1422
  void Init_UM(void) {
1285
1423
  rb_ext_ractor_safe(true);
1286
1424
 
1287
1425
  cUM = rb_define_class("UringMachine", rb_cObject);
1288
1426
  rb_define_alloc_func(cUM, UM_allocate);
1289
1427
 
1428
+ rb_define_singleton_method(cUM, "pipe", UM_pipe, 0);
1429
+ rb_define_singleton_method(cUM, "socketpair", UM_socketpair, 3);
1430
+ rb_define_singleton_method(cUM, "pidfd_open", UM_pidfd_open, 1);
1431
+ rb_define_singleton_method(cUM, "pidfd_send_signal", UM_pidfd_send_signal, 2);
1432
+
1433
+ rb_define_singleton_method(cUM, "kernel_version", UM_kernel_version, 0);
1434
+ rb_define_singleton_method(cUM, "debug", UM_debug, 1);
1435
+
1436
+ rb_define_singleton_method(cUM, "inotify_init", UM_inotify_init, 0);
1437
+ rb_define_singleton_method(cUM, "inotify_add_watch", UM_inotify_add_watch, 3);
1438
+
1439
+ rb_define_singleton_method(cUM, "pr_set_child_subreaper", UM_pr_set_child_subreaper, 1);
1440
+
1441
+
1290
1442
  rb_define_method(cUM, "initialize", UM_initialize, -1);
1291
1443
  rb_define_method(cUM, "size", UM_size, 0);
1292
1444
  rb_define_method(cUM, "mark", UM_mark_m, 1);
@@ -1302,19 +1454,6 @@ void Init_UM(void) {
1302
1454
 
1303
1455
  rb_define_method(cUM, "setup_buffer_ring", UM_setup_buffer_ring, 2);
1304
1456
 
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
1457
  rb_define_method(cUM, "schedule", UM_schedule, 2);
1319
1458
  rb_define_method(cUM, "snooze", UM_snooze, 0);
1320
1459
  rb_define_method(cUM, "timeout", UM_timeout, 2);
@@ -1354,16 +1493,15 @@ void Init_UM(void) {
1354
1493
  rb_define_method(cUM, "recv", UM_recv, 4);
1355
1494
  rb_define_method(cUM, "recv_each", UM_recv_each, 3);
1356
1495
  rb_define_method(cUM, "send", UM_send, 4);
1357
-
1358
- #ifdef HAVE_IO_URING_SEND_VECTORIZED
1359
1496
  rb_define_method(cUM, "sendv", UM_sendv, -1);
1360
- #endif
1361
1497
 
1362
1498
  rb_define_method(cUM, "send_bundle", UM_send_bundle, -1);
1363
1499
  rb_define_method(cUM, "setsockopt", UM_setsockopt, 4);
1364
1500
  rb_define_method(cUM, "socket", UM_socket, 4);
1365
1501
  rb_define_method(cUM, "shutdown", UM_shutdown, 2);
1366
1502
  rb_define_method(cUM, "shutdown_async", UM_shutdown_async, 2);
1503
+ rb_define_method(cUM, "send_fd", UM_send_fd, 2);
1504
+ rb_define_method(cUM, "recv_fd", UM_recv_fd, 1);
1367
1505
 
1368
1506
  rb_define_method(cUM, "prep_timeout", UM_prep_timeout, 1);
1369
1507