polyphony 0.82 → 0.84.1

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.
@@ -266,9 +266,28 @@ VALUE libev_wait_fd(Backend_t *backend, int fd, int events, int raise_exception)
266
266
  return switchpoint_result;
267
267
  }
268
268
 
269
+ static inline int fd_from_io(VALUE io, rb_io_t **fptr, int write_mode, int rectify_file_pos) {
270
+ if (rb_obj_class(io) == cPipe) {
271
+ *fptr = NULL;
272
+ Pipe_verify_blocking_mode(io, Qfalse);
273
+ return Pipe_get_fd(io, write_mode);
274
+ }
275
+ else {
276
+ VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
277
+ if (underlying_io != Qnil) io = underlying_io;
278
+
279
+ GetOpenFile(io, *fptr);
280
+ io_verify_blocking_mode(*fptr, io, Qfalse);
281
+ if (rectify_file_pos) rectify_io_file_pos(*fptr);
282
+
283
+ return (*fptr)->fd;
284
+ }
285
+ }
286
+
269
287
  VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof, VALUE pos) {
270
288
  Backend_t *backend;
271
289
  struct libev_io watcher;
290
+ int fd;
272
291
  rb_io_t *fptr;
273
292
 
274
293
  struct io_buffer buffer = get_io_buffer(str);
@@ -278,7 +297,6 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof,
278
297
  long total = 0;
279
298
  VALUE switchpoint_result = Qnil;
280
299
  int read_to_eof = RTEST(to_eof);
281
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
282
300
 
283
301
  if (buffer.raw) {
284
302
  if (buf_pos < 0 || buf_pos > buffer.len) buf_pos = buffer.len;
@@ -305,21 +323,17 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof,
305
323
  }
306
324
 
307
325
  GetBackend(self, backend);
308
- if (underlying_io != Qnil) io = underlying_io;
309
- GetOpenFile(io, fptr);
310
- rb_io_check_byte_readable(fptr);
311
- io_verify_blocking_mode(fptr, io, Qfalse);
312
- rectify_io_file_pos(fptr);
326
+ fd = fd_from_io(io, &fptr, 0, 1);
313
327
  watcher.fiber = Qnil;
314
328
 
315
329
  while (1) {
316
330
  backend->base.op_count++;
317
- ssize_t result = read(fptr->fd, buffer.ptr, buffer.len);
331
+ ssize_t result = read(fd, buffer.ptr, buffer.len);
318
332
  if (result < 0) {
319
333
  int e = errno;
320
334
  if (e != EWOULDBLOCK && e != EAGAIN) rb_syserr_fail(e, strerror(e));
321
335
 
322
- switchpoint_result = libev_wait_fd_with_watcher(backend, fptr->fd, &watcher, EV_READ);
336
+ switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_READ);
323
337
 
324
338
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
325
339
  }
@@ -352,7 +366,7 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof,
352
366
 
353
367
  if (!buffer.raw) {
354
368
  io_set_read_length(str, buf_pos + total, shrinkable_string);
355
- io_enc_str(str, fptr);
369
+ if (fptr) io_enc_str(str, fptr);
356
370
  }
357
371
  if (!total) return Qnil;
358
372
 
@@ -371,6 +385,7 @@ VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length, VALUE pos) {
371
385
  VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
372
386
  Backend_t *backend;
373
387
  struct libev_io watcher;
388
+ int fd;
374
389
  rb_io_t *fptr;
375
390
  VALUE str;
376
391
  long total;
@@ -378,26 +393,21 @@ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
378
393
  int shrinkable;
379
394
  char *buf;
380
395
  VALUE switchpoint_result = Qnil;
381
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
382
396
 
383
397
  READ_LOOP_PREPARE_STR();
384
398
 
385
399
  GetBackend(self, backend);
386
- if (underlying_io != Qnil) io = underlying_io;
387
- GetOpenFile(io, fptr);
388
- rb_io_check_byte_readable(fptr);
389
- io_verify_blocking_mode(fptr, io, Qfalse);
390
- rectify_io_file_pos(fptr);
400
+ fd = fd_from_io(io, &fptr, 0, 1);
391
401
  watcher.fiber = Qnil;
392
402
 
393
403
  while (1) {
394
404
  backend->base.op_count++;
395
- ssize_t n = read(fptr->fd, buf, len);
405
+ ssize_t n = read(fd, buf, len);
396
406
  if (n < 0) {
397
407
  int e = errno;
398
408
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
399
409
 
400
- switchpoint_result = libev_wait_fd_with_watcher(backend, fptr->fd, &watcher, EV_READ);
410
+ switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_READ);
401
411
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
402
412
  }
403
413
  else {
@@ -423,6 +433,7 @@ error:
423
433
  VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
424
434
  Backend_t *backend;
425
435
  struct libev_io watcher;
436
+ int fd;
426
437
  rb_io_t *fptr;
427
438
  VALUE str;
428
439
  long total;
@@ -430,27 +441,22 @@ VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
430
441
  int shrinkable;
431
442
  char *buf;
432
443
  VALUE switchpoint_result = Qnil;
433
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
434
444
  ID method_id = SYM2ID(method);
435
445
 
436
446
  READ_LOOP_PREPARE_STR();
437
447
 
438
448
  GetBackend(self, backend);
439
- if (underlying_io != Qnil) io = underlying_io;
440
- GetOpenFile(io, fptr);
441
- rb_io_check_byte_readable(fptr);
442
- io_verify_blocking_mode(fptr, io, Qfalse);
443
- rectify_io_file_pos(fptr);
449
+ fd = fd_from_io(io, &fptr, 0, 1);
444
450
  watcher.fiber = Qnil;
445
451
 
446
452
  while (1) {
447
453
  backend->base.op_count++;
448
- ssize_t n = read(fptr->fd, buf, len);
454
+ ssize_t n = read(fd, buf, len);
449
455
  if (n < 0) {
450
456
  int e = errno;
451
457
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
452
458
 
453
- switchpoint_result = libev_wait_fd_with_watcher(backend, fptr->fd, &watcher, EV_READ);
459
+ switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_READ);
454
460
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
455
461
  }
456
462
  else {
@@ -476,29 +482,25 @@ error:
476
482
  VALUE Backend_write(VALUE self, VALUE io, VALUE str) {
477
483
  Backend_t *backend;
478
484
  struct libev_io watcher;
485
+ int fd;
479
486
  rb_io_t *fptr;
480
487
  VALUE switchpoint_result = Qnil;
481
- VALUE underlying_io;
482
488
 
483
489
  struct io_buffer buffer = get_io_buffer(str);
484
490
  long left = buffer.len;
485
491
 
486
- underlying_io = rb_ivar_get(io, ID_ivar_io);
487
- if (underlying_io != Qnil) io = underlying_io;
488
492
  GetBackend(self, backend);
489
- io = rb_io_get_write_io(io);
490
- GetOpenFile(io, fptr);
491
- io_verify_blocking_mode(fptr, io, Qfalse);
493
+ fd = fd_from_io(io, &fptr, 1, 0);
492
494
  watcher.fiber = Qnil;
493
495
 
494
496
  while (left > 0) {
495
497
  backend->base.op_count++;
496
- ssize_t result = write(fptr->fd, buffer.ptr, left);
498
+ ssize_t result = write(fd, buffer.ptr, left);
497
499
  if (result < 0) {
498
500
  int e = errno;
499
501
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
500
502
 
501
- switchpoint_result = libev_wait_fd_with_watcher(backend, fptr->fd, &watcher, EV_WRITE);
503
+ switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_WRITE);
502
504
 
503
505
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
504
506
  }
@@ -525,21 +527,17 @@ error:
525
527
  VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
526
528
  Backend_t *backend;
527
529
  struct libev_io watcher;
530
+ int fd;
528
531
  rb_io_t *fptr;
529
532
  VALUE switchpoint_result = Qnil;
530
- VALUE underlying_io;
531
533
  long total_length = 0;
532
534
  long total_written = 0;
533
535
  struct iovec *iov = 0;
534
536
  struct iovec *iov_ptr = 0;
535
537
  int iov_count = argc;
536
538
 
537
- underlying_io = rb_ivar_get(io, ID_ivar_io);
538
- if (underlying_io != Qnil) io = underlying_io;
539
539
  GetBackend(self, backend);
540
- io = rb_io_get_write_io(io);
541
- GetOpenFile(io, fptr);
542
- io_verify_blocking_mode(fptr, io, Qfalse);
540
+ fd = fd_from_io(io, &fptr, 1, 0);
543
541
  watcher.fiber = Qnil;
544
542
 
545
543
  iov = malloc(iov_count * sizeof(struct iovec));
@@ -553,7 +551,7 @@ VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
553
551
 
554
552
  while (1) {
555
553
  backend->base.op_count++;
556
- ssize_t n = writev(fptr->fd, iov_ptr, iov_count);
554
+ ssize_t n = writev(fd, iov_ptr, iov_count);
557
555
  if (n < 0) {
558
556
  int e = errno;
559
557
  if ((e != EWOULDBLOCK && e != EAGAIN)) {
@@ -561,7 +559,7 @@ VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
561
559
  rb_syserr_fail(e, strerror(e));
562
560
  }
563
561
 
564
- switchpoint_result = libev_wait_fd_with_watcher(backend, fptr->fd, &watcher, EV_WRITE);
562
+ switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_WRITE);
565
563
 
566
564
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
567
565
  }
@@ -611,26 +609,25 @@ VALUE Backend_write_m(int argc, VALUE *argv, VALUE self) {
611
609
  VALUE Backend_accept(VALUE self, VALUE server_socket, VALUE socket_class) {
612
610
  Backend_t *backend;
613
611
  struct libev_io watcher;
614
- rb_io_t *fptr;
612
+ int server_fd;
613
+ rb_io_t *server_fptr;
615
614
  int fd;
616
615
  struct sockaddr addr;
617
616
  socklen_t len = (socklen_t)sizeof addr;
618
617
  VALUE switchpoint_result = Qnil;
619
- VALUE underlying_sock = rb_ivar_get(server_socket, ID_ivar_io);
620
- if (underlying_sock != Qnil) server_socket = underlying_sock;
621
618
 
622
619
  GetBackend(self, backend);
623
- GetOpenFile(server_socket, fptr);
624
- io_verify_blocking_mode(fptr, server_socket, Qfalse);
620
+ server_fd = fd_from_io(server_socket, &server_fptr, 0, 0);
625
621
  watcher.fiber = Qnil;
622
+
626
623
  while (1) {
627
624
  backend->base.op_count++;
628
- fd = accept(fptr->fd, &addr, &len);
625
+ fd = accept(server_fd, &addr, &len);
629
626
  if (fd < 0) {
630
627
  int e = errno;
631
628
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
632
629
 
633
- switchpoint_result = libev_wait_fd_with_watcher(backend, fptr->fd, &watcher, EV_READ);
630
+ switchpoint_result = libev_wait_fd_with_watcher(backend, server_fd, &watcher, EV_READ);
634
631
 
635
632
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
636
633
  }
@@ -668,28 +665,25 @@ error:
668
665
  VALUE Backend_accept_loop(VALUE self, VALUE server_socket, VALUE socket_class) {
669
666
  Backend_t *backend;
670
667
  struct libev_io watcher;
671
- rb_io_t *fptr;
672
- int fd;
668
+ int server_fd;
669
+ rb_io_t *server_fptr;
673
670
  struct sockaddr addr;
674
671
  socklen_t len = (socklen_t)sizeof addr;
675
672
  VALUE switchpoint_result = Qnil;
676
673
  VALUE socket = Qnil;
677
- VALUE underlying_sock = rb_ivar_get(server_socket, ID_ivar_io);
678
- if (underlying_sock != Qnil) server_socket = underlying_sock;
679
674
 
680
675
  GetBackend(self, backend);
681
- GetOpenFile(server_socket, fptr);
682
- io_verify_blocking_mode(fptr, server_socket, Qfalse);
676
+ server_fd = fd_from_io(server_socket, &server_fptr, 0, 0);
683
677
  watcher.fiber = Qnil;
684
678
 
685
679
  while (1) {
686
680
  backend->base.op_count++;
687
- fd = accept(fptr->fd, &addr, &len);
681
+ int fd = accept(server_fd, &addr, &len);
688
682
  if (fd < 0) {
689
683
  int e = errno;
690
684
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
691
685
 
692
- switchpoint_result = libev_wait_fd_with_watcher(backend, fptr->fd, &watcher, EV_READ);
686
+ switchpoint_result = libev_wait_fd_with_watcher(backend, server_fd, &watcher, EV_READ);
693
687
 
694
688
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
695
689
  }
@@ -727,28 +721,25 @@ error:
727
721
  VALUE Backend_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
728
722
  Backend_t *backend;
729
723
  struct libev_io watcher;
724
+ int fd;
730
725
  rb_io_t *fptr;
731
726
  struct sockaddr *ai_addr;
732
727
  int ai_addrlen;
733
728
  VALUE switchpoint_result = Qnil;
734
- VALUE underlying_sock = rb_ivar_get(sock, ID_ivar_io);
735
729
 
736
730
  ai_addrlen = backend_getaddrinfo(host, port, &ai_addr);
737
731
 
738
- if (underlying_sock != Qnil) sock = underlying_sock;
739
-
740
732
  GetBackend(self, backend);
741
- GetOpenFile(sock, fptr);
742
- io_verify_blocking_mode(fptr, sock, Qfalse);
733
+ fd = fd_from_io(sock, &fptr, 1, 0);
743
734
  watcher.fiber = Qnil;
744
735
 
745
736
  backend->base.op_count++;
746
- int result = connect(fptr->fd, ai_addr, ai_addrlen);
737
+ int result = connect(fd, ai_addr, ai_addrlen);
747
738
  if (result < 0) {
748
739
  int e = errno;
749
740
  if (e != EINPROGRESS) rb_syserr_fail(e, strerror(e));
750
741
 
751
- switchpoint_result = libev_wait_fd_with_watcher(backend, fptr->fd, &watcher, EV_WRITE);
742
+ switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_WRITE);
752
743
 
753
744
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
754
745
  }
@@ -766,30 +757,26 @@ error:
766
757
  VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
767
758
  Backend_t *backend;
768
759
  struct libev_io watcher;
760
+ int fd;
769
761
  rb_io_t *fptr;
770
762
  VALUE switchpoint_result = Qnil;
771
- VALUE underlying_io;
772
763
 
773
764
  struct io_buffer buffer = get_io_buffer(str);
774
765
  long left = buffer.len;
775
766
  int flags_int = NUM2INT(flags);
776
767
 
777
- underlying_io = rb_ivar_get(io, ID_ivar_io);
778
- if (underlying_io != Qnil) io = underlying_io;
779
768
  GetBackend(self, backend);
780
- io = rb_io_get_write_io(io);
781
- GetOpenFile(io, fptr);
782
- io_verify_blocking_mode(fptr, io, Qfalse);
769
+ fd = fd_from_io(io, &fptr, 1, 0);
783
770
  watcher.fiber = Qnil;
784
771
 
785
772
  while (left > 0) {
786
773
  backend->base.op_count++;
787
- ssize_t result = send(fptr->fd, buffer.ptr, left, flags_int);
774
+ ssize_t result = send(fd, buffer.ptr, left, flags_int);
788
775
  if (result < 0) {
789
776
  int e = errno;
790
777
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
791
778
 
792
- switchpoint_result = libev_wait_fd_with_watcher(backend, fptr->fd, &watcher, EV_WRITE);
779
+ switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_WRITE);
793
780
 
794
781
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
795
782
  }
@@ -863,41 +850,30 @@ VALUE libev_wait_rw_fd_with_watcher(Backend_t *backend, int r_fd, int w_fd, stru
863
850
  return switchpoint_result;
864
851
  }
865
852
 
866
-
867
-
868
-
869
853
  #ifdef POLYPHONY_LINUX
870
854
  VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
871
855
  Backend_t *backend;
872
856
  struct libev_rw_io watcher;
873
857
  VALUE switchpoint_result = Qnil;
874
- VALUE underlying_io;
858
+ int src_fd;
859
+ int dest_fd;
875
860
  rb_io_t *src_fptr;
876
861
  rb_io_t *dest_fptr;
877
862
  int len;
878
863
 
879
864
  GetBackend(self, backend);
880
-
881
- underlying_io = rb_ivar_get(src, ID_ivar_io);
882
- if (underlying_io != Qnil) src = underlying_io;
883
- GetOpenFile(src, src_fptr);
884
- io_verify_blocking_mode(src_fptr, src, Qfalse);
885
-
886
- underlying_io = rb_ivar_get(dest, ID_ivar_io);
887
- if (underlying_io != Qnil) dest = underlying_io;
888
- dest = rb_io_get_write_io(dest);
889
- GetOpenFile(dest, dest_fptr);
890
- io_verify_blocking_mode(dest_fptr, dest, Qfalse);
891
-
865
+ src_fd = fd_from_io(src, &src_fptr, 0, 0);
866
+ dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
892
867
  watcher.ctx.fiber = Qnil;
868
+
893
869
  while (1) {
894
870
  backend->base.op_count++;
895
- len = splice(src_fptr->fd, 0, dest_fptr->fd, 0, NUM2INT(maxlen), 0);
871
+ len = splice(src_fd, 0, dest_fd, 0, NUM2INT(maxlen), 0);
896
872
  if (len < 0) {
897
873
  int e = errno;
898
874
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
899
875
 
900
- switchpoint_result = libev_wait_rw_fd_with_watcher(backend, src_fptr->fd, dest_fptr->fd, &watcher);
876
+ switchpoint_result = libev_wait_rw_fd_with_watcher(backend, src_fd, dest_fd, &watcher);
901
877
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
902
878
  }
903
879
  else {
@@ -922,34 +898,26 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
922
898
  Backend_t *backend;
923
899
  struct libev_rw_io watcher;
924
900
  VALUE switchpoint_result = Qnil;
925
- VALUE underlying_io;
901
+ int src_fd;
902
+ int dest_fd;
926
903
  rb_io_t *src_fptr;
927
904
  rb_io_t *dest_fptr;
928
905
  int len;
929
906
  int total = 0;
930
907
 
931
908
  GetBackend(self, backend);
932
-
933
- underlying_io = rb_ivar_get(src, ID_ivar_io);
934
- if (underlying_io != Qnil) src = underlying_io;
935
- GetOpenFile(src, src_fptr);
936
- io_verify_blocking_mode(src_fptr, src, Qfalse);
937
-
938
- underlying_io = rb_ivar_get(dest, ID_ivar_io);
939
- if (underlying_io != Qnil) dest = underlying_io;
940
- dest = rb_io_get_write_io(dest);
941
- GetOpenFile(dest, dest_fptr);
942
- io_verify_blocking_mode(dest_fptr, dest, Qfalse);
943
-
909
+ src_fd = fd_from_io(src, &src_fptr, 0, 0);
910
+ dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
944
911
  watcher.ctx.fiber = Qnil;
912
+
945
913
  while (1) {
946
914
  backend->base.op_count++;
947
- len = splice(src_fptr->fd, 0, dest_fptr->fd, 0, NUM2INT(maxlen), 0);
915
+ len = splice(src_fd, 0, dest_fd, 0, NUM2INT(maxlen), 0);
948
916
  if (len < 0) {
949
917
  int e = errno;
950
918
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
951
919
 
952
- switchpoint_result = libev_wait_rw_fd_with_watcher(backend, src_fptr->fd, dest_fptr->fd, &watcher);
920
+ switchpoint_result = libev_wait_rw_fd_with_watcher(backend, src_fd, dest_fd, &watcher);
953
921
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
954
922
  }
955
923
  else if (len == 0) {
@@ -972,12 +940,58 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
972
940
  error:
973
941
  return RAISE_EXCEPTION(switchpoint_result);
974
942
  }
943
+
944
+ VALUE Backend_tee(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
945
+ Backend_t *backend;
946
+ struct libev_rw_io watcher;
947
+ VALUE switchpoint_result = Qnil;
948
+ int src_fd;
949
+ int dest_fd;
950
+ rb_io_t *src_fptr;
951
+ rb_io_t *dest_fptr;
952
+ int len;
953
+
954
+ GetBackend(self, backend);
955
+ src_fd = fd_from_io(src, &src_fptr, 0, 0);
956
+ dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
957
+ watcher.ctx.fiber = Qnil;
958
+
959
+ while (1) {
960
+ backend->base.op_count++;
961
+ len = tee(src_fd, dest_fd, NUM2INT(maxlen), 0);
962
+ if (len < 0) {
963
+ int e = errno;
964
+ if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
965
+
966
+ switchpoint_result = libev_wait_rw_fd_with_watcher(backend, src_fd, dest_fd, &watcher);
967
+ if (TEST_EXCEPTION(switchpoint_result)) goto error;
968
+ }
969
+ else {
970
+ break;
971
+ }
972
+ }
973
+
974
+ if (watcher.ctx.fiber == Qnil) {
975
+ switchpoint_result = backend_snooze(&backend->base);
976
+ if (TEST_EXCEPTION(switchpoint_result)) goto error;
977
+ }
978
+
979
+ RB_GC_GUARD(watcher.ctx.fiber);
980
+ RB_GC_GUARD(switchpoint_result);
981
+
982
+ return INT2NUM(len);
983
+ error:
984
+ return RAISE_EXCEPTION(switchpoint_result);
985
+ }
986
+
975
987
  #else
988
+
976
989
  VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
977
990
  Backend_t *backend;
978
991
  struct libev_io watcher;
979
992
  VALUE switchpoint_result = Qnil;
980
- VALUE underlying_io;
993
+ int src_fd;
994
+ int dest_fd;
981
995
  rb_io_t *src_fptr;
982
996
  rb_io_t *dest_fptr;
983
997
  int len = NUM2INT(maxlen);
@@ -987,28 +1001,18 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
987
1001
  int total = 0;
988
1002
 
989
1003
  GetBackend(self, backend);
990
-
991
- underlying_io = rb_ivar_get(src, ID_ivar_io);
992
- if (underlying_io != Qnil) src = underlying_io;
993
- GetOpenFile(src, src_fptr);
994
- io_verify_blocking_mode(src_fptr, src, Qfalse);
995
-
996
- underlying_io = rb_ivar_get(dest, ID_ivar_io);
997
- if (underlying_io != Qnil) dest = underlying_io;
998
- dest = rb_io_get_write_io(dest);
999
- GetOpenFile(dest, dest_fptr);
1000
- io_verify_blocking_mode(dest_fptr, dest, Qfalse);
1001
-
1004
+ src_fd = fd_from_io(src, &src_fptr, 0, 0);
1005
+ dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
1002
1006
  watcher.fiber = Qnil;
1003
1007
 
1004
1008
  while (1) {
1005
1009
  backend->base.op_count++;
1006
- ssize_t n = read(src_fptr->fd, buf, len);
1010
+ ssize_t n = read(src_fd, buf, len);
1007
1011
  if (n < 0) {
1008
1012
  int e = errno;
1009
1013
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
1010
1014
 
1011
- switchpoint_result = libev_wait_fd_with_watcher(backend, src_fptr->fd, &watcher, EV_READ);
1015
+ switchpoint_result = libev_wait_fd_with_watcher(backend, src_fd, &watcher, EV_READ);
1012
1016
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
1013
1017
  }
1014
1018
  else {
@@ -1019,12 +1023,12 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
1019
1023
 
1020
1024
  while (left > 0) {
1021
1025
  backend->base.op_count++;
1022
- ssize_t n = write(dest_fptr->fd, buf, left);
1026
+ ssize_t n = write(dest_fd, buf, left);
1023
1027
  if (n < 0) {
1024
1028
  int e = errno;
1025
1029
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
1026
1030
 
1027
- switchpoint_result = libev_wait_fd_with_watcher(backend, dest_fptr->fd, &watcher, EV_WRITE);
1031
+ switchpoint_result = libev_wait_fd_with_watcher(backend, dest_fd, &watcher, EV_WRITE);
1028
1032
 
1029
1033
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
1030
1034
  }
@@ -1052,7 +1056,8 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
1052
1056
  Backend_t *backend;
1053
1057
  struct libev_io watcher;
1054
1058
  VALUE switchpoint_result = Qnil;
1055
- VALUE underlying_io;
1059
+ int src_fd;
1060
+ int dest_fd;
1056
1061
  rb_io_t *src_fptr;
1057
1062
  rb_io_t *dest_fptr;
1058
1063
  int len = NUM2INT(maxlen);
@@ -1062,30 +1067,20 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
1062
1067
  int total = 0;
1063
1068
 
1064
1069
  GetBackend(self, backend);
1065
-
1066
- underlying_io = rb_ivar_get(src, ID_ivar_io);
1067
- if (underlying_io != Qnil) src = underlying_io;
1068
- GetOpenFile(src, src_fptr);
1069
- io_verify_blocking_mode(src_fptr, src, Qfalse);
1070
-
1071
- underlying_io = rb_ivar_get(dest, ID_ivar_io);
1072
- if (underlying_io != Qnil) dest = underlying_io;
1073
- dest = rb_io_get_write_io(dest);
1074
- GetOpenFile(dest, dest_fptr);
1075
- io_verify_blocking_mode(dest_fptr, dest, Qfalse);
1076
-
1070
+ src_fd = fd_from_io(src, &src_fptr, 0, 0);
1071
+ dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
1077
1072
  watcher.fiber = Qnil;
1078
1073
 
1079
1074
  while (1) {
1080
1075
  char *ptr = buf;
1081
1076
  while (1) {
1082
1077
  backend->base.op_count++;
1083
- ssize_t n = read(src_fptr->fd, ptr, len);
1078
+ ssize_t n = read(src_fd, ptr, len);
1084
1079
  if (n < 0) {
1085
1080
  int e = errno;
1086
1081
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
1087
1082
 
1088
- switchpoint_result = libev_wait_fd_with_watcher(backend, src_fptr->fd, &watcher, EV_READ);
1083
+ switchpoint_result = libev_wait_fd_with_watcher(backend, src_fd, &watcher, EV_READ);
1089
1084
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
1090
1085
  }
1091
1086
  else if (n == 0) goto done;
@@ -1098,12 +1093,12 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
1098
1093
 
1099
1094
  while (left > 0) {
1100
1095
  backend->base.op_count++;
1101
- ssize_t n = write(dest_fptr->fd, ptr, left);
1096
+ ssize_t n = write(dest_fd, ptr, left);
1102
1097
  if (n < 0) {
1103
1098
  int e = errno;
1104
1099
  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
1105
1100
 
1106
- switchpoint_result = libev_wait_fd_with_watcher(backend, dest_fptr->fd, &watcher, EV_WRITE);
1101
+ switchpoint_result = libev_wait_fd_with_watcher(backend, dest_fd, &watcher, EV_WRITE);
1107
1102
  if (TEST_EXCEPTION(switchpoint_result)) goto error;
1108
1103
  }
1109
1104
  else {
@@ -1131,15 +1126,15 @@ error:
1131
1126
 
1132
1127
  VALUE Backend_wait_io(VALUE self, VALUE io, VALUE write) {
1133
1128
  Backend_t *backend;
1129
+ int fd;
1134
1130
  rb_io_t *fptr;
1135
- int events = RTEST(write) ? EV_WRITE : EV_READ;
1136
- VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
1137
- if (underlying_io != Qnil) io = underlying_io;
1131
+ int write_mode = RTEST(write);
1132
+ int events = write_mode ? EV_WRITE : EV_READ;
1138
1133
  GetBackend(self, backend);
1139
- GetOpenFile(io, fptr);
1134
+ fd = fd_from_io(io, &fptr, write_mode, 0);
1140
1135
 
1141
1136
  backend->base.op_count++;
1142
- return libev_wait_fd(backend, fptr->fd, events, 1);
1137
+ return libev_wait_fd(backend, fd, events, 1);
1143
1138
  }
1144
1139
 
1145
1140
  struct libev_timer {
@@ -1486,19 +1481,13 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1486
1481
  int err = 0;
1487
1482
  VALUE result = Qnil;
1488
1483
 
1484
+ int src_fd;
1485
+ int dest_fd;
1489
1486
  rb_io_t *src_fptr;
1490
1487
  rb_io_t *dest_fptr;
1491
1488
 
1492
- VALUE underlying_io = rb_ivar_get(src, ID_ivar_io);
1493
- if (underlying_io != Qnil) src = underlying_io;
1494
- GetOpenFile(src, src_fptr);
1495
- io_verify_blocking_mode(src_fptr, src, Qfalse);
1496
-
1497
- underlying_io = rb_ivar_get(dest, ID_ivar_io);
1498
- if (underlying_io != Qnil) dest = underlying_io;
1499
- dest = rb_io_get_write_io(dest);
1500
- GetOpenFile(dest, dest_fptr);
1501
- io_verify_blocking_mode(dest_fptr, dest, Qfalse);
1489
+ src_fd = fd_from_io(src, &src_fptr, 0, 0);
1490
+ dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
1502
1491
 
1503
1492
  struct libev_rw_io watcher;
1504
1493
  watcher.ctx.fiber = Qnil;
@@ -1516,12 +1505,12 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1516
1505
  fcntl(pipefd[1], F_SETFL, O_NONBLOCK);
1517
1506
 
1518
1507
  if (prefix != Qnil) {
1519
- err = splice_chunks_write(backend, dest_fptr->fd, prefix, &watcher, &result);
1508
+ err = splice_chunks_write(backend, dest_fd, prefix, &watcher, &result);
1520
1509
  if (err == -1) goto error; else if (err) goto syscallerror;
1521
1510
  }
1522
1511
  while (1) {
1523
1512
  int chunk_len = 0;
1524
- err = splice_chunks_splice(backend, src_fptr->fd, pipefd[1], maxlen, &watcher, &result, &chunk_len);
1513
+ err = splice_chunks_splice(backend, src_fd, pipefd[1], maxlen, &watcher, &result, &chunk_len);
1525
1514
  if (err == -1) goto error; else if (err) goto syscallerror;
1526
1515
  if (chunk_len == 0) break;
1527
1516
 
@@ -1530,14 +1519,14 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1530
1519
 
1531
1520
  if (chunk_prefix != Qnil) {
1532
1521
  VALUE str = (TYPE(chunk_prefix) == T_STRING) ? chunk_prefix : rb_funcall(chunk_prefix, ID_call, 1, chunk_len_value);
1533
- int err = splice_chunks_write(backend, dest_fptr->fd, str, &watcher, &result);
1522
+ int err = splice_chunks_write(backend, dest_fd, str, &watcher, &result);
1534
1523
  if (err == -1) goto error; else if (err) goto syscallerror;
1535
1524
  }
1536
1525
 
1537
1526
  int left = chunk_len;
1538
1527
  while (left > 0) {
1539
1528
  int len;
1540
- err = splice_chunks_splice(backend, pipefd[0], dest_fptr->fd, left, &watcher, &result, &len);
1529
+ err = splice_chunks_splice(backend, pipefd[0], dest_fd, left, &watcher, &result, &len);
1541
1530
  if (err == -1) goto error; else if (err) goto syscallerror;
1542
1531
 
1543
1532
  left -= len;
@@ -1545,13 +1534,13 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
1545
1534
 
1546
1535
  if (chunk_postfix != Qnil) {
1547
1536
  VALUE str = (TYPE(chunk_postfix) == T_STRING) ? chunk_postfix : rb_funcall(chunk_postfix, ID_call, 1, chunk_len_value);
1548
- int err = splice_chunks_write(backend, dest_fptr->fd, str, &watcher, &result);
1537
+ int err = splice_chunks_write(backend, dest_fd, str, &watcher, &result);
1549
1538
  if (err == -1) goto error; else if (err) goto syscallerror;
1550
1539
  }
1551
1540
  }
1552
1541
 
1553
1542
  if (postfix != Qnil) {
1554
- int err = splice_chunks_write(backend, dest_fptr->fd, postfix, &watcher, &result);
1543
+ int err = splice_chunks_write(backend, dest_fd, postfix, &watcher, &result);
1555
1544
  if (err == -1) goto error; else if (err) goto syscallerror;
1556
1545
  }
1557
1546