polyphony 0.81 → 0.83

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.
@@ -102,24 +102,6 @@ static VALUE Backend_initialize(VALUE self) {
102
102
  return self;
103
103
  }
104
104
 
105
- static inline struct io_buffer get_io_buffer(VALUE in) {
106
- if (FIXNUM_P(in)) {
107
- struct raw_buffer *raw = (struct raw_buffer *)(FIX2LONG(in));
108
- return (struct io_buffer){ raw->base, raw->size, 1 };
109
- }
110
- return (struct io_buffer){ RSTRING_PTR(in), RSTRING_LEN(in), 0 };
111
- }
112
-
113
- static inline VALUE coerce_io_string_or_buffer(VALUE buf) {
114
- switch (TYPE(buf)) {
115
- case T_STRING:
116
- case T_FIXNUM:
117
- return buf;
118
- default:
119
- return StringValue(buf);
120
- }
121
- }
122
-
123
105
  VALUE Backend_finalize(VALUE self) {
124
106
  Backend_t *backend;
125
107
  GetBackend(self, backend);
@@ -347,8 +329,26 @@ VALUE io_uring_backend_wait_fd(Backend_t *backend, int fd, int write) {
347
329
  return resumed_value;
348
330
  }
349
331
 
332
+ static inline int fd_from_io(VALUE io, rb_io_t **fptr, int write_mode, int rectify_file_pos) {
333
+ if (rb_obj_class(io) == cPipe) {
334
+ *fptr = NULL;
335
+ return Pipe_get_fd(io, write_mode);
336
+ }
337
+ else {
338
+ VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
339
+ if (underlying_io != Qnil) io = underlying_io;
340
+
341
+ GetOpenFile(io, *fptr);
342
+ io_unset_nonblock(*fptr, io);
343
+ if (rectify_file_pos) rectify_io_file_pos(*fptr);
344
+
345
+ return (*fptr)->fd;
346
+ }
347
+ }
348
+
350
349
  VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof, VALUE pos) {
351
350
  Backend_t *backend;
351
+ int fd;
352
352
  rb_io_t *fptr;
353
353
  struct io_buffer buffer = get_io_buffer(str);
354
354
  long buf_pos = NUM2INT(pos);
@@ -356,38 +356,33 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof,
356
356
  int expandable_buffer = 0;
357
357
  long total = 0;
358
358
  int read_to_eof = RTEST(to_eof);
359
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
360
359
 
361
360
  if (buffer.raw) {
362
- if (buf_pos < 0 || buf_pos > buffer.size) buf_pos = buffer.size;
363
- buffer.base += buf_pos;
364
- buffer.size -= buf_pos;
361
+ if (buf_pos < 0 || buf_pos > buffer.len) buf_pos = buffer.len;
362
+ buffer.ptr += buf_pos;
363
+ buffer.len -= buf_pos;
365
364
  }
366
365
  else {
367
366
  expandable_buffer = length == Qnil;
368
367
  long expected_read_length = expandable_buffer ? 4096 : FIX2INT(length);
369
368
  long string_cap = rb_str_capacity(str);
370
- if (buf_pos < 0 || buf_pos > buffer.size) buf_pos = buffer.size;
369
+ if (buf_pos < 0 || buf_pos > buffer.len) buf_pos = buffer.len;
371
370
 
372
371
  if (string_cap < expected_read_length + buf_pos) {
373
372
  shrinkable_string = io_setstrbuf(&str, expected_read_length + buf_pos);
374
- buffer.base = RSTRING_PTR(str) + buf_pos;
375
- buffer.size = expected_read_length;
373
+ buffer.ptr = RSTRING_PTR(str) + buf_pos;
374
+ buffer.len = expected_read_length;
376
375
  }
377
376
  else {
378
- buffer.base += buf_pos;
379
- buffer.size = string_cap - buf_pos;
380
- if (buffer.size > expected_read_length)
381
- buffer.size = expected_read_length;
377
+ buffer.ptr += buf_pos;
378
+ buffer.len = string_cap - buf_pos;
379
+ if (buffer.len > expected_read_length)
380
+ buffer.len = expected_read_length;
382
381
  }
383
382
  }
384
383
 
385
384
  GetBackend(self, backend);
386
- if (underlying_io != Qnil) io = underlying_io;
387
- GetOpenFile(io, fptr);
388
- rb_io_check_byte_readable(fptr);
389
- io_unset_nonblock(fptr, io);
390
- rectify_io_file_pos(fptr);
385
+ fd = fd_from_io(io, &fptr, 0, 1);
391
386
 
392
387
  while (1) {
393
388
  VALUE resume_value = Qnil;
@@ -396,7 +391,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof,
396
391
  int result;
397
392
  int completed;
398
393
 
399
- io_uring_prep_read(sqe, fptr->fd, buffer.base, buffer.size - total, -1);
394
+ io_uring_prep_read(sqe, fd, buffer.ptr, buffer.len, -1);
400
395
 
401
396
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
402
397
  completed = context_store_release(&backend->store, ctx);
@@ -415,52 +410,47 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof,
415
410
  total += result;
416
411
  if (!read_to_eof) break;
417
412
 
418
- if (total == buffer.size) {
413
+ if (result == buffer.len) {
419
414
  if (!expandable_buffer) break;
420
415
 
421
- // resize buffer
416
+ // resize buffer to double its capacity
422
417
  rb_str_resize(str, total + buf_pos);
423
- rb_str_modify_expand(str, buffer.size);
418
+ rb_str_modify_expand(str, rb_str_capacity(str));
424
419
  shrinkable_string = 0;
425
- buffer.base = RSTRING_PTR(str) + total + buf_pos;
426
- buffer.size = buffer.size;
420
+ buffer.ptr = RSTRING_PTR(str) + total + buf_pos;
421
+ buffer.len = rb_str_capacity(str) - total - buf_pos;
427
422
  }
428
423
  else {
429
- buffer.base += result;
430
- buffer.size -= result;
431
- if (!buffer.size) break;
424
+ buffer.ptr += result;
425
+ buffer.len -= result;
426
+ if (!buffer.len) break;
432
427
  }
433
428
  }
434
429
  }
435
430
 
436
431
  if (!buffer.raw) {
437
432
  io_set_read_length(str, buf_pos + total, shrinkable_string);
438
- io_enc_str(str, fptr);
433
+ if (fptr) io_enc_str(str, fptr);
439
434
  }
440
-
441
435
  if (!total) return Qnil;
442
436
 
443
- return str;
437
+ return buffer.raw ? INT2FIX(total) : str;
444
438
  }
