polyphony 0.82 → 0.83
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|