polyphony 0.81 → 0.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +1 -1
- data/CHANGELOG.md +15 -0
- data/Gemfile.lock +1 -1
- data/bin/test +1 -1
- data/examples/core/raw_buffer_test.rb +8 -0
- data/examples/core/zlib_stream.rb +2 -1
- data/ext/polyphony/backend_common.c +33 -10
- data/ext/polyphony/backend_common.h +20 -3
- data/ext/polyphony/backend_io_uring.c +143 -216
- data/ext/polyphony/backend_libev.c +167 -197
- data/ext/polyphony/extconf.rb +4 -2
- data/ext/polyphony/io_extensions.c +440 -0
- data/ext/polyphony/pipe.c +109 -0
- data/ext/polyphony/polyphony.c +45 -1
- data/ext/polyphony/polyphony.h +5 -11
- 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 +367 -0
- data/test/test_pipe.rb +41 -0
- data/test/test_process_supervision.rb +1 -1
- data/test/test_raw_buffer.rb +37 -0
- data/test/test_socket.rb +50 -0
- metadata +9 -2
@@ -266,41 +266,74 @@ 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
|
-
|
274
|
-
|
292
|
+
|
293
|
+
struct io_buffer buffer = get_io_buffer(str);
|
275
294
|
long buf_pos = NUM2INT(pos);
|
276
|
-
|
277
|
-
|
278
|
-
if (buf_pos < 0 || buf_pos > current_len) buf_pos = current_len;
|
279
|
-
}
|
280
|
-
else buf_pos = 0;
|
281
|
-
int shrinkable = io_setstrbuf(&str, buf_pos + len);
|
282
|
-
char *buf = RSTRING_PTR(str) + buf_pos;
|
295
|
+
int shrinkable_string = 0;
|
296
|
+
int expandable_buffer = 0;
|
283
297
|
long total = 0;
|
284
298
|
VALUE switchpoint_result = Qnil;
|
285
299
|
int read_to_eof = RTEST(to_eof);
|
286
|
-
|
300
|
+
|
301
|
+
if (buffer.raw) {
|
302
|
+
if (buf_pos < 0 || buf_pos > buffer.len) buf_pos = buffer.len;
|
303
|
+
buffer.ptr += buf_pos;
|
304
|
+
buffer.len -= buf_pos;
|
305
|
+
}
|
306
|
+
else {
|
307
|
+
expandable_buffer = length == Qnil;
|
308
|
+
long expected_read_length = expandable_buffer ? 4096 : FIX2INT(length);
|
309
|
+
long string_cap = rb_str_capacity(str);
|
310
|
+
if (buf_pos < 0 || buf_pos > buffer.len) buf_pos = buffer.len;
|
311
|
+
|
312
|
+
if (string_cap < expected_read_length + buf_pos) {
|
313
|
+
shrinkable_string = io_setstrbuf(&str, expected_read_length + buf_pos);
|
314
|
+
buffer.ptr = RSTRING_PTR(str) + buf_pos;
|
315
|
+
buffer.len = expected_read_length;
|
316
|
+
}
|
317
|
+
else {
|
318
|
+
buffer.ptr += buf_pos;
|
319
|
+
buffer.len = string_cap - buf_pos;
|
320
|
+
if (buffer.len > expected_read_length)
|
321
|
+
buffer.len = expected_read_length;
|
322
|
+
}
|
323
|
+
}
|
287
324
|
|
288
325
|
GetBackend(self, backend);
|
289
|
-
|
290
|
-
GetOpenFile(io, fptr);
|
291
|
-
rb_io_check_byte_readable(fptr);
|
292
|
-
io_verify_blocking_mode(fptr, io, Qfalse);
|
293
|
-
rectify_io_file_pos(fptr);
|
326
|
+
fd = fd_from_io(io, &fptr, 0, 1);
|
294
327
|
watcher.fiber = Qnil;
|
295
328
|
|
296
329
|
while (1) {
|
297
330
|
backend->base.op_count++;
|
298
|
-
ssize_t
|
299
|
-
if (
|
331
|
+
ssize_t result = read(fd, buffer.ptr, buffer.len);
|
332
|
+
if (result < 0) {
|
300
333
|
int e = errno;
|
301
334
|
if (e != EWOULDBLOCK && e != EAGAIN) rb_syserr_fail(e, strerror(e));
|
302
335
|
|
303
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
336
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_READ);
|
304
337
|
|
305
338
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
306
339
|
}
|
@@ -308,32 +341,39 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof,
|
|
308
341
|
switchpoint_result = backend_snooze(&backend->base);
|
309
342
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
310
343
|
|
311
|
-
if (
|
312
|
-
|
344
|
+
if (!result) break; // EOF
|
345
|
+
|
346
|
+
total += result;
|
313
347
|
if (!read_to_eof) break;
|
314
348
|
|
315
|
-
if (
|
316
|
-
if (!
|
349
|
+
if (result == buffer.len) {
|
350
|
+
if (!expandable_buffer) break;
|
317
351
|
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
352
|
+
// resize buffer to double its capacity
|
353
|
+
rb_str_resize(str, total + buf_pos);
|
354
|
+
rb_str_modify_expand(str, rb_str_capacity(str));
|
355
|
+
shrinkable_string = 0;
|
356
|
+
buffer.ptr = RSTRING_PTR(str) + total + buf_pos;
|
357
|
+
buffer.len = rb_str_capacity(str) - total - buf_pos;
|
358
|
+
}
|
359
|
+
else {
|
360
|
+
buffer.ptr += result;
|
361
|
+
buffer.len -= result;
|
362
|
+
if (!buffer.len) break;
|
323
363
|
}
|
324
|
-
else buf += n;
|
325
364
|
}
|
326
365
|
}
|
327
366
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
367
|
+
if (!buffer.raw) {
|
368
|
+
io_set_read_length(str, buf_pos + total, shrinkable_string);
|
369
|
+
if (fptr) io_enc_str(str, fptr);
|
370
|
+
}
|
371
|
+
if (!total) return Qnil;
|
332
372
|
|
333
373
|
RB_GC_GUARD(watcher.fiber);
|
334
374
|
RB_GC_GUARD(switchpoint_result);
|
335
375
|
|
336
|
-
return str;
|
376
|
+
return buffer.raw ? INT2FIX(total) : str;
|
337
377
|
error:
|
338
378
|
return RAISE_EXCEPTION(switchpoint_result);
|
339
379
|
}
|
@@ -345,6 +385,7 @@ VALUE Backend_recv(VALUE self, VALUE io, VALUE str, VALUE length, VALUE pos) {
|
|
345
385
|
VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
|
346
386
|
Backend_t *backend;
|
347
387
|
struct libev_io watcher;
|
388
|
+
int fd;
|
348
389
|
rb_io_t *fptr;
|
349
390
|
VALUE str;
|
350
391
|
long total;
|
@@ -352,26 +393,21 @@ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
|
|
352
393
|
int shrinkable;
|
353
394
|
char *buf;
|
354
395
|
VALUE switchpoint_result = Qnil;
|
355
|
-
VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
|
356
396
|
|
357
397
|
READ_LOOP_PREPARE_STR();
|
358
398
|
|
359
399
|
GetBackend(self, backend);
|
360
|
-
|
361
|
-
GetOpenFile(io, fptr);
|
362
|
-
rb_io_check_byte_readable(fptr);
|
363
|
-
io_verify_blocking_mode(fptr, io, Qfalse);
|
364
|
-
rectify_io_file_pos(fptr);
|
400
|
+
fd = fd_from_io(io, &fptr, 0, 1);
|
365
401
|
watcher.fiber = Qnil;
|
366
402
|
|
367
403
|
while (1) {
|
368
404
|
backend->base.op_count++;
|
369
|
-
ssize_t n = read(
|
405
|
+
ssize_t n = read(fd, buf, len);
|
370
406
|
if (n < 0) {
|
371
407
|
int e = errno;
|
372
408
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
373
409
|
|
374
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
410
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_READ);
|
375
411
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
376
412
|
}
|
377
413
|
else {
|
@@ -397,6 +433,7 @@ error:
|
|
397
433
|
VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
|
398
434
|
Backend_t *backend;
|
399
435
|
struct libev_io watcher;
|
436
|
+
int fd;
|
400
437
|
rb_io_t *fptr;
|
401
438
|
VALUE str;
|
402
439
|
long total;
|
@@ -404,27 +441,22 @@ VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) {
|
|
404
441
|
int shrinkable;
|
405
442
|
char *buf;
|
406
443
|
VALUE switchpoint_result = Qnil;
|
407
|
-
VALUE underlying_io = rb_ivar_get(io, ID_ivar_io);
|
408
444
|
ID method_id = SYM2ID(method);
|
409
445
|
|
410
446
|
READ_LOOP_PREPARE_STR();
|
411
447
|
|
412
448
|
GetBackend(self, backend);
|
413
|
-
|
414
|
-
GetOpenFile(io, fptr);
|
415
|
-
rb_io_check_byte_readable(fptr);
|
416
|
-
io_verify_blocking_mode(fptr, io, Qfalse);
|
417
|
-
rectify_io_file_pos(fptr);
|
449
|
+
fd = fd_from_io(io, &fptr, 0, 1);
|
418
450
|
watcher.fiber = Qnil;
|
419
451
|
|
420
452
|
while (1) {
|
421
453
|
backend->base.op_count++;
|
422
|
-
ssize_t n = read(
|
454
|
+
ssize_t n = read(fd, buf, len);
|
423
455
|
if (n < 0) {
|
424
456
|
int e = errno;
|
425
457
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
426
458
|
|
427
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
459
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_READ);
|
428
460
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
429
461
|
}
|
430
462
|
else {
|
@@ -450,35 +482,31 @@ error:
|
|
450
482
|
VALUE Backend_write(VALUE self, VALUE io, VALUE str) {
|
451
483
|
Backend_t *backend;
|
452
484
|
struct libev_io watcher;
|
485
|
+
int fd;
|
453
486
|
rb_io_t *fptr;
|
454
487
|
VALUE switchpoint_result = Qnil;
|
455
|
-
VALUE underlying_io;
|
456
|
-
char *buf = StringValuePtr(str);
|
457
|
-
long len = RSTRING_LEN(str);
|
458
|
-
long left = len;
|
459
488
|
|
460
|
-
|
461
|
-
|
489
|
+
struct io_buffer buffer = get_io_buffer(str);
|
490
|
+
long left = buffer.len;
|
491
|
+
|
462
492
|
GetBackend(self, backend);
|
463
|
-
|
464
|
-
GetOpenFile(io, fptr);
|
465
|
-
io_verify_blocking_mode(fptr, io, Qfalse);
|
493
|
+
fd = fd_from_io(io, &fptr, 1, 0);
|
466
494
|
watcher.fiber = Qnil;
|
467
495
|
|
468
496
|
while (left > 0) {
|
469
497
|
backend->base.op_count++;
|
470
|
-
ssize_t
|
471
|
-
if (
|
498
|
+
ssize_t result = write(fd, buffer.ptr, left);
|
499
|
+
if (result < 0) {
|
472
500
|
int e = errno;
|
473
501
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
474
502
|
|
475
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
503
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_WRITE);
|
476
504
|
|
477
505
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
478
506
|
}
|
479
507
|
else {
|
480
|
-
|
481
|
-
left -=
|
508
|
+
buffer.ptr += result;
|
509
|
+
left -= result;
|
482
510
|
}
|
483
511
|
}
|
484
512
|
|
@@ -491,7 +519,7 @@ VALUE Backend_write(VALUE self, VALUE io, VALUE str) {
|
|
491
519
|
RB_GC_GUARD(watcher.fiber);
|
492
520
|
RB_GC_GUARD(switchpoint_result);
|
493
521
|
|
494
|
-
return INT2NUM(len);
|
522
|
+
return INT2NUM(buffer.len);
|
495
523
|
error:
|
496
524
|
return RAISE_EXCEPTION(switchpoint_result);
|
497
525
|
}
|
@@ -499,21 +527,17 @@ error:
|
|
499
527
|
VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
|
500
528
|
Backend_t *backend;
|
501
529
|
struct libev_io watcher;
|
530
|
+
int fd;
|
502
531
|
rb_io_t *fptr;
|
503
532
|
VALUE switchpoint_result = Qnil;
|
504
|
-
VALUE underlying_io;
|
505
533
|
long total_length = 0;
|
506
534
|
long total_written = 0;
|
507
535
|
struct iovec *iov = 0;
|
508
536
|
struct iovec *iov_ptr = 0;
|
509
537
|
int iov_count = argc;
|
510
538
|
|
511
|
-
underlying_io = rb_ivar_get(io, ID_ivar_io);
|
512
|
-
if (underlying_io != Qnil) io = underlying_io;
|
513
539
|
GetBackend(self, backend);
|
514
|
-
|
515
|
-
GetOpenFile(io, fptr);
|
516
|
-
io_verify_blocking_mode(fptr, io, Qfalse);
|
540
|
+
fd = fd_from_io(io, &fptr, 1, 0);
|
517
541
|
watcher.fiber = Qnil;
|
518
542
|
|
519
543
|
iov = malloc(iov_count * sizeof(struct iovec));
|
@@ -527,7 +551,7 @@ VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
|
|
527
551
|
|
528
552
|
while (1) {
|
529
553
|
backend->base.op_count++;
|
530
|
-
ssize_t n = writev(
|
554
|
+
ssize_t n = writev(fd, iov_ptr, iov_count);
|
531
555
|
if (n < 0) {
|
532
556
|
int e = errno;
|
533
557
|
if ((e != EWOULDBLOCK && e != EAGAIN)) {
|
@@ -535,7 +559,7 @@ VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) {
|
|
535
559
|
rb_syserr_fail(e, strerror(e));
|
536
560
|
}
|
537
561
|
|
538
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
562
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_WRITE);
|
539
563
|
|
540
564
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
541
565
|
}
|
@@ -585,26 +609,25 @@ VALUE Backend_write_m(int argc, VALUE *argv, VALUE self) {
|
|
585
609
|
VALUE Backend_accept(VALUE self, VALUE server_socket, VALUE socket_class) {
|
586
610
|
Backend_t *backend;
|
587
611
|
struct libev_io watcher;
|
588
|
-
|
612
|
+
int server_fd;
|
613
|
+
rb_io_t *server_fptr;
|
589
614
|
int fd;
|
590
615
|
struct sockaddr addr;
|
591
616
|
socklen_t len = (socklen_t)sizeof addr;
|
592
617
|
VALUE switchpoint_result = Qnil;
|
593
|
-
VALUE underlying_sock = rb_ivar_get(server_socket, ID_ivar_io);
|
594
|
-
if (underlying_sock != Qnil) server_socket = underlying_sock;
|
595
618
|
|
596
619
|
GetBackend(self, backend);
|
597
|
-
|
598
|
-
io_verify_blocking_mode(fptr, server_socket, Qfalse);
|
620
|
+
server_fd = fd_from_io(server_socket, &server_fptr, 0, 0);
|
599
621
|
watcher.fiber = Qnil;
|
622
|
+
|
600
623
|
while (1) {
|
601
624
|
backend->base.op_count++;
|
602
|
-
fd = accept(
|
625
|
+
fd = accept(server_fd, &addr, &len);
|
603
626
|
if (fd < 0) {
|
604
627
|
int e = errno;
|
605
628
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
606
629
|
|
607
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
630
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, server_fd, &watcher, EV_READ);
|
608
631
|
|
609
632
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
610
633
|
}
|
@@ -642,28 +665,25 @@ error:
|
|
642
665
|
VALUE Backend_accept_loop(VALUE self, VALUE server_socket, VALUE socket_class) {
|
643
666
|
Backend_t *backend;
|
644
667
|
struct libev_io watcher;
|
645
|
-
|
646
|
-
|
668
|
+
int server_fd;
|
669
|
+
rb_io_t *server_fptr;
|
647
670
|
struct sockaddr addr;
|
648
671
|
socklen_t len = (socklen_t)sizeof addr;
|
649
672
|
VALUE switchpoint_result = Qnil;
|
650
673
|
VALUE socket = Qnil;
|
651
|
-
VALUE underlying_sock = rb_ivar_get(server_socket, ID_ivar_io);
|
652
|
-
if (underlying_sock != Qnil) server_socket = underlying_sock;
|
653
674
|
|
654
675
|
GetBackend(self, backend);
|
655
|
-
|
656
|
-
io_verify_blocking_mode(fptr, server_socket, Qfalse);
|
676
|
+
server_fd = fd_from_io(server_socket, &server_fptr, 0, 0);
|
657
677
|
watcher.fiber = Qnil;
|
658
678
|
|
659
679
|
while (1) {
|
660
680
|
backend->base.op_count++;
|
661
|
-
fd = accept(
|
681
|
+
int fd = accept(server_fd, &addr, &len);
|
662
682
|
if (fd < 0) {
|
663
683
|
int e = errno;
|
664
684
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
665
685
|
|
666
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
686
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, server_fd, &watcher, EV_READ);
|
667
687
|
|
668
688
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
669
689
|
}
|
@@ -701,28 +721,25 @@ error:
|
|
701
721
|
VALUE Backend_connect(VALUE self, VALUE sock, VALUE host, VALUE port) {
|
702
722
|
Backend_t *backend;
|
703
723
|
struct libev_io watcher;
|
724
|
+
int fd;
|
704
725
|
rb_io_t *fptr;
|
705
726
|
struct sockaddr *ai_addr;
|
706
727
|
int ai_addrlen;
|
707
728
|
VALUE switchpoint_result = Qnil;
|
708
|
-
VALUE underlying_sock = rb_ivar_get(sock, ID_ivar_io);
|
709
729
|
|
710
730
|
ai_addrlen = backend_getaddrinfo(host, port, &ai_addr);
|
711
731
|
|
712
|
-
if (underlying_sock != Qnil) sock = underlying_sock;
|
713
|
-
|
714
732
|
GetBackend(self, backend);
|
715
|
-
|
716
|
-
io_verify_blocking_mode(fptr, sock, Qfalse);
|
733
|
+
fd = fd_from_io(sock, &fptr, 1, 0);
|
717
734
|
watcher.fiber = Qnil;
|
718
735
|
|
719
736
|
backend->base.op_count++;
|
720
|
-
int result = connect(
|
737
|
+
int result = connect(fd, ai_addr, ai_addrlen);
|
721
738
|
if (result < 0) {
|
722
739
|
int e = errno;
|
723
740
|
if (e != EINPROGRESS) rb_syserr_fail(e, strerror(e));
|
724
741
|
|
725
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
742
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_WRITE);
|
726
743
|
|
727
744
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
728
745
|
}
|
@@ -740,36 +757,32 @@ error:
|
|
740
757
|
VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
|
741
758
|
Backend_t *backend;
|
742
759
|
struct libev_io watcher;
|
760
|
+
int fd;
|
743
761
|
rb_io_t *fptr;
|
744
762
|
VALUE switchpoint_result = Qnil;
|
745
|
-
|
746
|
-
|
747
|
-
long
|
748
|
-
long left = len;
|
763
|
+
|
764
|
+
struct io_buffer buffer = get_io_buffer(str);
|
765
|
+
long left = buffer.len;
|
749
766
|
int flags_int = NUM2INT(flags);
|
750
767
|
|
751
|
-
underlying_io = rb_ivar_get(io, ID_ivar_io);
|
752
|
-
if (underlying_io != Qnil) io = underlying_io;
|
753
768
|
GetBackend(self, backend);
|
754
|
-
|
755
|
-
GetOpenFile(io, fptr);
|
756
|
-
io_verify_blocking_mode(fptr, io, Qfalse);
|
769
|
+
fd = fd_from_io(io, &fptr, 1, 0);
|
757
770
|
watcher.fiber = Qnil;
|
758
771
|
|
759
772
|
while (left > 0) {
|
760
773
|
backend->base.op_count++;
|
761
|
-
ssize_t
|
762
|
-
if (
|
774
|
+
ssize_t result = send(fd, buffer.ptr, left, flags_int);
|
775
|
+
if (result < 0) {
|
763
776
|
int e = errno;
|
764
777
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
765
778
|
|
766
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
779
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, fd, &watcher, EV_WRITE);
|
767
780
|
|
768
781
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
769
782
|
}
|
770
783
|
else {
|
771
|
-
|
772
|
-
left -=
|
784
|
+
buffer.ptr += result;
|
785
|
+
left -= result;
|
773
786
|
}
|
774
787
|
}
|
775
788
|
|
@@ -782,7 +795,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) {
|
|
782
795
|
RB_GC_GUARD(watcher.fiber);
|
783
796
|
RB_GC_GUARD(switchpoint_result);
|
784
797
|
|
785
|
-
return INT2NUM(len);
|
798
|
+
return INT2NUM(buffer.len);
|
786
799
|
error:
|
787
800
|
return RAISE_EXCEPTION(switchpoint_result);
|
788
801
|
}
|
@@ -837,41 +850,30 @@ VALUE libev_wait_rw_fd_with_watcher(Backend_t *backend, int r_fd, int w_fd, stru
|
|
837
850
|
return switchpoint_result;
|
838
851
|
}
|
839
852
|
|
840
|
-
|
841
|
-
|
842
|
-
|
843
853
|
#ifdef POLYPHONY_LINUX
|
844
854
|
VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
845
855
|
Backend_t *backend;
|
846
856
|
struct libev_rw_io watcher;
|
847
857
|
VALUE switchpoint_result = Qnil;
|
848
|
-
|
858
|
+
int src_fd;
|
859
|
+
int dest_fd;
|
849
860
|
rb_io_t *src_fptr;
|
850
861
|
rb_io_t *dest_fptr;
|
851
862
|
int len;
|
852
863
|
|
853
864
|
GetBackend(self, backend);
|
854
|
-
|
855
|
-
|
856
|
-
if (underlying_io != Qnil) src = underlying_io;
|
857
|
-
GetOpenFile(src, src_fptr);
|
858
|
-
io_verify_blocking_mode(src_fptr, src, Qfalse);
|
859
|
-
|
860
|
-
underlying_io = rb_ivar_get(dest, ID_ivar_io);
|
861
|
-
if (underlying_io != Qnil) dest = underlying_io;
|
862
|
-
dest = rb_io_get_write_io(dest);
|
863
|
-
GetOpenFile(dest, dest_fptr);
|
864
|
-
io_verify_blocking_mode(dest_fptr, dest, Qfalse);
|
865
|
-
|
865
|
+
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
866
|
+
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
866
867
|
watcher.ctx.fiber = Qnil;
|
868
|
+
|
867
869
|
while (1) {
|
868
870
|
backend->base.op_count++;
|
869
|
-
len = splice(
|
871
|
+
len = splice(src_fd, 0, dest_fd, 0, NUM2INT(maxlen), 0);
|
870
872
|
if (len < 0) {
|
871
873
|
int e = errno;
|
872
874
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
873
875
|
|
874
|
-
switchpoint_result = libev_wait_rw_fd_with_watcher(backend,
|
876
|
+
switchpoint_result = libev_wait_rw_fd_with_watcher(backend, src_fd, dest_fd, &watcher);
|
875
877
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
876
878
|
}
|
877
879
|
else {
|
@@ -896,34 +898,26 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
896
898
|
Backend_t *backend;
|
897
899
|
struct libev_rw_io watcher;
|
898
900
|
VALUE switchpoint_result = Qnil;
|
899
|
-
|
901
|
+
int src_fd;
|
902
|
+
int dest_fd;
|
900
903
|
rb_io_t *src_fptr;
|
901
904
|
rb_io_t *dest_fptr;
|
902
905
|
int len;
|
903
906
|
int total = 0;
|
904
907
|
|
905
908
|
GetBackend(self, backend);
|
906
|
-
|
907
|
-
|
908
|
-
if (underlying_io != Qnil) src = underlying_io;
|
909
|
-
GetOpenFile(src, src_fptr);
|
910
|
-
io_verify_blocking_mode(src_fptr, src, Qfalse);
|
911
|
-
|
912
|
-
underlying_io = rb_ivar_get(dest, ID_ivar_io);
|
913
|
-
if (underlying_io != Qnil) dest = underlying_io;
|
914
|
-
dest = rb_io_get_write_io(dest);
|
915
|
-
GetOpenFile(dest, dest_fptr);
|
916
|
-
io_verify_blocking_mode(dest_fptr, dest, Qfalse);
|
917
|
-
|
909
|
+
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
910
|
+
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
918
911
|
watcher.ctx.fiber = Qnil;
|
912
|
+
|
919
913
|
while (1) {
|
920
914
|
backend->base.op_count++;
|
921
|
-
len = splice(
|
915
|
+
len = splice(src_fd, 0, dest_fd, 0, NUM2INT(maxlen), 0);
|
922
916
|
if (len < 0) {
|
923
917
|
int e = errno;
|
924
918
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
925
919
|
|
926
|
-
switchpoint_result = libev_wait_rw_fd_with_watcher(backend,
|
920
|
+
switchpoint_result = libev_wait_rw_fd_with_watcher(backend, src_fd, dest_fd, &watcher);
|
927
921
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
928
922
|
}
|
929
923
|
else if (len == 0) {
|
@@ -951,7 +945,8 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
951
945
|
Backend_t *backend;
|
952
946
|
struct libev_io watcher;
|
953
947
|
VALUE switchpoint_result = Qnil;
|
954
|
-
|
948
|
+
int src_fd;
|
949
|
+
int dest_fd;
|
955
950
|
rb_io_t *src_fptr;
|
956
951
|
rb_io_t *dest_fptr;
|
957
952
|
int len = NUM2INT(maxlen);
|
@@ -961,28 +956,18 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
961
956
|
int total = 0;
|
962
957
|
|
963
958
|
GetBackend(self, backend);
|
964
|
-
|
965
|
-
|
966
|
-
if (underlying_io != Qnil) src = underlying_io;
|
967
|
-
GetOpenFile(src, src_fptr);
|
968
|
-
io_verify_blocking_mode(src_fptr, src, Qfalse);
|
969
|
-
|
970
|
-
underlying_io = rb_ivar_get(dest, ID_ivar_io);
|
971
|
-
if (underlying_io != Qnil) dest = underlying_io;
|
972
|
-
dest = rb_io_get_write_io(dest);
|
973
|
-
GetOpenFile(dest, dest_fptr);
|
974
|
-
io_verify_blocking_mode(dest_fptr, dest, Qfalse);
|
975
|
-
|
959
|
+
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
960
|
+
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
976
961
|
watcher.fiber = Qnil;
|
977
962
|
|
978
963
|
while (1) {
|
979
964
|
backend->base.op_count++;
|
980
|
-
ssize_t n = read(
|
965
|
+
ssize_t n = read(src_fd, buf, len);
|
981
966
|
if (n < 0) {
|
982
967
|
int e = errno;
|
983
968
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
984
969
|
|
985
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
970
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, src_fd, &watcher, EV_READ);
|
986
971
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
987
972
|
}
|
988
973
|
else {
|
@@ -993,12 +978,12 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
993
978
|
|
994
979
|
while (left > 0) {
|
995
980
|
backend->base.op_count++;
|
996
|
-
ssize_t n = write(
|
981
|
+
ssize_t n = write(dest_fd, buf, left);
|
997
982
|
if (n < 0) {
|
998
983
|
int e = errno;
|
999
984
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
1000
985
|
|
1001
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
986
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, dest_fd, &watcher, EV_WRITE);
|
1002
987
|
|
1003
988
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1004
989
|
}
|
@@ -1026,7 +1011,8 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1026
1011
|
Backend_t *backend;
|
1027
1012
|
struct libev_io watcher;
|
1028
1013
|
VALUE switchpoint_result = Qnil;
|
1029
|
-
|
1014
|
+
int src_fd;
|
1015
|
+
int dest_fd;
|
1030
1016
|
rb_io_t *src_fptr;
|
1031
1017
|
rb_io_t *dest_fptr;
|
1032
1018
|
int len = NUM2INT(maxlen);
|
@@ -1036,30 +1022,20 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1036
1022
|
int total = 0;
|
1037
1023
|
|
1038
1024
|
GetBackend(self, backend);
|
1039
|
-
|
1040
|
-
|
1041
|
-
if (underlying_io != Qnil) src = underlying_io;
|
1042
|
-
GetOpenFile(src, src_fptr);
|
1043
|
-
io_verify_blocking_mode(src_fptr, src, Qfalse);
|
1044
|
-
|
1045
|
-
underlying_io = rb_ivar_get(dest, ID_ivar_io);
|
1046
|
-
if (underlying_io != Qnil) dest = underlying_io;
|
1047
|
-
dest = rb_io_get_write_io(dest);
|
1048
|
-
GetOpenFile(dest, dest_fptr);
|
1049
|
-
io_verify_blocking_mode(dest_fptr, dest, Qfalse);
|
1050
|
-
|
1025
|
+
src_fd = fd_from_io(src, &src_fptr, 0, 0);
|
1026
|
+
dest_fd = fd_from_io(dest, &dest_fptr, 1, 0);
|
1051
1027
|
watcher.fiber = Qnil;
|
1052
1028
|
|
1053
1029
|
while (1) {
|
1054
1030
|
char *ptr = buf;
|
1055
1031
|
while (1) {
|
1056
1032
|
backend->base.op_count++;
|
1057
|
-
ssize_t n = read(
|
1033
|
+
ssize_t n = read(src_fd, ptr, len);
|
1058
1034
|
if (n < 0) {
|
1059
1035
|
int e = errno;
|
1060
1036
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
1061
1037
|
|
1062
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
1038
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, src_fd, &watcher, EV_READ);
|
1063
1039
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1064
1040
|
}
|
1065
1041
|
else if (n == 0) goto done;
|
@@ -1072,12 +1048,12 @@ VALUE Backend_splice_to_eof(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
1072
1048
|
|
1073
1049
|
while (left > 0) {
|
1074
1050
|
backend->base.op_count++;
|
1075
|
-
ssize_t n = write(
|
1051
|
+
ssize_t n = write(dest_fd, ptr, left);
|
1076
1052
|
if (n < 0) {
|
1077
1053
|
int e = errno;
|
1078
1054
|
if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
|
1079
1055
|
|
1080
|
-
switchpoint_result = libev_wait_fd_with_watcher(backend,
|
1056
|
+
switchpoint_result = libev_wait_fd_with_watcher(backend, dest_fd, &watcher, EV_WRITE);
|
1081
1057
|
if (TEST_EXCEPTION(switchpoint_result)) goto error;
|
1082
1058
|
}
|
1083
1059
|
else {
|
@@ -1105,15 +1081,15 @@ error:
|
|
1105
1081
|
|
1106
1082
|
VALUE Backend_wait_io(VALUE self, VALUE io, VALUE write) {
|
1107
1083
|
Backend_t *backend;
|
1084
|
+
int fd;
|
1108
1085
|
rb_io_t *fptr;
|
1109
|
-
int
|
1110
|
-
|
1111
|
-
if (underlying_io != Qnil) io = underlying_io;
|
1086
|
+
int write_mode = RTEST(write);
|
1087
|
+
int events = write_mode ? EV_WRITE : EV_READ;
|
1112
1088
|
GetBackend(self, backend);
|
1113
|
-
|
1089
|
+
fd = fd_from_io(io, &fptr, write_mode, 0);
|
1114
1090
|
|
1115
1091
|
backend->base.op_count++;
|
1116
|
-
return libev_wait_fd(backend,
|
1092
|
+
return libev_wait_fd(backend, fd, events, 1);
|
1117
1093
|
}
|
1118
1094
|
|
1119
1095
|
struct libev_timer {
|
@@ -1460,19 +1436,13 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1460
1436
|
int err = 0;
|
1461
1437
|
VALUE result = Qnil;
|
1462
1438
|
|
1439
|
+
int src_fd;
|
1440
|
+
int dest_fd;
|
1463
1441
|
rb_io_t *src_fptr;
|
1464
1442
|
rb_io_t *dest_fptr;
|
1465
1443
|
|
1466
|
-
|
1467
|
-
|
1468
|
-
GetOpenFile(src, src_fptr);
|
1469
|
-
io_verify_blocking_mode(src_fptr, src, Qfalse);
|
1470
|
-
|
1471
|
-
underlying_io = rb_ivar_get(dest, ID_ivar_io);
|
1472
|
-
if (underlying_io != Qnil) dest = underlying_io;
|
1473
|
-
dest = rb_io_get_write_io(dest);
|
1474
|
-
GetOpenFile(dest, dest_fptr);
|
1475
|
-
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);
|
1476
1446
|
|
1477
1447
|
struct libev_rw_io watcher;
|
1478
1448
|
watcher.ctx.fiber = Qnil;
|
@@ -1490,12 +1460,12 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1490
1460
|
fcntl(pipefd[1], F_SETFL, O_NONBLOCK);
|
1491
1461
|
|
1492
1462
|
if (prefix != Qnil) {
|
1493
|
-
err = splice_chunks_write(backend,
|
1463
|
+
err = splice_chunks_write(backend, dest_fd, prefix, &watcher, &result);
|
1494
1464
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1495
1465
|
}
|
1496
1466
|
while (1) {
|
1497
1467
|
int chunk_len = 0;
|
1498
|
-
err = splice_chunks_splice(backend,
|
1468
|
+
err = splice_chunks_splice(backend, src_fd, pipefd[1], maxlen, &watcher, &result, &chunk_len);
|
1499
1469
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1500
1470
|
if (chunk_len == 0) break;
|
1501
1471
|
|
@@ -1504,14 +1474,14 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1504
1474
|
|
1505
1475
|
if (chunk_prefix != Qnil) {
|
1506
1476
|
VALUE str = (TYPE(chunk_prefix) == T_STRING) ? chunk_prefix : rb_funcall(chunk_prefix, ID_call, 1, chunk_len_value);
|
1507
|
-
int err = splice_chunks_write(backend,
|
1477
|
+
int err = splice_chunks_write(backend, dest_fd, str, &watcher, &result);
|
1508
1478
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1509
1479
|
}
|
1510
1480
|
|
1511
1481
|
int left = chunk_len;
|
1512
1482
|
while (left > 0) {
|
1513
1483
|
int len;
|
1514
|
-
err = splice_chunks_splice(backend, pipefd[0],
|
1484
|
+
err = splice_chunks_splice(backend, pipefd[0], dest_fd, left, &watcher, &result, &len);
|
1515
1485
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1516
1486
|
|
1517
1487
|
left -= len;
|
@@ -1519,13 +1489,13 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL
|
|
1519
1489
|
|
1520
1490
|
if (chunk_postfix != Qnil) {
|
1521
1491
|
VALUE str = (TYPE(chunk_postfix) == T_STRING) ? chunk_postfix : rb_funcall(chunk_postfix, ID_call, 1, chunk_len_value);
|
1522
|
-
int err = splice_chunks_write(backend,
|
1492
|
+
int err = splice_chunks_write(backend, dest_fd, str, &watcher, &result);
|
1523
1493
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1524
1494
|
}
|
1525
1495
|
}
|
1526
1496
|
|
1527
1497
|
if (postfix != Qnil) {
|
1528
|
-
int err = splice_chunks_write(backend,
|
1498
|
+
int err = splice_chunks_write(backend, dest_fd, postfix, &watcher, &result);
|
1529
1499
|
if (err == -1) goto error; else if (err) goto syscallerror;
|
1530
1500
|
}
|
1531
1501
|
|