445
439
 
446
440
  VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
447
441
  Backend_t *backend;
442
+ int fd;
448
443
  rb_io_t *fptr;
449
444
  VALUE str;
450
445
  long total;
451
446
  long len = NUM2INT(maxlen);
452
447
  int shrinkable;
453
448
  char *buf;
454
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
455
449
 
456
450
  READ_LOOP_PREPARE_STR();
457
451
 
458
452
  GetBackend(self, backend);
459
- if (underlying_io != Qnil) io = underlying_io;
460
- GetOpenFile(io, fptr);
461
- rb_io_check_byte_readable(fptr);
462
- io_unset_nonblock(fptr, io);
463
- rectify_io_file_pos(fptr);
453
+ fd = fd_from_io(io, &fptr, 0, 1);
464
454
 
465
455
  while (1) {
466
456
  VALUE resume_value = Qnil;
@@ -469,7 +459,7 @@ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
469
459
  ssize_t result;
470
460
  int completed;
471
461
 
472
- io_uring_prep_read(sqe, fptr->fd, buf, len, -1);
462
+ io_uring_prep_read(sqe, fd, buf, len, -1);
473
463
 
474
464
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
475
465
  completed = context_store_release(&backend->store, ctx);
@@ -497,23 +487,19 @@ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
497
487
 
498
488
  VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
499
489
  Backend_t *backend;
490
+ int fd;
500
491
  rb_io_t *fptr;
501
492
  VALUE str;
502
493
  long total;
503
494
  long len = 8192;
504
495
  int shrinkable;
505
496
  char *buf;
506
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
507
497
  ID method_id = SYM2ID(method);
508
498
 
509
499
  READ_LOOP_PREPARE_STR();
510
500
 
511
501
  GetBackend(self, backend);
512
- if (underlying_io != Qnil) io = underlying_io;
513
- GetOpenFile(io, fptr);
514
- rb_io_check_byte_readable(fptr);
515
- io_unset_nonblock(fptr, io);
516
- rectify_io_file_pos(fptr);
502
+ fd = fd_from_io(io, &fptr, 0, 1);
517
503
 
518
504
  while (1) {
519
505
  VALUE resume_value = Qnil;
@@ -522,7 +508,7 @@ VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
522
508
  ssize_t result;
523
509
  int completed;
524
510
 
525
- io_uring_prep_read(sqe, fptr->fd, buf, len, -1);
511
+ io_uring_prep_read(sqe, fd, buf, len, -1);
526
512
 
527
513
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
528
514
  completed = context_store_release(&backend->store, ctx);
@@ -550,18 +536,14 @@ VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
550
536
 
551
537
  VALUE Backend_write(VALUE self, VALUE io, VALUE str) {
552
538
  Backend_t *backend;
539
+ int fd;
553
540
  rb_io_t *fptr;
554
- VALUE underlying_io;
555
541
 
556
542
  struct io_buffer buffer = get_io_buffer(str);
557
- long left = buffer.size;
543
+ long left = buffer.len;
558
544
 
559
- underlying_io = rb_ivar_get(io, ID_ivar_io);
560
- if (underlying_io != Qnil) io = underlying_io;
561
545
  GetBackend(self, backend);
562
- io = rb_io_get_write_io(io);
563
- GetOpenFile(io, fptr);
564
- io_unset_nonblock(fptr, io);
546
+ fd = fd_from_io(io, &fptr, 1, 0);
565
547
 
566
548
  while (left > 0) {
567
549
  VALUE resume_value = Qnil;
@@ -570,7 +552,7 @@ VALUE Backend_write(VALUE self, VALUE io, VALUE str) {
570
552
  int result;
571
553
  int completed;
572
554
 
573
- io_uring_prep_write(sqe, fptr->fd, buffer.base, left, 0);
555
+ io_uring_prep_write(sqe, fd, buffer.ptr, left, 0);
574
556
 
575
557
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
576
558
  completed = context_store_release(&backend->store, ctx);
@@ -584,30 +566,26 @@ VALUE Backend_write(VALUE self, VALUE io, VALUE str) {
584
566
  if (result < 0)
585
567
  rb_syserr_fail(-result, strerror(-result));
586
568
  else {
587
- buffer.base += result;
569
+ buffer.ptr += result;
588
570
  left -= result;
589
571
  }
590
572
  }
591
573
 
592
- return INT2NUM(buffer.size);
574
+ return INT2NUM(buffer.len);
593
575
  }
594
576
 
595
577
  VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
596
578
  Backend_t *backend;
579
+ int fd;
597
580
  rb_io_t *fptr;
598
- VALUE underlying_io;
599
581
  long total_length = 0;
600
582
  long total_written = 0;
601
583
  struct iovec *iov = 0;
602
584
  struct iovec *iov_ptr = 0;
603
585
  int iov_count = argc;
604
586
 
605
- underlying_io = rb_ivar_get(io, ID_ivar_io);
606
- if (underlying_io != Qnil) io = underlying_io;
607
587
  GetBackend(self, backend);
608
- io = rb_io_get_write_io(io);
609
- GetOpenFile(io, fptr);
610
- io_unset_nonblock(fptr, io);
588
+ fd = fd_from_io(io, &fptr, 1, 0);
611
589
 
612
590
  iov = malloc(iov_count * sizeof(struct iovec));
613
591
  for (int i = 0; i < argc; i++) {
@@ -625,7 +603,7 @@ VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
625
603
  int result;
626
604
  int completed;
627
605
 
628
- io_uring_prep_writev(sqe, fptr->fd, iov_ptr, iov_count, -1);
606
+ io_uring_prep_writev(sqe, fd, iov_ptr, iov_count, -1);
629
607
 
630
608
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
631
609
  completed = context_store_release(&backend->store, ctx);
@@ -675,29 +653,40 @@ VALUE Backend_write_m(int argc, VALUE *argv, VALUE self) {
675
653
 
676
654
  VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length, VALUE pos) {
677
655
  Backend_t *backend;
656
+ int fd;
678
657
  rb_io_t *fptr;
679
- long dynamic_len = length == Qnil;
680
- long len = dynamic_len ? 4096 : NUM2INT(length);
658
+ struct io_buffer buffer = get_io_buffer(str);
681
659
  long buf_pos = NUM2INT(pos);
682
- int shrinkable;
683
- char *buf;
660
+ int shrinkable_string = 0;
661
+ int expandable_buffer = 0;
684
662
  long total = 0;
685
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);;
686
663
 
687
- if (str != Qnil) {
688
- int current_len = RSTRING_LEN(str);
689
- if (buf_pos < 0 || buf_pos > current_len) buf_pos = current_len;
664
+ if (buffer.raw) {
665
+ if (buf_pos < 0 || buf_pos > buffer.len) buf_pos = buffer.len;
666
+ buffer.ptr += buf_pos;
667
+ buffer.len -= buf_pos;
668
+ }
669
+ else {
670
+ expandable_buffer = length == Qnil;
671
+ long expected_read_length = expandable_buffer ? 4096 : FIX2INT(length);
672
+ long string_cap = rb_str_capacity(str);
673
+ if (buf_pos < 0 || buf_pos > buffer.len) buf_pos = buffer.len;
674
+
675
+ if (string_cap < expected_read_length + buf_pos) {
676
+ shrinkable_string = io_setstrbuf(&str, expected_read_length + buf_pos);
677
+ buffer.ptr = RSTRING_PTR(str) + buf_pos;
678
+ buffer.len = expected_read_length;
679
+ }
680
+ else {
681
+ buffer.ptr += buf_pos;
682
+ buffer.len = string_cap - buf_pos;
683
+ if (buffer.len > expected_read_length)
684
+ buffer.len = expected_read_length;
685
+ }
690
686
  }
691
- else buf_pos = 0;
692
- shrinkable = io_setstrbuf(&str, buf_pos + len);
693
- buf = RSTRING_PTR(str) + buf_pos;
694
687
 
695
688
  GetBackend(self, backend);
696
- if (underlying_io != Qnil) io = underlying_io;
697
- GetOpenFile(io, fptr);
698
- rb_io_check_byte_readable(fptr);
699
- io_unset_nonblock(fptr, io);
700
- rectify_io_file_pos(fptr);
689
+ fd = fd_from_io(io, &fptr, 0, 0);
701
690
 
702
691
  while (1) {
703
692
  VALUE resume_value = Qnil;
@@ -706,7 +695,7 @@ VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length, VALUE pos) {
706
695
  int result;
707
696
  int completed;
708
697
 
709
- io_uring_prep_recv(sqe, fptr->fd, buf, len - total, 0);
698
+ io_uring_prep_recv(sqe, fd, buffer.ptr, buffer.len, 0);
710
699
 
711
700
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
712
701
  completed = context_store_release(&backend->store, ctx);
@@ -725,32 +714,29 @@ VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length, VALUE pos) {
725
714
  }
726
715
  }
727
716
 
728
- io_set_read_length(str, buf_pos + total, shrinkable);
729
- io_enc_str(str, fptr);
730
-
717
+ if (!buffer.raw) {
718
+ io_set_read_length(str, buf_pos + total, shrinkable_string);
719
+ if (fptr) io_enc_str(str, fptr);
720
+ }
731
721
  if (!total) return Qnil;
732
722
 
733
- return str;
723
+ return buffer.raw ? INT2FIX(total) : str;
734
724
  }
735
725
 
736
726
  VALUE Backend_recv_loop(VALUE self, VALUE io, VALUE maxlen) {
737
727
  Backend_t *backend;
728
+ int fd;
738
729
  rb_io_t *fptr;
739
730
  VALUE str;
740
731
  long total;
741
732
  long len = NUM2INT(maxlen);
742
733
  int shrinkable;
743
734
  char *buf;
744
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
745
735
 
746
736
  READ_LOOP_PREPARE_STR();
747
737
 
748
738
  GetBackend(self, backend);
749
- if (underlying_io != Qnil) io = underlying_io;
750
- GetOpenFile(io, fptr);
751
- rb_io_check_byte_readable(fptr);
752
- io_unset_nonblock(fptr, io);
753
- rectify_io_file_pos(fptr);
739
+ fd = fd_from_io(io, &fptr, 0, 0);
754
740
 
755
741
  while (1) {
756
742
  VALUE resume_value = Qnil;
@@ -759,7 +745,7 @@ VALUE Backend_recv_loop(VALUE self, VALUE io, VALUE maxlen) {
759
745
  int result;
760
746
  int completed;
761
747
 
762
- io_uring_prep_recv(sqe, fptr->fd, buf, len, 0);
748
+ io_uring_prep_recv(sqe, fd, buf, len, 0);
763
749
 
764
750
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
765
751
  completed = context_store_release(&backend->store, ctx);
@@ -786,23 +772,19 @@ VALUE Backend_recv_loop(VALUE self, VALUE io, VALUE maxlen) {
786
772
 
787
773
  VALUE Backend_recv_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
788
774
  Backend_t *backend;
775
+ int fd;
789
776
  rb_io_t *fptr;
790
777
  VALUE str;
791
778
  long total;
792
779
  long len = 8192;
793
780
  int shrinkable;
794
781
  char *buf;
795
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
796
782
  ID method_id = SYM2ID(method);
797
783
 
798
784
  READ_LOOP_PREPARE_STR();
799
785
 
800
786
  GetBackend(self, backend);
801
- if (underlying_io != Qnil) io = underlying_io;
802
- GetOpenFile(io, fptr);
803
- rb_io_check_byte_readable(fptr);
804
- io_unset_nonblock(fptr, io);
805
- rectify_io_file_pos(fptr);
787
+ fd = fd_from_io(io, &fptr, 0, 0);
806
788
 
807
789
  while (1) {
808
790
  VALUE resume_value = Qnil;
@@ -811,7 +793,7 @@ VALUE Backend_recv_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method)
811
793
  int result;
812
794
  int completed;
813
795
 
814
- io_uring_prep_recv(sqe, fptr->fd, buf, len, 0);
796
+ io_uring_prep_recv(sqe, fd, buf, len, 0);
815
797
 
816
798
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
817
799
  completed = context_store_release(&backend->store, ctx);
@@ -838,24 +820,15 @@ VALUE Backend_recv_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method)
838
820
 
839
821
  VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
840
822
  Backend_t *backend;
823
+ int fd;
841
824
  rb_io_t *fptr;
842
- VALUE underlying_io;
843
- char *buf;
844
- long len;
845
- long left;
846
- int flags_int;
847
825
 
848
- underlying_io = rb_ivar_get(io, ID_ivar_io);
849
- if (underlying_io != Qnil) io = underlying_io;
850
- GetBackend(self, backend);
851
- io = rb_io_get_write_io(io);
852
- GetOpenFile(io, fptr);
853
- io_unset_nonblock(fptr, io);
826
+ struct io_buffer buffer = get_io_buffer(str);
827
+ long left = buffer.len;
828
+ int flags_int = NUM2INT(flags);
854
829
 
855
- buf = StringValuePtr(str);
856
- len = RSTRING_LEN(str);
857
- left = len;
858
- flags_int = NUM2INT(flags);
830
+ GetBackend(self, backend);
831
+ fd = fd_from_io(io, &fptr, 1, 0);
859
832
 
860
833
  while (left > 0) {
861
834
  VALUE resume_value = Qnil;
@@ -864,7 +837,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
864
837
  int result;
865
838
  int completed;
866
839
 
867
- io_uring_prep_send(sqe, fptr->fd, buf, left, flags_int);
840
+ io_uring_prep_send(sqe, fd, buffer.ptr, left, flags_int);
868
841
 
869
842
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
870
843
  completed = context_store_release(&backend->store, ctx);
@@ -878,24 +851,22 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
878
851
  if (result < 0)
879
852
  rb_syserr_fail(-result, strerror(-result));
880
853
  else {
881
- buf += result;
854
+ buffer.ptr += result;
882
855
  left -= result;
883
856
  }
884
857
  }
885
858
 
886
- return INT2NUM(len);
859
+ return INT2NUM(buffer.len);
887
860
  }
888
861
 
889
862
  VALUE io_uring_backend_accept(Backend_t *backend, VALUE server_socket, VALUE socket_class, int loop) {
890
- rb_io_t *fptr;
863
+ int server_fd;
864
+ rb_io_t *server_fptr;
891
865
  struct sockaddr addr;
892
866
  socklen_t len = (socklen_t)sizeof addr;
893
867
  VALUE socket = Qnil;
894
- VALUE underlying_sock = rb_ivar_get(server_socket, ID_ivar_io);
895
- if (underlying_sock != Qnil) server_socket = underlying_sock;
896
868
 
897
- GetOpenFile(server_socket, fptr);
898
- io_unset_nonblock(fptr, server_socket);
869
+ server_fd = fd_from_io(server_socket, &server_fptr, 0, 0);
899
870
 
900
871
  while (1) {
901
872
  VALUE resume_value = Qnil;
@@ -904,7 +875,7 @@ VALUE io_uring_backend_accept(Backend_t *backend, VALUE server_socket, VALUE soc
904
875
  int fd;
905
876
  int completed;
906
877
 
907
- io_uring_prep_accept(sqe, fptr->fd, &addr, &len, 0);
878
+ io_uring_prep_accept(sqe, server_fd, &addr, &len, 0);
908
879
 
909
880
  fd = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
910
881
  completed = context_store_release(&backend->store, ctx);
@@ -954,22 +925,15 @@ VALUE Backend_accept_loop(VALUE self, VALUE server_socket, VALUE socket_class) {
954
925
  }
955
926
 
956
927
  VALUE io_uring_backend_splice(Backend_t *backend, VALUE src, VALUE dest, VALUE maxlen, int loop) {
928
+ int src_fd;
929
+ int dest_fd;
957
930
  rb_io_t *src_fptr;
958
931
  rb_io_t *dest_fptr;
959
- VALUE underlying_io;
960
932
  int total = 0;
961
933
  VALUE resume_value = Qnil;
962
934
 
963
- underlying_io = rb_ivar_get(src, ID_ivar_io);
964
- if (underlying_io != Qnil) src = underlying_io;
965
- GetOpenFile(src, src_fptr);
966
- io_unset_nonblock(src_fptr, src);
967
-
968
- underlying_io = rb_ivar_get(dest, ID_ivar_io);
969
- if (underlying_io != Qnil) dest = underlying_io;
970
- dest = rb_io_get_write_io(dest);
971
- GetOpenFile(dest, dest_fptr);
972
- io_unset_nonblock(dest_fptr, dest);
935
+ src_fd = fd_from_io(src, &src_fptr, 0, 0);
936
+ dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
973
937
 
974
938
  while (1) {
975
939
  op_context_t *ctx = context_store_acquire(&backend->store, OP_SPLICE);
@@ -977,7 +941,7 @@ VALUE io_uring_backend_splice(Backend_t *backend, VALUE src, VALUE dest, VALUE m
977
941
  int result;
978
942
  int completed;
979
943
 
980
- io_uring_prep_splice(sqe, src_fptr->fd, -1, dest_fptr->fd, -1, NUM2INT(maxlen), 0);
944
+ io_uring_prep_splice(sqe, src_fd, -1, dest_fd, -1, NUM2INT(maxlen), 0);
981
945
 
982
946
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
983
947
  completed = context_store_release(&backend->store, ctx);
@@ -997,7 +961,6 @@ VALUE io_uring_backend_splice(Backend_t *backend, VALUE src, VALUE dest, VALUE m
997
961
  VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
998
962
  Backend_t *backend;
999
963
  GetBackend(self, backend);
1000
-
1001
964
  return io_uring_backend_splice(backend, src, dest, maxlen, 0);
1002
965
  }
1003
966
 
@@ -1010,10 +973,10 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE chunksize)
1010
973
 
1011
974
  VALUE Backend_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
1012
975
  Backend_t *backend;
976
+ int fd;
1013
977
  rb_io_t *fptr;
1014
978
  struct sockaddr *ai_addr;
1015
979
  int ai_addrlen;
1016
- VALUE underlying_sock = rb_ivar_get(sock, ID_ivar_io);
1017
980
  VALUE resume_value = Qnil;
1018
981
  op_context_t *ctx;
1019
982
  struct io_uring_sqe *sqe;
@@ -1022,15 +985,11 @@ VALUE Backend_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
1022
985
 
1023
986
  ai_addrlen = backend_getaddrinfo(host, port, &ai_addr);
1024
987
 
1025
- if (underlying_sock != Qnil) sock = underlying_sock;
1026
-
1027
988
  GetBackend(self, backend);
1028
- GetOpenFile(sock, fptr);
1029
- io_unset_nonblock(fptr, sock);
1030
-
989
+ fd = fd_from_io(sock, &fptr, 1, 0);
1031
990
  ctx = context_store_acquire(&backend->store, OP_CONNECT);
1032
991
  sqe = io_uring_get_sqe(&backend->ring);
1033
- io_uring_prep_connect(sqe, fptr->fd, ai_addr, ai_addrlen);
992
+ io_uring_prep_connect(sqe, fd, ai_addr, ai_addrlen);
1034
993
  result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
1035
994
  completed = context_store_release(&backend->store, ctx);
1036
995
  RAISE_IF_EXCEPTION(resume_value);
@@ -1043,16 +1002,14 @@ VALUE Backend_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
1043
1002
 
1044
1003
  VALUE Backend_wait_io(VALUE self, VALUE io, VALUE write) {
1045
1004
  Backend_t *backend;
1005
+ int fd;
1046
1006
  rb_io_t *fptr;
1047
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
1048
1007
  VALUE resume_value;
1008
+ int write_mode = RTEST(write);
1049
1009
 
1050
- if (underlying_io != Qnil) io = underlying_io;
1051
1010
  GetBackend(self, backend);
1052
- GetOpenFile(io, fptr);
1053
- io_unset_nonblock(fptr, io);
1054
-
1055
- resume_value = io_uring_backend_wait_fd(backend, fptr->fd, RTEST(write));
1011
+ fd = fd_from_io(io, &fptr, write_mode, 0);
1012
+ resume_value = io_uring_backend_wait_fd(backend, fd, write_mode);
1056
1013
 
1057
1014
  RAISE_IF_EXCEPTION(resume_value);
1058
1015
  RB_GC_GUARD(resume_value);
@@ -1062,24 +1019,19 @@ VALUE Backend_wait_io(VALUE self, VALUE io, VALUE write) {
1062
1019
  // VALUE Backend_close(VALUE self, VALUE io) {
1063
1020
  // Backend_t *backend;
1064
1021
  // rb_io_t *fptr;
1065
- // VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
1066
1022
  // VALUE resume_value = Qnil;
1067
1023
  // op_context_t *ctx;
1068
1024
  // struct io_uring_sqe *sqe;
1069
1025
  // int result;
1070
1026
  // int completed;
1071
1027
 
1072
- // if (underlying_io != Qnil) io = underlying_io;
1073
- // GetBackend(self, backend);
1074
- // GetOpenFile(io, fptr);
1075
-
1076
- // if (fptr->fd < 0) return Qnil;
1028
+ // if (fd < 0) return Qnil;
1077
1029
 
1078
1030
  // io_unset_nonblock(fptr, io);
1079
1031
 
1080
1032
  // ctx = context_store_acquire(&backend->store, OP_CLOSE);
1081
1033
  // sqe = io_uring_get_sqe(&backend->ring);
1082
- // io_uring_prep_close(sqe, fptr->fd);
1034
+ // io_uring_prep_close(sqe, fd);
1083
1035
  // result = io_uring_backend_defer_submit_and_await(backend, sqe, ctx, &resume_value);
1084
1036
  // completed = context_store_release(&backend->store, ctx);
1085
1037
  // RAISE_IF_EXCEPTION(resume_value);
@@ -1089,7 +1041,7 @@ VALUE Backend_wait_io(VALUE self, VALUE io, VALUE write) {
1089
1041
  // if (result < 0) rb_syserr_fail(-result, strerror(-result));
1090
1042
 
1091
1043
  // fptr_finalize(fptr);
1092
- // // fptr->fd = -1;
1044
+ // // fd = -1;
1093
1045
  // return io;
1094
1046
  // }
1095
1047
 
@@ -1275,56 +1227,39 @@ VALUE Backend_kind(VALUE self) {
1275
1227
  }
1276
1228
 
1277
1229
  struct io_uring_sqe *Backend_chain_prepare_write(Backend_t *backend, VALUE io, VALUE str) {
1230
+ int fd;
1278
1231
  rb_io_t *fptr;
1279
- VALUE underlying_io;
1280
1232
  struct io_uring_sqe *sqe;
1281
1233
 
1282
- underlying_io = rb_ivar_get(io, ID_ivar_io);
1283
- if (underlying_io != Qnil) io = underlying_io;
1284
- io = rb_io_get_write_io(io);
1285
- GetOpenFile(io, fptr);
1286
- io_unset_nonblock(fptr, io);
1287
-
1234
+ fd = fd_from_io(io, &fptr, 1, 0);
1288
1235
  sqe = io_uring_get_sqe(&backend->ring);
1289
- io_uring_prep_write(sqe, fptr->fd, StringValuePtr(str), RSTRING_LEN(str), 0);
1236
+ io_uring_prep_write(sqe, fd, StringValuePtr(str), RSTRING_LEN(str), 0);
1290
1237
  return sqe;
1291
1238
  }
1292
1239
 
1293
1240
  struct io_uring_sqe *Backend_chain_prepare_send(Backend_t *backend, VALUE io, VALUE str, VALUE flags) {
1241
+ int fd;
1294
1242
  rb_io_t *fptr;
1295
- VALUE underlying_io;
1296
1243
  struct io_uring_sqe *sqe;
1297
1244
 
1298
- underlying_io = rb_ivar_get(io, ID_ivar_io);
1299
- if (underlying_io != Qnil) io = underlying_io;
1300
- io = rb_io_get_write_io(io);
1301
- GetOpenFile(io, fptr);
1302
- io_unset_nonblock(fptr, io);
1245
+ fd = fd_from_io(io, &fptr, 1, 0);
1303
1246
 
1304
1247
  sqe = io_uring_get_sqe(&backend->ring);
1305
- io_uring_prep_send(sqe, fptr->fd, StringValuePtr(str), RSTRING_LEN(str), NUM2INT(flags));
1248
+ io_uring_prep_send(sqe, fd, StringValuePtr(str), RSTRING_LEN(str), NUM2INT(flags));
1306
1249
  return sqe;
1307
1250
  }
1308
1251
 
1309
1252
  struct io_uring_sqe *Backend_chain_prepare_splice(Backend_t *backend, VALUE src, VALUE dest, VALUE maxlen) {
1253
+ int src_fd;
1254
+ int dest_fd;
1310
1255
  rb_io_t *src_fptr;
1311
1256
  rb_io_t *dest_fptr;
1312
- VALUE underlying_io;
1313
1257
  struct io_uring_sqe *sqe;
1314
1258
 
1315
- underlying_io = rb_ivar_get(src, ID_ivar_io);
1316
- if (underlying_io != Qnil) src = underlying_io;
1317
- GetOpenFile(src, src_fptr);
1318
- io_unset_nonblock(src_fptr, src);
1319
-
1320
- underlying_io = rb_ivar_get(dest, ID_ivar_io);
1321
- if (underlying_io != Qnil) dest = underlying_io;
1322
- dest = rb_io_get_write_io(dest);
1323
- GetOpenFile(dest, dest_fptr);
1324
- io_unset_nonblock(dest_fptr, dest);
1325
-
1259
+ src_fd = fd_from_io(src, &src_fptr, 0, 0);
1260
+ dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
1326
1261
  sqe = io_uring_get_sqe(&backend->ring);
1327
- io_uring_prep_splice(sqe, src_fptr->fd, -1, dest_fptr->fd, -1, NUM2INT(maxlen), 0);
1262
+ io_uring_prep_splice(sqe, src_fd, -1, dest_fd, -1, NUM2INT(maxlen), 0);
1328
1263
  return sqe;
1329
1264
  }
1330
1265
 
@@ -1517,25 +1452,17 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1517
1452
  op_context_t *ctx = 0;
1518
1453
  struct io_uring_sqe *sqe = 0;
1519
1454
  int maxlen;
1520
- VALUE underlying_io;
1521
1455
  VALUE str = Qnil;
1522
1456
  VALUE chunk_len_value = Qnil;
1457
+ int src_fd;
1458
+ int dest_fd;
1523
1459
  rb_io_t *src_fptr;
1524
1460
  rb_io_t *dest_fptr;
1525
1461
  int pipefd[2] = { -1, -1 };
1526
1462
 
1527
1463
  GetBackend(self, backend);
1528
-
1529
- underlying_io = rb_ivar_get(src, ID_ivar_io);
1530
- if (underlying_io != Qnil) src = underlying_io;
1531
- GetOpenFile(src, src_fptr);
1532
- io_verify_blocking_mode(src_fptr, src, Qtrue);
1533
-
1534
- underlying_io = rb_ivar_get(dest, ID_ivar_io);
1535
- if (underlying_io != Qnil) dest = underlying_io;
1536
- dest = rb_io_get_write_io(dest);
1537
- GetOpenFile(dest, dest_fptr);
1538
- io_verify_blocking_mode(dest_fptr, dest, Qtrue);
1464
+ src_fd = fd_from_io(src, &src_fptr, 0, 0);
1465
+ dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
1539
1466
 
1540
1467
  maxlen = NUM2INT(chunk_size);
1541
1468
 
@@ -1546,7 +1473,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1546
1473
 
1547
1474
  if (prefix != Qnil) {
1548
1475
  splice_chunks_get_sqe(backend, &ctx, &sqe, OP_WRITE);
1549
- splice_chunks_prep_write(ctx, sqe, dest_fptr->fd, prefix);
1476
+ splice_chunks_prep_write(ctx, sqe, dest_fd, prefix);
1550
1477
  backend->base.op_count++;
1551
1478
  }
1552
1479
 
@@ -1556,7 +1483,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1556
1483
  VALUE chunk_postfix_str = Qnil;
1557
1484
 
1558
1485
  splice_chunks_get_sqe(backend, &ctx, &sqe, OP_SPLICE);
1559
- splice_chunks_prep_splice(ctx, sqe, src_fptr->fd, pipefd[1], maxlen);
1486
+ splice_chunks_prep_splice(ctx, sqe, src_fd, pipefd[1], maxlen);
1560
1487
  backend->base.op_count++;
1561
1488
 
1562
1489
  SPLICE_CHUNKS_AWAIT_OPS(backend, &ctx, &chunk_len, &switchpoint_result);
@@ -1569,18 +1496,18 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1569
1496
  if (chunk_prefix != Qnil) {
1570
1497
  chunk_prefix_str = (TYPE(chunk_prefix) == T_STRING) ? chunk_prefix : rb_funcall(chunk_prefix, ID_call, 1, chunk_len_value);
1571
1498
  splice_chunks_get_sqe(backend, &ctx, &sqe, OP_WRITE);
1572
- splice_chunks_prep_write(ctx, sqe, dest_fptr->fd, chunk_prefix_str);
1499
+ splice_chunks_prep_write(ctx, sqe, dest_fd, chunk_prefix_str);
1573
1500
  backend->base.op_count++;
1574
1501
  }
1575
1502
 
1576
1503
  splice_chunks_get_sqe(backend, &ctx, &sqe, OP_SPLICE);
1577
- splice_chunks_prep_splice(ctx, sqe, pipefd[0], dest_fptr->fd, chunk_len);
1504
+ splice_chunks_prep_splice(ctx, sqe, pipefd[0], dest_fd, chunk_len);
1578
1505
  backend->base.op_count++;
1579
1506
 
1580
1507
  if (chunk_postfix != Qnil) {
1581
1508
  chunk_postfix_str = (TYPE(chunk_postfix) == T_STRING) ? chunk_postfix : rb_funcall(chunk_postfix, ID_call, 1, chunk_len_value);
1582
1509
  splice_chunks_get_sqe(backend, &ctx, &sqe, OP_WRITE);
1583
- splice_chunks_prep_write(ctx, sqe, dest_fptr->fd, chunk_postfix_str);
1510
+ splice_chunks_prep_write(ctx, sqe, dest_fd, chunk_postfix_str);
1584
1511
  backend->base.op_count++;
1585
1512
  }
1586
1513
 
@@ -1590,7 +1517,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1590
1517
 
1591
1518
  if (postfix != Qnil) {
1592
1519
  splice_chunks_get_sqe(backend, &ctx, &sqe, OP_WRITE);
1593
- splice_chunks_prep_write(ctx, sqe, dest_fptr->fd, postfix);
1520
+ splice_chunks_prep_write(ctx, sqe, dest_fd, postfix);
1594
1521
  backend->base.op_count++;
1595
1522
  }
1596
1523
  if (ctx) {