polyphony 0.93 → 0.94
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/Gemfile.lock +8 -12
- data/examples/pipes/echo_server.rb +1 -1
- data/examples/pipes/http_server.rb +33 -0
- data/ext/polyphony/backend_common.c +50 -5
- data/ext/polyphony/backend_common.h +21 -13
- data/ext/polyphony/backend_io_uring.c +67 -131
- data/ext/polyphony/backend_libev.c +58 -89
- data/ext/polyphony/extconf.rb +2 -2
- data/ext/polyphony/io_extensions.c +67 -67
- data/ext/polyphony/polyphony.c +22 -22
- data/ext/polyphony/polyphony.h +0 -9
- data/lib/polyphony/version.rb +1 -1
- data/test/test_global_api.rb +1 -1
- metadata +8 -7
| @@ -284,51 +284,25 @@ static inline int fd_from_io(VALUE io, rb_io_t **fptr, int write_mode, int recti | |
| 284 284 | 
             
              }
         | 
| 285 285 | 
             
            }
         | 
| 286 286 |  | 
| 287 | 
            -
            VALUE Backend_read(VALUE self, VALUE io, VALUE  | 
| 287 | 
            +
            VALUE Backend_read(VALUE self, VALUE io, VALUE buffer, VALUE length, VALUE to_eof, VALUE pos) {
         | 
| 288 288 | 
             
              Backend_t *backend;
         | 
| 289 289 | 
             
              struct libev_io watcher;
         | 
| 290 290 | 
             
              int fd;
         | 
| 291 291 | 
             
              rb_io_t *fptr;
         | 
| 292 292 |  | 
| 293 | 
            -
              struct  | 
| 294 | 
            -
              long buf_pos = FIX2INT(pos);
         | 
| 295 | 
            -
              int shrinkable_string = 0;
         | 
| 296 | 
            -
              int expandable_buffer = 0;
         | 
| 293 | 
            +
              struct backend_buffer_spec buffer_spec = backend_get_buffer_spec(buffer, 0);
         | 
| 297 294 | 
             
              long total = 0;
         | 
| 298 295 | 
             
              VALUE switchpoint_result = Qnil;
         | 
| 299 296 | 
             
              int read_to_eof = RTEST(to_eof);
         | 
| 300 297 |  | 
| 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 = (unsigned char *)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 | 
            -
              }
         | 
| 324 | 
            -
             | 
| 325 298 | 
             
              GetBackend(self, backend);
         | 
| 299 | 
            +
              backend_prepare_read_buffer(buffer, length, &buffer_spec, FIX2INT(pos));
         | 
| 326 300 | 
             
              fd = fd_from_io(io, &fptr, 0, 1);
         | 
| 327 301 | 
             
              watcher.fiber = Qnil;
         | 
| 328 302 |  | 
| 329 303 | 
             
              while (1) {
         | 
| 330 304 | 
             
                backend->base.op_count++;
         | 
| 331 | 
            -
                ssize_t result = read(fd,  | 
| 305 | 
            +
                ssize_t result = read(fd, buffer_spec.ptr, buffer_spec.len);
         | 
| 332 306 | 
             
                if (result < 0) {
         | 
| 333 307 | 
             
                  int e = errno;
         | 
| 334 308 | 
             
                  if (e != EWOULDBLOCK && e != EAGAIN) rb_syserr_fail(e, strerror(e));
         | 
| @@ -346,40 +320,34 @@ VALUE Backend_read(VALUE self, VALUE io, VALUE str, VALUE length, VALUE to_eof, | |
| 346 320 | 
             
                  total += result;
         | 
| 347 321 | 
             
                  if (!read_to_eof) break;
         | 
| 348 322 |  | 
| 349 | 
            -
                  if (result ==  | 
| 350 | 
            -
                    if ( | 
| 351 | 
            -
             | 
| 352 | 
            -
                     | 
| 353 | 
            -
             | 
| 354 | 
            -
                    rb_str_modify_expand(str, rb_str_capacity(str));
         | 
| 355 | 
            -
                    shrinkable_string = 0;
         | 
| 356 | 
            -
                    buffer.ptr = (unsigned char *)RSTRING_PTR(str) + total + buf_pos;
         | 
| 357 | 
            -
                    buffer.len = rb_str_capacity(str) - total - buf_pos;
         | 
| 323 | 
            +
                  if (result == buffer_spec.len) {
         | 
| 324 | 
            +
                    if (buffer_spec.expandable)
         | 
| 325 | 
            +
                      backend_grow_string_buffer(buffer, &buffer_spec, total);
         | 
| 326 | 
            +
                    else
         | 
| 327 | 
            +
                      break;
         | 
| 358 328 | 
             
                  }
         | 
| 359 329 | 
             
                  else {
         | 
| 360 | 
            -
                     | 
| 361 | 
            -
                     | 
| 362 | 
            -
                    if (! | 
| 330 | 
            +
                    buffer_spec.ptr += result;
         | 
| 331 | 
            +
                    buffer_spec.len -= result;
         | 
| 332 | 
            +
                    if (!buffer_spec.len) break;
         | 
| 363 333 | 
             
                  }
         | 
| 364 334 | 
             
                }
         | 
| 365 335 | 
             
              }
         | 
| 366 336 |  | 
| 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 337 | 
             
              if (!total) return Qnil;
         | 
| 338 | 
            +
              
         | 
| 339 | 
            +
              if (!buffer_spec.raw) backend_finalize_string_buffer(buffer, &buffer_spec, total, fptr);
         | 
| 372 340 |  | 
| 373 341 | 
             
              RB_GC_GUARD(watcher.fiber);
         | 
| 374 342 | 
             
              RB_GC_GUARD(switchpoint_result);
         | 
| 375 343 |  | 
| 376 | 
            -
              return  | 
| 344 | 
            +
              return buffer_spec.raw ? INT2FIX(total) : buffer;
         | 
| 377 345 | 
             
            error:
         | 
| 378 346 | 
             
              return RAISE_EXCEPTION(switchpoint_result);
         | 
| 379 347 | 
             
            }
         | 
| 380 348 |  | 
| 381 | 
            -
            VALUE Backend_recv(VALUE self, VALUE io, VALUE  | 
| 382 | 
            -
              return Backend_read(self, io,  | 
| 349 | 
            +
            VALUE Backend_recv(VALUE self, VALUE io, VALUE buffer, VALUE length, VALUE pos) {
         | 
| 350 | 
            +
              return Backend_read(self, io, buffer, length, Qnil, pos);
         | 
| 383 351 | 
             
            }
         | 
| 384 352 |  | 
| 385 353 | 
             
            VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) {
         | 
| @@ -387,11 +355,11 @@ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) { | |
| 387 355 | 
             
              struct libev_io watcher;
         | 
| 388 356 | 
             
              int fd;
         | 
| 389 357 | 
             
              rb_io_t *fptr;
         | 
| 390 | 
            -
              VALUE  | 
| 358 | 
            +
              VALUE buffer;
         | 
| 391 359 | 
             
              long total;
         | 
| 360 | 
            +
              char *ptr;
         | 
| 392 361 | 
             
              long len = FIX2INT(maxlen);
         | 
| 393 362 | 
             
              int shrinkable;
         | 
| 394 | 
            -
              char *buf;
         | 
| 395 363 | 
             
              VALUE switchpoint_result = Qnil;
         | 
| 396 364 |  | 
| 397 365 | 
             
              READ_LOOP_PREPARE_STR();
         | 
| @@ -402,7 +370,7 @@ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) { | |
| 402 370 |  | 
| 403 371 | 
             
              while (1) {
         | 
| 404 372 | 
             
                backend->base.op_count++;
         | 
| 405 | 
            -
                ssize_t n = read(fd,  | 
| 373 | 
            +
                ssize_t n = read(fd, ptr, len);
         | 
| 406 374 | 
             
                if (n < 0) {
         | 
| 407 375 | 
             
                  int e = errno;
         | 
| 408 376 | 
             
                  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
         | 
| @@ -421,7 +389,7 @@ VALUE Backend_read_loop(VALUE self, VALUE io, VALUE maxlen) { | |
| 421 389 | 
             
                }
         | 
| 422 390 | 
             
              }
         | 
| 423 391 |  | 
| 424 | 
            -
              RB_GC_GUARD( | 
| 392 | 
            +
              RB_GC_GUARD(buffer);
         | 
| 425 393 | 
             
              RB_GC_GUARD(watcher.fiber);
         | 
| 426 394 | 
             
              RB_GC_GUARD(switchpoint_result);
         | 
| 427 395 |  | 
| @@ -435,11 +403,11 @@ VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) { | |
| 435 403 | 
             
              struct libev_io watcher;
         | 
| 436 404 | 
             
              int fd;
         | 
| 437 405 | 
             
              rb_io_t *fptr;
         | 
| 438 | 
            -
              VALUE  | 
| 406 | 
            +
              VALUE buffer;
         | 
| 439 407 | 
             
              long total;
         | 
| 408 | 
            +
              char *ptr;
         | 
| 440 409 | 
             
              long len = 8192;
         | 
| 441 410 | 
             
              int shrinkable;
         | 
| 442 | 
            -
              char *buf;
         | 
| 443 411 | 
             
              VALUE switchpoint_result = Qnil;
         | 
| 444 412 | 
             
              ID method_id = SYM2ID(method);
         | 
| 445 413 |  | 
| @@ -451,7 +419,7 @@ VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) { | |
| 451 419 |  | 
| 452 420 | 
             
              while (1) {
         | 
| 453 421 | 
             
                backend->base.op_count++;
         | 
| 454 | 
            -
                ssize_t n = read(fd,  | 
| 422 | 
            +
                ssize_t n = read(fd, ptr, len);
         | 
| 455 423 | 
             
                if (n < 0) {
         | 
| 456 424 | 
             
                  int e = errno;
         | 
| 457 425 | 
             
                  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
         | 
| @@ -470,7 +438,7 @@ VALUE Backend_feed_loop(VALUE self, VALUE io, VALUE receiver, VALUE method) { | |
| 470 438 | 
             
                }
         | 
| 471 439 | 
             
              }
         | 
| 472 440 |  | 
| 473 | 
            -
              RB_GC_GUARD( | 
| 441 | 
            +
              RB_GC_GUARD(buffer);
         | 
| 474 442 | 
             
              RB_GC_GUARD(watcher.fiber);
         | 
| 475 443 | 
             
              RB_GC_GUARD(switchpoint_result);
         | 
| 476 444 |  | 
| @@ -479,15 +447,15 @@ error: | |
| 479 447 | 
             
              return RAISE_EXCEPTION(switchpoint_result);
         | 
| 480 448 | 
             
            }
         | 
| 481 449 |  | 
| 482 | 
            -
            VALUE Backend_write(VALUE self, VALUE io, VALUE  | 
| 450 | 
            +
            VALUE Backend_write(VALUE self, VALUE io, VALUE buffer) {
         | 
| 483 451 | 
             
              Backend_t *backend;
         | 
| 484 452 | 
             
              struct libev_io watcher;
         | 
| 485 453 | 
             
              int fd;
         | 
| 486 454 | 
             
              rb_io_t *fptr;
         | 
| 487 455 | 
             
              VALUE switchpoint_result = Qnil;
         | 
| 488 456 |  | 
| 489 | 
            -
              struct  | 
| 490 | 
            -
              long left =  | 
| 457 | 
            +
              struct backend_buffer_spec buffer_spec = backend_get_buffer_spec(buffer, 1);
         | 
| 458 | 
            +
              long left = buffer_spec.len;
         | 
| 491 459 |  | 
| 492 460 | 
             
              GetBackend(self, backend);
         | 
| 493 461 | 
             
              fd = fd_from_io(io, &fptr, 1, 0);
         | 
| @@ -495,7 +463,7 @@ VALUE Backend_write(VALUE self, VALUE io, VALUE str) { | |
| 495 463 |  | 
| 496 464 | 
             
              while (left > 0) {
         | 
| 497 465 | 
             
                backend->base.op_count++;
         | 
| 498 | 
            -
                ssize_t result = write(fd,  | 
| 466 | 
            +
                ssize_t result = write(fd, buffer_spec.ptr, left);
         | 
| 499 467 | 
             
                if (result < 0) {
         | 
| 500 468 | 
             
                  int e = errno;
         | 
| 501 469 | 
             
                  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
         | 
| @@ -505,7 +473,7 @@ VALUE Backend_write(VALUE self, VALUE io, VALUE str) { | |
| 505 473 | 
             
                  if (TEST_EXCEPTION(switchpoint_result)) goto error;
         | 
| 506 474 | 
             
                }
         | 
| 507 475 | 
             
                else {
         | 
| 508 | 
            -
                   | 
| 476 | 
            +
                  buffer_spec.ptr += result;
         | 
| 509 477 | 
             
                  left -= result;
         | 
| 510 478 | 
             
                }
         | 
| 511 479 | 
             
              }
         | 
| @@ -519,7 +487,7 @@ VALUE Backend_write(VALUE self, VALUE io, VALUE str) { | |
| 519 487 | 
             
              RB_GC_GUARD(watcher.fiber);
         | 
| 520 488 | 
             
              RB_GC_GUARD(switchpoint_result);
         | 
| 521 489 |  | 
| 522 | 
            -
              return INT2FIX( | 
| 490 | 
            +
              return INT2FIX(buffer_spec.len);
         | 
| 523 491 | 
             
            error:
         | 
| 524 492 | 
             
              return RAISE_EXCEPTION(switchpoint_result);
         | 
| 525 493 | 
             
            }
         | 
| @@ -542,9 +510,9 @@ VALUE Backend_writev(VALUE self, VALUE io, int argc, VALUE *argv) { | |
| 542 510 |  | 
| 543 511 | 
             
              iov = malloc(iov_count * sizeof(struct iovec));
         | 
| 544 512 | 
             
              for (int i = 0; i < argc; i++) {
         | 
| 545 | 
            -
                VALUE  | 
| 546 | 
            -
                iov[i].iov_base = StringValuePtr( | 
| 547 | 
            -
                iov[i].iov_len = RSTRING_LEN( | 
| 513 | 
            +
                VALUE buffer = argv[i];
         | 
| 514 | 
            +
                iov[i].iov_base = StringValuePtr(buffer);
         | 
| 515 | 
            +
                iov[i].iov_len = RSTRING_LEN(buffer);
         | 
| 548 516 | 
             
                total_length += iov[i].iov_len;
         | 
| 549 517 | 
             
              }
         | 
| 550 518 | 
             
              iov_ptr = iov;
         | 
| @@ -754,15 +722,15 @@ error: | |
| 754 722 | 
             
              return RAISE_EXCEPTION(switchpoint_result);
         | 
| 755 723 | 
             
            }
         | 
| 756 724 |  | 
| 757 | 
            -
            VALUE Backend_send(VALUE self, VALUE io, VALUE  | 
| 725 | 
            +
            VALUE Backend_send(VALUE self, VALUE io, VALUE buffer, VALUE flags) {
         | 
| 758 726 | 
             
              Backend_t *backend;
         | 
| 759 727 | 
             
              struct libev_io watcher;
         | 
| 760 728 | 
             
              int fd;
         | 
| 761 729 | 
             
              rb_io_t *fptr;
         | 
| 762 730 | 
             
              VALUE switchpoint_result = Qnil;
         | 
| 763 731 |  | 
| 764 | 
            -
              struct  | 
| 765 | 
            -
              long left =  | 
| 732 | 
            +
              struct backend_buffer_spec buffer_spec = backend_get_buffer_spec(buffer, 1);
         | 
| 733 | 
            +
              long left = buffer_spec.len;
         | 
| 766 734 | 
             
              int flags_int = FIX2INT(flags);
         | 
| 767 735 |  | 
| 768 736 | 
             
              GetBackend(self, backend);
         | 
| @@ -771,7 +739,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) { | |
| 771 739 |  | 
| 772 740 | 
             
              while (left > 0) {
         | 
| 773 741 | 
             
                backend->base.op_count++;
         | 
| 774 | 
            -
                ssize_t result = send(fd,  | 
| 742 | 
            +
                ssize_t result = send(fd, buffer_spec.ptr, left, flags_int);
         | 
| 775 743 | 
             
                if (result < 0) {
         | 
| 776 744 | 
             
                  int e = errno;
         | 
| 777 745 | 
             
                  if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
         | 
| @@ -781,7 +749,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) { | |
| 781 749 | 
             
                  if (TEST_EXCEPTION(switchpoint_result)) goto error;
         | 
| 782 750 | 
             
                }
         | 
| 783 751 | 
             
                else {
         | 
| 784 | 
            -
                   | 
| 752 | 
            +
                  buffer_spec.ptr += result;
         | 
| 785 753 | 
             
                  left -= result;
         | 
| 786 754 | 
             
                }
         | 
| 787 755 | 
             
              }
         | 
| @@ -795,7 +763,7 @@ VALUE Backend_send(VALUE self, VALUE io, VALUE str, VALUE flags) { | |
| 795 763 | 
             
              RB_GC_GUARD(watcher.fiber);
         | 
| 796 764 | 
             
              RB_GC_GUARD(switchpoint_result);
         | 
| 797 765 |  | 
| 798 | 
            -
              return INT2FIX( | 
| 766 | 
            +
              return INT2FIX(buffer_spec.len);
         | 
| 799 767 | 
             
            error:
         | 
| 800 768 | 
             
              return RAISE_EXCEPTION(switchpoint_result);
         | 
| 801 769 | 
             
            }
         | 
| @@ -952,11 +920,11 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) { | |
| 952 920 | 
             
              rb_io_t *dest_fptr;
         | 
| 953 921 | 
             
              int left = 0;
         | 
| 954 922 | 
             
              int total = 0;
         | 
| 923 | 
            +
              char *ptr;
         | 
| 955 924 | 
             
              int maxlen_i = FIX2INT(maxlen);
         | 
| 956 925 | 
             
              int splice_to_eof = maxlen_i < 0;
         | 
| 957 926 | 
             
              if (splice_to_eof) maxlen_i = -maxlen_i;
         | 
| 958 | 
            -
              VALUE  | 
| 959 | 
            -
              char *buf = RSTRING_PTR(str);
         | 
| 927 | 
            +
              VALUE buffer = rb_str_new(0, maxlen_i);
         | 
| 960 928 |  | 
| 961 929 | 
             
              GetBackend(self, backend);
         | 
| 962 930 | 
             
              src_fd = fd_from_io(src, &src_fptr, 0, 0);
         | 
| @@ -967,7 +935,8 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) { | |
| 967 935 | 
             
                int done;
         | 
| 968 936 | 
             
                while (1) {
         | 
| 969 937 | 
             
                  backend->base.op_count++;
         | 
| 970 | 
            -
                   | 
| 938 | 
            +
                  ptr = RSTRING_PTR(buffer);
         | 
| 939 | 
            +
                  ssize_t n = read(src_fd, ptr, maxlen_i);
         | 
| 971 940 | 
             
                  if (n < 0) {
         | 
| 972 941 | 
             
                    int e = errno;
         | 
| 973 942 | 
             
                    if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
         | 
| @@ -984,7 +953,7 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) { | |
| 984 953 |  | 
| 985 954 | 
             
                while (left > 0) {
         | 
| 986 955 | 
             
                  backend->base.op_count++;
         | 
| 987 | 
            -
                  ssize_t n = write(dest_fd,  | 
| 956 | 
            +
                  ssize_t n = write(dest_fd, ptr, left);
         | 
| 988 957 | 
             
                  if (n < 0) {
         | 
| 989 958 | 
             
                    int e = errno;
         | 
| 990 959 | 
             
                    if ((e != EWOULDBLOCK && e != EAGAIN)) rb_syserr_fail(e, strerror(e));
         | 
| @@ -994,7 +963,7 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) { | |
| 994 963 | 
             
                    if (TEST_EXCEPTION(switchpoint_result)) goto error;
         | 
| 995 964 | 
             
                  }
         | 
| 996 965 | 
             
                  else {
         | 
| 997 | 
            -
                     | 
| 966 | 
            +
                    ptr += n;
         | 
| 998 967 | 
             
                    left -= n;
         | 
| 999 968 | 
             
                  }
         | 
| 1000 969 | 
             
                }
         | 
| @@ -1008,7 +977,7 @@ VALUE Backend_splice(VALUE self, VALUE src, VALUE dest, VALUE maxlen) { | |
| 1008 977 |  | 
| 1009 978 | 
             
              RB_GC_GUARD(watcher.fiber);
         | 
| 1010 979 | 
             
              RB_GC_GUARD(switchpoint_result);
         | 
| 1011 | 
            -
              RB_GC_GUARD( | 
| 980 | 
            +
              RB_GC_GUARD(buffer);
         | 
| 1012 981 |  | 
| 1013 982 | 
             
              return INT2FIX(total);
         | 
| 1014 983 | 
             
            error:
         | 
| @@ -1290,13 +1259,13 @@ inline VALUE Backend_run_idle_tasks(VALUE self) { | |
| 1290 1259 | 
             
              return self;
         | 
| 1291 1260 | 
             
            }
         | 
| 1292 1261 |  | 
| 1293 | 
            -
            static inline int splice_chunks_write(Backend_t *backend, int fd, VALUE  | 
| 1294 | 
            -
              char * | 
| 1295 | 
            -
              int len = RSTRING_LEN( | 
| 1262 | 
            +
            static inline int splice_chunks_write(Backend_t *backend, int fd, VALUE buffer, struct libev_rw_io *watcher, VALUE *result) {
         | 
| 1263 | 
            +
              char *ptr = RSTRING_PTR(buffer);
         | 
| 1264 | 
            +
              int len = RSTRING_LEN(buffer);
         | 
| 1296 1265 | 
             
              int left = len;
         | 
| 1297 1266 | 
             
              while (left > 0) {
         | 
| 1298 1267 | 
             
                backend->base.op_count++;
         | 
| 1299 | 
            -
                ssize_t n = write(fd,  | 
| 1268 | 
            +
                ssize_t n = write(fd, ptr, left);
         | 
| 1300 1269 | 
             
                if (n < 0) {
         | 
| 1301 1270 | 
             
                  int err = errno;
         | 
| 1302 1271 | 
             
                  if ((err != EWOULDBLOCK && err != EAGAIN)) return err;
         | 
| @@ -1305,7 +1274,7 @@ static inline int splice_chunks_write(Backend_t *backend, int fd, VALUE str, str | |
| 1305 1274 | 
             
                  if (TEST_EXCEPTION(*result)) return -1;
         | 
| 1306 1275 | 
             
                }
         | 
| 1307 1276 | 
             
                else {
         | 
| 1308 | 
            -
                   | 
| 1277 | 
            +
                  ptr += n;
         | 
| 1309 1278 | 
             
                  left -= n;
         | 
| 1310 1279 | 
             
                }
         | 
| 1311 1280 | 
             
              }
         | 
| @@ -1388,8 +1357,8 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL | |
| 1388 1357 | 
             
              struct libev_rw_io watcher;
         | 
| 1389 1358 | 
             
              watcher.ctx.fiber = Qnil;
         | 
| 1390 1359 | 
             
              int maxlen = FIX2INT(chunk_size);
         | 
| 1391 | 
            -
              VALUE str = Qnil;
         | 
| 1392 1360 | 
             
              VALUE chunk_len_value = Qnil;
         | 
| 1361 | 
            +
              VALUE buffer;
         | 
| 1393 1362 |  | 
| 1394 1363 | 
             
              int pipefd[2] = { -1, -1 };
         | 
| 1395 1364 | 
             
              if (pipe(pipefd) == -1) {
         | 
| @@ -1414,8 +1383,8 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL | |
| 1414 1383 | 
             
                chunk_len_value = INT2FIX(chunk_len);
         | 
| 1415 1384 |  | 
| 1416 1385 | 
             
                if (chunk_prefix != Qnil) {
         | 
| 1417 | 
            -
                   | 
| 1418 | 
            -
                  int err = splice_chunks_write(backend, dest_fd,  | 
| 1386 | 
            +
                  buffer = (TYPE(chunk_prefix) == T_STRING) ? chunk_prefix : rb_funcall(chunk_prefix, ID_call, 1, chunk_len_value);
         | 
| 1387 | 
            +
                  int err = splice_chunks_write(backend, dest_fd, buffer, &watcher, &result);
         | 
| 1419 1388 | 
             
                  if (err == -1) goto error; else if (err) goto syscallerror;
         | 
| 1420 1389 | 
             
                }
         | 
| 1421 1390 |  | 
| @@ -1429,8 +1398,8 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL | |
| 1429 1398 | 
             
                }
         | 
| 1430 1399 |  | 
| 1431 1400 | 
             
                if (chunk_postfix != Qnil) {
         | 
| 1432 | 
            -
                   | 
| 1433 | 
            -
                  int err = splice_chunks_write(backend, dest_fd,  | 
| 1401 | 
            +
                  buffer = (TYPE(chunk_postfix) == T_STRING) ? chunk_postfix : rb_funcall(chunk_postfix, ID_call, 1, chunk_len_value);
         | 
| 1402 | 
            +
                  int err = splice_chunks_write(backend, dest_fd, buffer, &watcher, &result);
         | 
| 1434 1403 | 
             
                  if (err == -1) goto error; else if (err) goto syscallerror;
         | 
| 1435 1404 | 
             
                }
         | 
| 1436 1405 | 
             
              }
         | 
| @@ -1444,7 +1413,7 @@ VALUE Backend_splice_chunks(VALUE self, VALUE src, VALUE dest, VALUE prefix, VAL | |
| 1444 1413 | 
             
                result = backend_snooze(&backend->base);
         | 
| 1445 1414 | 
             
                if (TEST_EXCEPTION(result)) goto error;
         | 
| 1446 1415 | 
             
              }
         | 
| 1447 | 
            -
              RB_GC_GUARD( | 
| 1416 | 
            +
              RB_GC_GUARD(buffer);
         | 
| 1448 1417 | 
             
              RB_GC_GUARD(chunk_len_value);
         | 
| 1449 1418 | 
             
              RB_GC_GUARD(result);
         | 
| 1450 1419 | 
             
              if (pipefd[0] != -1) close(pipefd[0]);
         | 
    
        data/ext/polyphony/extconf.rb
    CHANGED
    
    | @@ -5,7 +5,7 @@ require 'mkmf' | |
| 5 5 |  | 
| 6 6 | 
             
            dir_config 'polyphony_ext'
         | 
| 7 7 |  | 
| 8 | 
            -
            KERNEL_INFO_RE = /Linux (\d)\.(\d+) | 
| 8 | 
            +
            KERNEL_INFO_RE = /Linux (\d)\.(\d+)(?:\.)?((?:\d+\.?)*)(?:\-)?([\w\-]+)?/
         | 
| 9 9 | 
             
            def get_config
         | 
| 10 10 | 
             
              config = { linux: !!(RUBY_PLATFORM =~ /linux/) }
         | 
| 11 11 | 
             
              return config if !config[:linux]
         | 
| @@ -14,7 +14,7 @@ def get_config | |
| 14 14 | 
             
              m = kernel_info.match(KERNEL_INFO_RE)
         | 
| 15 15 | 
             
              raise "Could not parse Linux kernel information (#{kernel_info.inspect})" if !m
         | 
| 16 16 |  | 
| 17 | 
            -
              version, major_revision, distribution = m[1].to_i, m[2].to_i, m[ | 
| 17 | 
            +
              version, major_revision, distribution = m[1].to_i, m[2].to_i, m[4]
         | 
| 18 18 | 
             
              config[:pidfd_open] = (version == 5) && (major_revision >= 3)
         | 
| 19 19 |  | 
| 20 20 | 
             
              force_libev = ENV['POLYPHONY_LIBEV'] != nil
         |