polyphony 0.82 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/ext/polyphony/backend_common.c +15 -10
- data/ext/polyphony/backend_common.h +5 -4
- data/ext/polyphony/backend_io_uring.c +86 -151
- data/ext/polyphony/backend_libev.c +103 -159
- data/ext/polyphony/extconf.rb +3 -1
- data/ext/polyphony/io_extensions.c +440 -0
- data/ext/polyphony/pipe.c +109 -0
- data/ext/polyphony/polyphony.h +5 -0
- data/ext/polyphony/polyphony_ext.c +7 -2
- data/ext/polyphony/zlib_conf.rb +119 -0
- data/lib/polyphony/extensions/io.rb +10 -2
- data/lib/polyphony/extensions/pipe.rb +167 -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 +332 -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 -2
@@ -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) {
|
@@ -977,7 +945,8 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
977
945
|
Backend_t *backend;
|
978
946
|
struct libev_io watcher;
|
979
947
|
VALUE switchpoint_result = Qnil;
|
980
|
-
|
948
|
+
int src_fd;
|
949
|
+
int dest_fd;
|
981
950
|
rb_io_t *src_fptr;
|
982
951
|
rb_io_t *dest_fptr;
|
983
952
|
int len = NUM2INT(maxlen);
|
@@ -987,28 +956,18 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
987
956
|
int total = 0;
|
988
957
|
|
989
958
|
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
|
-
|
959
|
+
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
960
|
+
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
1002
961
|
watcher.fiber = Qnil;
|
1003
962
|
|
1004
963
|
while (1) {
|
1005
964
|
backend->base.op_count++;
|
1006
|
-
ssize_t n = read(
|
965
|
+
ssize_t n = read(src_fd, buf, len);
|
1007
966
|
if (n < 0) {
|
1008
967
|
int e = errno;
|
1009
968
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
1010
969
|
|
1011
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
970
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, src_fd, &watcher, EV_READ);
|
1012
971
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1013
972
|
}
|
1014
973
|
else {
|
@@ -1019,12 +978,12 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1019
978
|
|
1020
979
|
while (left > 0) {
|
1021
980
|
backend->base.op_count++;
|
1022
|
-
ssize_t n = write(
|
981
|
+
ssize_t n = write(dest_fd, buf, left);
|
1023
982
|
if (n < 0) {
|
1024
983
|
int e = errno;
|
1025
984
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
1026
985
|
|
1027
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
986
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, dest_fd, &watcher, EV_WRITE);
|
1028
987
|
|
1029
988
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1030
989
|
}
|
@@ -1052,7 +1011,8 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1052
1011
|
Backend_t *backend;
|
1053
1012
|
struct libev_io watcher;
|
1054
1013
|
VALUE switchpoint_result = Qnil;
|
1055
|
-
|
1014
|
+
int src_fd;
|
1015
|
+
int dest_fd;
|
1056
1016
|
rb_io_t *src_fptr;
|
1057
1017
|
rb_io_t *dest_fptr;
|
1058
1018
|
int len = NUM2INT(maxlen);
|
@@ -1062,30 +1022,20 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1062
1022
|
int total = 0;
|
1063
1023
|
|
1064
1024
|
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
|
-
|
1025
|
+
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
1026
|
+
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
1077
1027
|
watcher.fiber = Qnil;
|
1078
1028
|
|
1079
1029
|
while (1) {
|
1080
1030
|
char *ptr = buf;
|
1081
1031
|
while (1) {
|
1082
1032
|
backend->base.op_count++;
|
1083
|
-
ssize_t n = read(
|
1033
|
+
ssize_t n = read(src_fd, ptr, len);
|
1084
1034
|
if (n < 0) {
|
1085
1035
|
int e = errno;
|
1086
1036
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
1087
1037
|
|
1088
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
1038
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, src_fd, &watcher, EV_READ);
|
1089
1039
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1090
1040
|
}
|
1091
1041
|
else if (n == 0) goto done;
|
@@ -1098,12 +1048,12 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1098
1048
|
|
1099
1049
|
while (left > 0) {
|
1100
1050
|
backend->base.op_count++;
|
1101
|
-
ssize_t n = write(
|
1051
|
+
ssize_t n = write(dest_fd, ptr, left);
|
1102
1052
|
if (n < 0) {
|
1103
1053
|
int e = errno;
|
1104
1054
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
1105
1055
|
|
1106
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
1056
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, dest_fd, &watcher, EV_WRITE);
|
1107
1057
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1108
1058
|
}
|
1109
1059
|
else {
|
@@ -1131,15 +1081,15 @@ error:
|
|
1131
1081
|
|
1132
1082
|
VALUE Backend_wait_io(VALUE self, VALUE io, VALUE write) {
|
1133
1083
|
Backend_t *backend;
|
1084
|
+
int fd;
|
1134
1085
|
rb_io_t *fptr;
|
1135
|
-
int
|
1136
|
-
|
1137
|
-
if (underlying_io != Qnil) io = underlying_io;
|
1086
|
+
int write_mode = RTEST(write);
|
1087
|
+
int events = write_mode ? EV_WRITE : EV_READ;
|
1138
1088
|
GetBackend(self, backend);
|
1139
|
-
|
1089
|
+
fd = fd_from_io(io, &fptr, write_mode, 0);
|
1140
1090
|
|
1141
1091
|
backend->base.op_count++;
|
1142
|
-
return libev_wait_fd(backend,
|
1092
|
+
return libev_wait_fd(backend, fd, events, 1);
|
1143
1093
|
}
|
1144
1094
|
|
1145
1095
|
struct libev_timer {
|
@@ -1486,19 +1436,13 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1486
1436
|
int err = 0;
|
1487
1437
|
VALUE result = Qnil;
|
1488
1438
|
|
1439
|
+
int src_fd;
|
1440
|
+
int dest_fd;
|
1489
1441
|
rb_io_t *src_fptr;
|
1490
1442
|
rb_io_t *dest_fptr;
|
1491
1443
|
|
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);
|
1444
|
+
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
1445
|
+
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
1502
1446
|
|
1503
1447
|
struct libev_rw_io watcher;
|
1504
1448
|
watcher.ctx.fiber = Qnil;
|
@@ -1516,12 +1460,12 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1516
1460
|
fcntl(pipefd[1], F_SETFL, O_NONBLOCK);
|
1517
1461
|
|
1518
1462
|
if (prefix != Qnil) {
|
1519
|
-
err = splice_chunks_write(backend,
|
1463
|
+
err = splice_chunks_write(backend, dest_fd, prefix, &watcher, &result);
|
1520
1464
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1521
1465
|
}
|
1522
1466
|
while (1) {
|
1523
1467
|
int chunk_len = 0;
|
1524
|
-
err = splice_chunks_splice(backend,
|
1468
|
+
err = splice_chunks_splice(backend, src_fd, pipefd[1], maxlen, &watcher, &result, &chunk_len);
|
1525
1469
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1526
1470
|
if (chunk_len == 0) break;
|
1527
1471
|
|
@@ -1530,14 +1474,14 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1530
1474
|
|
1531
1475
|
if (chunk_prefix != Qnil) {
|
1532
1476
|
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,
|
1477
|
+
int err = splice_chunks_write(backend, dest_fd, str, &watcher, &result);
|
1534
1478
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1535
1479
|
}
|
1536
1480
|
|
1537
1481
|
int left = chunk_len;
|
1538
1482
|
while (left > 0) {
|
1539
1483
|
int len;
|
1540
|
-
err = splice_chunks_splice(backend, pipefd[0],
|
1484
|
+
err = splice_chunks_splice(backend, pipefd[0], dest_fd, left, &watcher, &result, &len);
|
1541
1485
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1542
1486
|
|
1543
1487
|
left -= len;
|
@@ -1545,13 +1489,13 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1545
1489
|
|
1546
1490
|
if (chunk_postfix != Qnil) {
|
1547
1491
|
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,
|
1492
|
+
int err = splice_chunks_write(backend, dest_fd, str, &watcher, &result);
|
1549
1493
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1550
1494
|
}
|
1551
1495
|
}
|
1552
1496
|
|
1553
1497
|
if (postfix != Qnil) {
|
1554
|
-
int err = splice_chunks_write(backend,
|
1498
|
+
int err = splice_chunks_write(backend, dest_fd, postfix, &watcher, &result);
|
1555
1499
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1556
1500
|
}
|
1557
1501
|
|
data/ext/polyphony/extconf.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'mkmf'
|
5
5
|
|
6
|
+
dir_config 'polyphony_ext'
|
6
7
|
|
7
8
|
KERNEL_INFO_RE = /Linux (\d)\.(\d+)\.(?:\d+)\-(?:\d+\-)?(\w+)/
|
8
9
|
def get_config
|
@@ -25,6 +26,8 @@ end
|
|
25
26
|
config = get_config
|
26
27
|
puts "Building Polyphony... (#{config.inspect})"
|
27
28
|
|
29
|
+
require_relative 'zlib_conf'
|
30
|
+
|
28
31
|
$defs << '-DPOLYPHONY_USE_PIDFD_OPEN' if config[:pidfd_open]
|
29
32
|
if config[:io_uring]
|
30
33
|
$defs << "-DPOLYPHONY_BACKEND_LIBURING"
|
@@ -53,5 +56,4 @@ CONFIG['optflags'] << ' -fno-strict-aliasing' unless RUBY_PLATFORM =~ /mswin/
|
|
53
56
|
|
54
57
|
have_func('rb_fiber_transfer', 'ruby.h')
|
55
58
|
|
56
|
-
dir_config 'polyphony_ext'
|
57
59
|
create_makefile 'polyphony_ext'
|