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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/TODO.md +6 -16
- data/ext/um/um.c +80 -0
- data/ext/um/um.h +6 -1
- data/ext/um/um_class.c +219 -81
- data/ext/um/um_op.c +3 -1
- data/ext/um/um_stream.c +11 -0
- data/ext/um/um_stream_class.c +9 -0
- data/grant-2025/tasks.md +3 -16
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +5 -0
- data/test/test_async_op.rb +1 -1
- data/test/test_stream.rb +17 -0
- data/test/test_um.rb +315 -33
- metadata +1 -1
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
|
|
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
|
-
* @
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
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
|
|
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
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
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
|
|
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
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
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
|
|
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
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
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.
|
|
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.
|
|
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
|
|