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.
- checksums.yaml +4 -4
- data/.gitmodules +3 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +14 -0
- data/ext/polyphony/backend_common.c +15 -10
- data/ext/polyphony/backend_common.h +5 -4
- data/ext/polyphony/backend_io_uring.c +128 -157
- data/ext/polyphony/backend_libev.c +148 -159
- data/ext/polyphony/extconf.rb +20 -1
- data/ext/polyphony/io_extensions.c +440 -0
- data/ext/polyphony/pipe.c +109 -0
- data/ext/polyphony/polyphony.c +5 -0
- data/ext/polyphony/polyphony.h +6 -0
- data/ext/polyphony/polyphony_ext.c +7 -2
- data/ext/polyphony/zlib_conf.rb +119 -0
- data/lib/polyphony/extensions/io.rb +20 -2
- data/lib/polyphony/extensions/pipe.rb +171 -0
- data/lib/polyphony/extensions.rb +1 -0
- data/lib/polyphony/version.rb +1 -1
- data/lib/polyphony.rb +4 -0
- data/test/helper.rb +4 -0
- data/test/test_backend.rb +3 -48
- data/test/test_global_api.rb +23 -23
- data/test/test_io.rb +391 -0
- data/test/test_pipe.rb +41 -0
- data/test/test_process_supervision.rb +1 -1
- data/test/test_socket.rb +1 -0
- metadata +7 -13
- data/ext/liburing/liburing/README.md +0 -4
- data/ext/liburing/liburing/barrier.h +0 -73
- data/ext/liburing/liburing/compat.h +0 -15
- data/ext/liburing/liburing/io_uring.h +0 -343
- data/ext/liburing/liburing.h +0 -585
- data/ext/liburing/queue.c +0 -333
- data/ext/liburing/register.c +0 -187
- data/ext/liburing/setup.c +0 -210
- data/ext/liburing/syscall.c +0 -54
- data/ext/liburing/syscall.h +0 -18
- data/ext/polyphony/liburing.c +0 -8
@@ -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
|
-
|
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(
|
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,
|
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
|
-
|
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(
|
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,
|
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
|
-
|
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(
|
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,
|
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
|
-
|
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(
|
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,
|
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
|
-
|
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(
|
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,
|
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
|
-
|
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
|
-
|
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(
|
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,
|
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
|
-
|
672
|
-
|
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
|
-
|
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(
|
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,
|
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
|
-
|
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(
|
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,
|
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
|
-
|
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(
|
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,
|
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
|
-
|
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
|
-
|
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(
|
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,
|
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
|
-
|
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
|
-
|
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(
|
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,
|
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
|
-
|
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
|
-
|
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(
|
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,
|
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(
|
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,
|
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
|
-
|
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
|
-
|
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(
|
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,
|
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(
|
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,
|
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
|
1136
|
-
|
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
|
-
|
1134
|
+
fd = fd_from_io(io, &fptr, write_mode, 0);
|
1140
1135
|
|
1141
1136
|
backend->base.op_count++;
|
1142
|
-
return libev_wait_fd(backend,
|
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
|
-
|
1493
|
-
|
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,
|
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,
|
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,
|
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],
|
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,
|
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,
|
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
|
|