polyphony 0.94 → 0.95
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 +2 -2
- data/.gitignore +3 -3
- data/CHANGELOG.md +14 -0
- data/docs/api-reference/fiber.md +2 -2
- data/docs/api-reference/object.md +3 -3
- data/docs/main-concepts/exception-handling.md +2 -2
- data/ext/polyphony/backend_common.c +3 -3
- data/ext/polyphony/backend_io_uring.c +18 -16
- data/ext/polyphony/event.c +1 -1
- data/ext/polyphony/extconf.rb +5 -3
- data/ext/polyphony/fiber.c +5 -13
- data/ext/polyphony/io_extensions.c +1 -1
- data/ext/polyphony/pipe.c +1 -1
- data/ext/polyphony/polyphony.c +1 -1
- data/ext/polyphony/polyphony_ext.c +1 -1
- data/ext/polyphony/queue.c +1 -1
- data/ext/polyphony/ring_buffer.c +1 -0
- data/ext/polyphony/socket_extensions.c +1 -1
- data/ext/polyphony/thread.c +1 -1
- data/lib/polyphony/extensions/enumerator.rb +16 -0
- data/lib/polyphony/extensions/socket.rb +2 -0
- data/lib/polyphony/extensions.rb +1 -0
- data/lib/polyphony/version.rb +1 -1
- data/polyphony.gemspec +2 -2
- data/test/test_backend.rb +5 -1
- data/test/test_enumerator.rb +46 -0
- data/test/test_io.rb +241 -216
- data/test/test_socket.rb +1 -1
- data/test/test_thread_pool.rb +3 -3
- data/vendor/liburing/.github/workflows/build.yml +51 -5
- data/vendor/liburing/.github/workflows/shellcheck.yml +1 -1
- data/vendor/liburing/.gitignore +6 -123
- data/vendor/liburing/CHANGELOG +35 -0
- data/vendor/liburing/CITATION.cff +11 -0
- data/vendor/liburing/LICENSE +16 -3
- data/vendor/liburing/Makefile +3 -1
- data/vendor/liburing/Makefile.common +1 -0
- data/vendor/liburing/README +14 -2
- data/vendor/liburing/SECURITY.md +6 -0
- data/vendor/liburing/configure +16 -15
- data/vendor/liburing/examples/Makefile +4 -1
- data/vendor/liburing/examples/io_uring-udp.c +395 -0
- data/vendor/liburing/examples/poll-bench.c +101 -0
- data/vendor/liburing/examples/send-zerocopy.c +339 -0
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/man/io_uring.7 +38 -11
- data/vendor/liburing/man/io_uring_buf_ring_add.3 +53 -0
- data/vendor/liburing/man/io_uring_buf_ring_advance.3 +31 -0
- data/vendor/liburing/man/io_uring_buf_ring_cq_advance.3 +41 -0
- data/vendor/liburing/man/io_uring_buf_ring_init.3 +30 -0
- data/vendor/liburing/man/io_uring_buf_ring_mask.3 +27 -0
- data/vendor/liburing/man/io_uring_cq_advance.3 +29 -15
- data/vendor/liburing/man/io_uring_cq_has_overflow.3 +25 -0
- data/vendor/liburing/man/io_uring_cq_ready.3 +9 -8
- data/vendor/liburing/man/io_uring_cqe_get_data.3 +32 -13
- data/vendor/liburing/man/io_uring_cqe_get_data64.3 +1 -0
- data/vendor/liburing/man/io_uring_cqe_seen.3 +22 -12
- data/vendor/liburing/man/io_uring_enter.2 +249 -32
- data/vendor/liburing/man/io_uring_enter2.2 +1 -0
- data/vendor/liburing/man/io_uring_free_probe.3 +11 -8
- data/vendor/liburing/man/io_uring_get_events.3 +33 -0
- data/vendor/liburing/man/io_uring_get_probe.3 +9 -8
- data/vendor/liburing/man/io_uring_get_sqe.3 +29 -10
- data/vendor/liburing/man/io_uring_opcode_supported.3 +11 -10
- data/vendor/liburing/man/io_uring_peek_cqe.3 +38 -0
- data/vendor/liburing/man/io_uring_prep_accept.3 +197 -0
- data/vendor/liburing/man/io_uring_prep_accept_direct.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_cancel.3 +118 -0
- data/vendor/liburing/man/io_uring_prep_cancel64.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_close.3 +59 -0
- data/vendor/liburing/man/io_uring_prep_close_direct.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_connect.3 +66 -0
- data/vendor/liburing/man/io_uring_prep_fadvise.3 +59 -0
- data/vendor/liburing/man/io_uring_prep_fallocate.3 +59 -0
- data/vendor/liburing/man/io_uring_prep_files_update.3 +92 -0
- data/vendor/liburing/man/io_uring_prep_fsync.3 +70 -0
- data/vendor/liburing/man/io_uring_prep_link.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_linkat.3 +91 -0
- data/vendor/liburing/man/io_uring_prep_madvise.3 +56 -0
- data/vendor/liburing/man/io_uring_prep_mkdir.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_mkdirat.3 +83 -0
- data/vendor/liburing/man/io_uring_prep_msg_ring.3 +39 -25
- data/vendor/liburing/man/io_uring_prep_multishot_accept.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_multishot_accept_direct.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_nop.3 +28 -0
- data/vendor/liburing/man/io_uring_prep_openat.3 +117 -0
- data/vendor/liburing/man/io_uring_prep_openat2.3 +117 -0
- data/vendor/liburing/man/io_uring_prep_openat2_direct.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_openat_direct.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_poll_add.3 +72 -0
- data/vendor/liburing/man/io_uring_prep_poll_multishot.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_poll_remove.3 +55 -0
- data/vendor/liburing/man/io_uring_prep_poll_update.3 +89 -0
- data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +131 -0
- data/vendor/liburing/man/io_uring_prep_read.3 +33 -14
- data/vendor/liburing/man/io_uring_prep_read_fixed.3 +39 -21
- data/vendor/liburing/man/io_uring_prep_readv.3 +49 -15
- data/vendor/liburing/man/io_uring_prep_readv2.3 +49 -17
- data/vendor/liburing/man/io_uring_prep_recv.3 +105 -0
- data/vendor/liburing/man/io_uring_prep_recv_multishot.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_recvmsg.3 +124 -0
- data/vendor/liburing/man/io_uring_prep_recvmsg_multishot.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_remove_buffers.3 +52 -0
- data/vendor/liburing/man/io_uring_prep_rename.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_renameat.3 +96 -0
- data/vendor/liburing/man/io_uring_prep_send.3 +57 -0
- data/vendor/liburing/man/io_uring_prep_send_zc.3 +64 -0
- data/vendor/liburing/man/io_uring_prep_sendmsg.3 +69 -0
- data/vendor/liburing/man/io_uring_prep_shutdown.3 +53 -0
- data/vendor/liburing/man/io_uring_prep_socket.3 +118 -0
- data/vendor/liburing/man/io_uring_prep_socket_direct.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_socket_direct_alloc.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_splice.3 +80 -0
- data/vendor/liburing/man/io_uring_prep_statx.3 +74 -0
- data/vendor/liburing/man/io_uring_prep_symlink.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_symlinkat.3 +85 -0
- data/vendor/liburing/man/io_uring_prep_sync_file_range.3 +59 -0
- data/vendor/liburing/man/io_uring_prep_tee.3 +74 -0
- data/vendor/liburing/man/io_uring_prep_timeout.3 +95 -0
- data/vendor/liburing/man/io_uring_prep_timeout_remove.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_timeout_update.3 +98 -0
- data/vendor/liburing/man/io_uring_prep_unlink.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_unlinkat.3 +82 -0
- data/vendor/liburing/man/io_uring_prep_write.3 +32 -15
- data/vendor/liburing/man/io_uring_prep_write_fixed.3 +39 -21
- data/vendor/liburing/man/io_uring_prep_writev.3 +50 -16
- data/vendor/liburing/man/io_uring_prep_writev2.3 +50 -17
- data/vendor/liburing/man/io_uring_queue_exit.3 +3 -4
- data/vendor/liburing/man/io_uring_queue_init.3 +58 -13
- data/vendor/liburing/man/io_uring_queue_init_params.3 +1 -0
- data/vendor/liburing/man/io_uring_recvmsg_cmsg_firsthdr.3 +1 -0
- data/vendor/liburing/man/io_uring_recvmsg_cmsg_nexthdr.3 +1 -0
- data/vendor/liburing/man/io_uring_recvmsg_name.3 +1 -0
- data/vendor/liburing/man/io_uring_recvmsg_out.3 +78 -0
- data/vendor/liburing/man/io_uring_recvmsg_payload.3 +1 -0
- data/vendor/liburing/man/io_uring_recvmsg_payload_length.3 +1 -0
- data/vendor/liburing/man/io_uring_recvmsg_validate.3 +1 -0
- data/vendor/liburing/man/io_uring_register.2 +153 -13
- data/vendor/liburing/man/io_uring_register_buf_ring.3 +140 -0
- data/vendor/liburing/man/io_uring_register_buffers.3 +32 -12
- data/vendor/liburing/man/io_uring_register_eventfd.3 +51 -0
- data/vendor/liburing/man/io_uring_register_eventfd_async.3 +1 -0
- data/vendor/liburing/man/io_uring_register_file_alloc_range.3 +52 -0
- data/vendor/liburing/man/io_uring_register_files.3 +33 -11
- data/vendor/liburing/man/io_uring_register_files_sparse.3 +1 -0
- data/vendor/liburing/man/io_uring_register_iowq_aff.3 +61 -0
- data/vendor/liburing/man/io_uring_register_iowq_max_workers.3 +71 -0
- data/vendor/liburing/man/io_uring_register_ring_fd.3 +49 -0
- data/vendor/liburing/man/io_uring_register_sync_cancel.3 +71 -0
- data/vendor/liburing/man/io_uring_setup.2 +119 -13
- data/vendor/liburing/man/io_uring_sq_ready.3 +14 -8
- data/vendor/liburing/man/io_uring_sq_space_left.3 +9 -9
- data/vendor/liburing/man/io_uring_sqe_set_data.3 +29 -11
- data/vendor/liburing/man/io_uring_sqe_set_data64.3 +1 -0
- data/vendor/liburing/man/io_uring_sqe_set_flags.3 +38 -11
- data/vendor/liburing/man/io_uring_sqring_wait.3 +13 -9
- data/vendor/liburing/man/io_uring_submit.3 +29 -12
- data/vendor/liburing/man/io_uring_submit_and_get_events.3 +31 -0
- data/vendor/liburing/man/io_uring_submit_and_wait.3 +16 -12
- data/vendor/liburing/man/io_uring_submit_and_wait_timeout.3 +30 -23
- data/vendor/liburing/man/io_uring_unregister_buf_ring.3 +30 -0
- data/vendor/liburing/man/io_uring_unregister_buffers.3 +11 -10
- data/vendor/liburing/man/io_uring_unregister_eventfd.3 +1 -0
- data/vendor/liburing/man/io_uring_unregister_files.3 +11 -10
- data/vendor/liburing/man/io_uring_unregister_iowq_aff.3 +1 -0
- data/vendor/liburing/man/io_uring_unregister_ring_fd.3 +32 -0
- data/vendor/liburing/man/io_uring_wait_cqe.3 +19 -12
- data/vendor/liburing/man/io_uring_wait_cqe_nr.3 +21 -14
- data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +27 -13
- data/vendor/liburing/man/io_uring_wait_cqes.3 +24 -14
- data/vendor/liburing/src/Makefile +8 -7
- data/vendor/liburing/src/arch/aarch64/lib.h +48 -0
- data/vendor/liburing/src/arch/aarch64/syscall.h +0 -4
- data/vendor/liburing/src/arch/generic/lib.h +0 -4
- data/vendor/liburing/src/arch/generic/syscall.h +29 -16
- data/vendor/liburing/src/arch/syscall-defs.h +41 -14
- data/vendor/liburing/src/arch/x86/lib.h +0 -21
- data/vendor/liburing/src/arch/x86/syscall.h +146 -10
- data/vendor/liburing/src/include/liburing/io_uring.h +245 -5
- data/vendor/liburing/src/include/liburing.h +468 -35
- data/vendor/liburing/src/int_flags.h +1 -0
- data/vendor/liburing/src/lib.h +20 -16
- data/vendor/liburing/src/liburing.map +16 -0
- data/vendor/liburing/src/nolibc.c +1 -1
- data/vendor/liburing/src/queue.c +87 -55
- data/vendor/liburing/src/register.c +129 -53
- data/vendor/liburing/src/setup.c +65 -28
- data/vendor/liburing/src/syscall.c +14 -32
- data/vendor/liburing/src/syscall.h +12 -64
- data/vendor/liburing/test/{232c93d07b74-test.c → 232c93d07b74.c} +8 -9
- data/vendor/liburing/test/{35fa71a030ca-test.c → 35fa71a030ca.c} +4 -4
- data/vendor/liburing/test/{500f9fbadef8-test.c → 500f9fbadef8.c} +7 -7
- data/vendor/liburing/test/{7ad0e4b2f83c-test.c → 7ad0e4b2f83c.c} +8 -7
- data/vendor/liburing/test/{8a9973408177-test.c → 8a9973408177.c} +4 -3
- data/vendor/liburing/test/{917257daa0fe-test.c → 917257daa0fe.c} +3 -2
- data/vendor/liburing/test/Makefile +60 -62
- data/vendor/liburing/test/{a0908ae19763-test.c → a0908ae19763.c} +3 -2
- data/vendor/liburing/test/{a4c0b3decb33-test.c → a4c0b3decb33.c} +3 -2
- data/vendor/liburing/test/accept-link.c +5 -4
- data/vendor/liburing/test/accept-reuse.c +17 -16
- data/vendor/liburing/test/accept-test.c +14 -10
- data/vendor/liburing/test/accept.c +529 -107
- data/vendor/liburing/test/across-fork.c +7 -6
- data/vendor/liburing/test/{b19062a56726-test.c → b19062a56726.c} +3 -2
- data/vendor/liburing/test/{b5837bd5311d-test.c → b5837bd5311d.c} +10 -9
- data/vendor/liburing/test/buf-ring.c +420 -0
- data/vendor/liburing/test/{ce593a6c480a-test.c → ce593a6c480a.c} +15 -12
- data/vendor/liburing/test/connect.c +8 -7
- data/vendor/liburing/test/cq-full.c +5 -4
- data/vendor/liburing/test/cq-overflow.c +242 -12
- data/vendor/liburing/test/cq-peek-batch.c +5 -4
- data/vendor/liburing/test/cq-ready.c +5 -4
- data/vendor/liburing/test/cq-size.c +5 -4
- data/vendor/liburing/test/{d4ae271dfaae-test.c → d4ae271dfaae.c} +2 -2
- data/vendor/liburing/test/{d77a67ed5f27-test.c → d77a67ed5f27.c} +6 -6
- data/vendor/liburing/test/defer-taskrun.c +336 -0
- data/vendor/liburing/test/defer.c +26 -14
- data/vendor/liburing/test/double-poll-crash.c +15 -5
- data/vendor/liburing/test/drop-submit.c +5 -3
- data/vendor/liburing/test/{eeed8b54e0df-test.c → eeed8b54e0df.c} +7 -6
- data/vendor/liburing/test/empty-eownerdead.c +4 -4
- data/vendor/liburing/test/eventfd-disable.c +48 -20
- data/vendor/liburing/test/eventfd-reg.c +10 -9
- data/vendor/liburing/test/eventfd-ring.c +13 -12
- data/vendor/liburing/test/eventfd.c +13 -12
- data/vendor/liburing/test/exit-no-cleanup.c +1 -1
- data/vendor/liburing/test/fadvise.c +3 -3
- data/vendor/liburing/test/fallocate.c +16 -9
- data/vendor/liburing/test/{fc2a85cb02ef-test.c → fc2a85cb02ef.c} +4 -3
- data/vendor/liburing/test/fd-pass.c +187 -0
- data/vendor/liburing/test/file-register.c +302 -36
- data/vendor/liburing/test/file-update.c +62 -4
- data/vendor/liburing/test/file-verify.c +6 -2
- data/vendor/liburing/test/files-exit-hang-poll.c +11 -25
- data/vendor/liburing/test/files-exit-hang-timeout.c +13 -10
- data/vendor/liburing/test/fixed-buf-iter.c +115 -0
- data/vendor/liburing/test/fixed-link.c +10 -10
- data/vendor/liburing/test/fixed-reuse.c +160 -0
- data/vendor/liburing/test/fpos.c +6 -3
- data/vendor/liburing/test/fsync.c +3 -3
- data/vendor/liburing/test/hardlink.c +10 -6
- data/vendor/liburing/test/helpers.c +137 -4
- data/vendor/liburing/test/helpers.h +27 -0
- data/vendor/liburing/test/io-cancel.c +16 -11
- data/vendor/liburing/test/io_uring_enter.c +46 -81
- data/vendor/liburing/test/io_uring_passthrough.c +451 -0
- data/vendor/liburing/test/io_uring_register.c +59 -229
- data/vendor/liburing/test/io_uring_setup.c +24 -29
- data/vendor/liburing/test/iopoll-leak.c +85 -0
- data/vendor/liburing/test/iopoll.c +16 -9
- data/vendor/liburing/test/lfs-openat-write.c +3 -1
- data/vendor/liburing/test/link-timeout.c +4 -3
- data/vendor/liburing/test/link.c +8 -7
- data/vendor/liburing/test/madvise.c +2 -2
- data/vendor/liburing/test/mkdir.c +9 -5
- data/vendor/liburing/test/msg-ring.c +46 -20
- data/vendor/liburing/test/multicqes_drain.c +51 -12
- data/vendor/liburing/test/nolibc.c +60 -0
- data/vendor/liburing/test/nop.c +78 -16
- data/vendor/liburing/test/nvme.h +168 -0
- data/vendor/liburing/test/open-direct-link.c +188 -0
- data/vendor/liburing/test/open-direct-pick.c +180 -0
- data/vendor/liburing/test/openat2.c +3 -3
- data/vendor/liburing/test/poll-cancel-all.c +472 -0
- data/vendor/liburing/test/poll-link.c +9 -18
- data/vendor/liburing/test/poll-mshot-overflow.c +162 -0
- data/vendor/liburing/test/poll-mshot-update.c +83 -33
- data/vendor/liburing/test/pollfree.c +2 -2
- data/vendor/liburing/test/read-before-exit.c +112 -0
- data/vendor/liburing/test/read-write.c +83 -1
- data/vendor/liburing/test/recv-msgall-stream.c +398 -0
- data/vendor/liburing/test/recv-msgall.c +265 -0
- data/vendor/liburing/test/recv-multishot.c +505 -0
- data/vendor/liburing/test/rename.c +2 -5
- data/vendor/liburing/test/ring-leak.c +97 -0
- data/vendor/liburing/test/ringbuf-read.c +200 -0
- data/vendor/liburing/test/rsrc_tags.c +25 -13
- data/vendor/liburing/test/runtests-quiet.sh +11 -0
- data/vendor/liburing/test/runtests.sh +18 -20
- data/vendor/liburing/test/rw_merge_test.c +3 -2
- data/vendor/liburing/test/send-zerocopy.c +684 -0
- data/vendor/liburing/test/send_recv.c +49 -2
- data/vendor/liburing/test/send_recvmsg.c +165 -55
- data/vendor/liburing/test/shutdown.c +3 -4
- data/vendor/liburing/test/sigfd-deadlock.c +22 -8
- data/vendor/liburing/test/single-issuer.c +171 -0
- data/vendor/liburing/test/socket-rw-eagain.c +2 -12
- data/vendor/liburing/test/socket-rw-offset.c +2 -11
- data/vendor/liburing/test/socket-rw.c +2 -11
- data/vendor/liburing/test/socket.c +409 -0
- data/vendor/liburing/test/sq-poll-dup.c +1 -1
- data/vendor/liburing/test/sq-poll-share.c +1 -1
- data/vendor/liburing/test/statx.c +2 -2
- data/vendor/liburing/test/submit-and-wait.c +108 -0
- data/vendor/liburing/test/submit-link-fail.c +5 -3
- data/vendor/liburing/test/submit-reuse.c +0 -2
- data/vendor/liburing/test/sync-cancel.c +235 -0
- data/vendor/liburing/test/test.h +35 -0
- data/vendor/liburing/test/timeout-overflow.c +11 -11
- data/vendor/liburing/test/timeout.c +7 -7
- data/vendor/liburing/test/tty-write-dpoll.c +60 -0
- data/vendor/liburing/test/unlink.c +1 -1
- data/vendor/liburing/test/xattr.c +425 -0
- metadata +143 -22
- data/Gemfile.lock +0 -78
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 554854ea3a7b1bc8dd555b24283e42019bb7bfb91953cd0b3e6ac49c9c59198b
|
|
4
|
+
data.tar.gz: 59a88ec85837e68ed50594ee892c814dee9e15ba19b4392d50436fb0b51b1d82
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3637e9af046327dd642bb555224e4dd36169824a698b1176f57ebeb309e61d1ac6c50d2423c8ab2ac72abf9d8e9184f37ebf9ca8343032d7e40b3244d99f8ca7
|
|
7
|
+
data.tar.gz: 27fca71574396f73e783630691cbda094488ab19128c884ca2fdafd570b0df920f083e46750455a656c0f26c9acc6f11783634cb7d43b23f2689f000ee0c67ea
|
data/.github/workflows/test.yml
CHANGED
|
@@ -8,7 +8,7 @@ jobs:
|
|
|
8
8
|
fail-fast: false
|
|
9
9
|
matrix:
|
|
10
10
|
os: [ubuntu-latest, macos-latest]
|
|
11
|
-
ruby: ['
|
|
11
|
+
ruby: ['3.0', '3.1', '3.2']
|
|
12
12
|
|
|
13
13
|
name: >-
|
|
14
14
|
${{matrix.os}}, ${{matrix.ruby}}
|
|
@@ -20,7 +20,7 @@ jobs:
|
|
|
20
20
|
|
|
21
21
|
steps:
|
|
22
22
|
- name: Setup machine
|
|
23
|
-
uses: actions/checkout@
|
|
23
|
+
uses: actions/checkout@v3
|
|
24
24
|
- name: Setup Ruby
|
|
25
25
|
uses: ruby/setup-ruby@v1
|
|
26
26
|
with:
|
data/.gitignore
CHANGED
|
@@ -42,9 +42,9 @@ build-iPhoneSimulator/
|
|
|
42
42
|
|
|
43
43
|
# for a library or gem, you might want to ignore these files since the code is
|
|
44
44
|
# intended to run in multiple environments; otherwise, check them in:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
Gemfile.lock
|
|
46
|
+
.ruby-version
|
|
47
|
+
.ruby-gemset
|
|
48
48
|
|
|
49
49
|
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
|
50
50
|
.rvmrc
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 0.95 2023-01-16
|
|
2
|
+
|
|
3
|
+
- Remove support for Ruby 2.7
|
|
4
|
+
- Add support for explicit Enumerator (external enumeration) (#93)
|
|
5
|
+
- Fix `Socket#readpartial`
|
|
6
|
+
- Fix `receive_all_pending` docs (#92)
|
|
7
|
+
- Improve linux kernel version detection
|
|
8
|
+
- Update liburing
|
|
9
|
+
- Always reset SQE user data in io_uring backend
|
|
10
|
+
|
|
11
|
+
## 0.94 2022-10-03
|
|
12
|
+
|
|
13
|
+
- Fix linux kernel version detection (#89)
|
|
14
|
+
|
|
1
15
|
## 0.93 2022-04-05
|
|
2
16
|
|
|
3
17
|
- Add support for IO::Buffer in Ruby 3.1 (#80)
|
data/docs/api-reference/fiber.md
CHANGED
|
@@ -212,7 +212,7 @@ spin { Fiber.current.parent << 'hello from child' }
|
|
|
212
212
|
message = receive #=> 'hello from child'
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
-
### #
|
|
215
|
+
### #receive_all_pending → [*object]
|
|
216
216
|
|
|
217
217
|
Returns all messages currently in the mailbox, emptying the mailbox. This method
|
|
218
218
|
does not block if no the mailbox is already empty. This method may be used to
|
|
@@ -225,7 +225,7 @@ worker = spin do
|
|
|
225
225
|
handle_job(job)
|
|
226
226
|
end
|
|
227
227
|
rescue Polyphony::Terminate => e
|
|
228
|
-
|
|
228
|
+
receive_all_pending.each { |job| handle_job(job) }
|
|
229
229
|
end
|
|
230
230
|
```
|
|
231
231
|
|
|
@@ -63,9 +63,9 @@ result #=> 'bar'
|
|
|
63
63
|
|
|
64
64
|
Shortcut for `Fiber.current.receive`
|
|
65
65
|
|
|
66
|
-
### #
|
|
66
|
+
### #receive_all_pending → [*object]
|
|
67
67
|
|
|
68
|
-
Shortcut for `Fiber.current.
|
|
68
|
+
Shortcut for `Fiber.current.receive_all_pending`
|
|
69
69
|
|
|
70
70
|
### #sleep(duration = nil) → fiber
|
|
71
71
|
|
|
@@ -96,4 +96,4 @@ returns. Otherwise, the loop is infinite (unless an exception is raised).
|
|
|
96
96
|
```ruby
|
|
97
97
|
# twice a second
|
|
98
98
|
throttled_loop(2) { puts 'hello world' }
|
|
99
|
-
```
|
|
99
|
+
```
|
|
@@ -229,7 +229,7 @@ def do_work
|
|
|
229
229
|
end
|
|
230
230
|
rescue Polyphony::Terminate
|
|
231
231
|
# We still need to handle any pending request
|
|
232
|
-
|
|
232
|
+
receive_all_pending.each { handle_req(req) }
|
|
233
233
|
end
|
|
234
234
|
|
|
235
235
|
# on the main fiber
|
|
@@ -288,4 +288,4 @@ loop.
|
|
|
288
288
|
To ensure proper thread termination, including the termination of all the
|
|
289
289
|
thread's fibers, Polyphony patches the `Thread#kill` and `Thread#raise` methods
|
|
290
290
|
to schedule the thread's main fiber with the corresponding exceptions, thus
|
|
291
|
-
ensuring an orderly termination or exception handling.
|
|
291
|
+
ensuring an orderly termination or exception handling.
|
|
@@ -280,7 +280,7 @@ inline void rectify_io_file_pos(rb_io_t *fptr) {
|
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
-
inline double current_time() {
|
|
283
|
+
inline double current_time(void) {
|
|
284
284
|
struct timespec ts;
|
|
285
285
|
double t;
|
|
286
286
|
uint64_t ns;
|
|
@@ -292,7 +292,7 @@ inline double current_time() {
|
|
|
292
292
|
return t / 1e9;
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
inline uint64_t current_time_ns() {
|
|
295
|
+
inline uint64_t current_time_ns(void) {
|
|
296
296
|
struct timespec ts;
|
|
297
297
|
uint64_t ns;
|
|
298
298
|
|
|
@@ -439,7 +439,7 @@ VALUE Backend_verify_blocking_mode(VALUE self, VALUE io, VALUE blocking) {
|
|
|
439
439
|
return self;
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
-
void backend_setup_stats_symbols() {
|
|
442
|
+
void backend_setup_stats_symbols(void) {
|
|
443
443
|
SYM_runqueue_size = ID2SYM(rb_intern("runqueue_size"));
|
|
444
444
|
SYM_runqueue_length = ID2SYM(rb_intern("runqueue_length"));
|
|
445
445
|
SYM_runqueue_max_length = ID2SYM(rb_intern("runqueue_max_length"));
|
|
@@ -286,6 +286,7 @@ VALUE Backend_wakeup(VALUE self) {
|
|
|
286
286
|
// NOP which would cause the io_uring_enter syscall to return
|
|
287
287
|
struct io_uring_sqe *sqe = io_uring_backend_get_sqe(backend);
|
|
288
288
|
io_uring_prep_nop(sqe);
|
|
289
|
+
io_uring_sqe_set_data(sqe, NULL);
|
|
289
290
|
io_uring_backend_immediate_submit(backend);
|
|
290
291
|
|
|
291
292
|
return Qtrue;
|
|
@@ -304,10 +305,7 @@ int io_uring_backend_defer_submit_and_await(
|
|
|
304
305
|
VALUE switchpoint_result = Qnil;
|
|
305
306
|
|
|
306
307
|
backend->base.op_count++;
|
|
307
|
-
if (sqe)
|
|
308
|
-
io_uring_sqe_set_data(sqe, ctx);
|
|
309
|
-
io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
|
|
310
|
-
}
|
|
308
|
+
if (sqe) io_uring_sqe_set_data(sqe, ctx);
|
|
311
309
|
io_uring_backend_defer_submit(backend);
|
|
312
310
|
|
|
313
311
|
switchpoint_result = backend_await((struct Backend_base *)backend);
|
|
@@ -318,7 +316,8 @@ int io_uring_backend_defer_submit_and_await(
|
|
|
318
316
|
// op was not completed (an exception was raised), so we need to cancel it
|
|
319
317
|
ctx->result = -ECANCELED;
|
|
320
318
|
sqe = io_uring_backend_get_sqe(backend);
|
|
321
|
-
io_uring_prep_cancel(sqe,
|
|
319
|
+
io_uring_prep_cancel(sqe, ctx, 0);
|
|
320
|
+
io_uring_sqe_set_data(sqe, NULL);
|
|
322
321
|
io_uring_backend_immediate_submit(backend);
|
|
323
322
|
}
|
|
324
323
|
|
|
@@ -931,7 +930,6 @@ static inline op_context_t *prepare_double_splice_ctx(Backend_t *backend, int sr
|
|
|
931
930
|
struct io_uring_sqe *sqe = io_uring_backend_get_sqe(backend);
|
|
932
931
|
io_uring_prep_splice(sqe, src_fd, -1, dest_fd, -1, DOUBLE_SPLICE_MAXLEN, 0);
|
|
933
932
|
io_uring_sqe_set_data(sqe, ctx);
|
|
934
|
-
io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
|
|
935
933
|
backend->base.op_count += 1;
|
|
936
934
|
backend->pending_sqes += 1;
|
|
937
935
|
|
|
@@ -941,7 +939,8 @@ static inline op_context_t *prepare_double_splice_ctx(Backend_t *backend, int sr
|
|
|
941
939
|
static inline void io_uring_backend_cancel(Backend_t *backend, op_context_t *ctx) {
|
|
942
940
|
struct io_uring_sqe *sqe = io_uring_backend_get_sqe(backend);
|
|
943
941
|
ctx->result = -ECANCELED;
|
|
944
|
-
io_uring_prep_cancel(sqe,
|
|
942
|
+
io_uring_prep_cancel(sqe, ctx, 0);
|
|
943
|
+
io_uring_sqe_set_data(sqe, NULL);
|
|
945
944
|
}
|
|
946
945
|
|
|
947
946
|
VALUE double_splice_safe(struct double_splice_ctx *ctx) {
|
|
@@ -1212,7 +1211,8 @@ VALUE Backend_timeout_ensure(VALUE arg) {
|
|
|
1212
1211
|
timeout_ctx->ctx->result = -ECANCELED;
|
|
1213
1212
|
// op was not completed, so we need to cancel it
|
|
1214
1213
|
sqe = io_uring_get_sqe(&timeout_ctx->backend->ring);
|
|
1215
|
-
io_uring_prep_cancel(sqe,
|
|
1214
|
+
io_uring_prep_cancel(sqe, timeout_ctx->ctx, 0);
|
|
1215
|
+
io_uring_sqe_set_data(sqe, NULL);
|
|
1216
1216
|
io_uring_backend_immediate_submit(timeout_ctx->backend);
|
|
1217
1217
|
}
|
|
1218
1218
|
context_store_release(&timeout_ctx->backend->store, timeout_ctx->ctx);
|
|
@@ -1330,7 +1330,8 @@ VALUE Backend_wait_event(VALUE self, VALUE raise) {
|
|
|
1330
1330
|
// last fiber to use the eventfd, so we cancel the ongoing poll
|
|
1331
1331
|
struct io_uring_sqe *sqe;
|
|
1332
1332
|
sqe = io_uring_backend_get_sqe(backend);
|
|
1333
|
-
io_uring_prep_cancel(sqe,
|
|
1333
|
+
io_uring_prep_cancel(sqe, backend->event_fd_ctx, 0);
|
|
1334
|
+
io_uring_sqe_set_data(sqe, NULL);
|
|
1334
1335
|
io_uring_backend_immediate_submit(backend);
|
|
1335
1336
|
backend->event_fd_ctx = NULL;
|
|
1336
1337
|
}
|
|
@@ -1429,14 +1430,13 @@ VALUE Backend_chain(int argc,VALUE *argv, VALUE self) {
|
|
|
1429
1430
|
|
|
1430
1431
|
if (sqe_count) {
|
|
1431
1432
|
struct io_uring_sqe *sqe;
|
|
1432
|
-
|
|
1433
1433
|
io_uring_sqe_set_data(last_sqe, ctx);
|
|
1434
|
-
io_uring_sqe_set_flags(last_sqe, IOSQE_ASYNC);
|
|
1435
1434
|
|
|
1436
1435
|
ctx->ref_count = sqe_count;
|
|
1437
1436
|
ctx->result = -ECANCELED;
|
|
1438
1437
|
sqe = io_uring_backend_get_sqe(backend);
|
|
1439
|
-
io_uring_prep_cancel(sqe,
|
|
1438
|
+
io_uring_prep_cancel(sqe, ctx, 0);
|
|
1439
|
+
io_uring_sqe_set_data(sqe, NULL);
|
|
1440
1440
|
io_uring_backend_immediate_submit(backend);
|
|
1441
1441
|
}
|
|
1442
1442
|
else {
|
|
@@ -1447,7 +1447,7 @@ VALUE Backend_chain(int argc,VALUE *argv, VALUE self) {
|
|
|
1447
1447
|
}
|
|
1448
1448
|
|
|
1449
1449
|
io_uring_sqe_set_data(last_sqe, ctx);
|
|
1450
|
-
flags = (i == (argc - 1)) ?
|
|
1450
|
+
flags = (i == (argc - 1)) ? 0 : IOSQE_IO_LINK;
|
|
1451
1451
|
io_uring_sqe_set_flags(last_sqe, flags);
|
|
1452
1452
|
sqe_count++;
|
|
1453
1453
|
}
|
|
@@ -1466,7 +1466,8 @@ VALUE Backend_chain(int argc,VALUE *argv, VALUE self) {
|
|
|
1466
1466
|
// op was not completed (an exception was raised), so we need to cancel it
|
|
1467
1467
|
ctx->result = -ECANCELED;
|
|
1468
1468
|
sqe = io_uring_backend_get_sqe(backend);
|
|
1469
|
-
io_uring_prep_cancel(sqe,
|
|
1469
|
+
io_uring_prep_cancel(sqe, ctx, 0);
|
|
1470
|
+
io_uring_sqe_set_data(sqe, NULL);
|
|
1470
1471
|
io_uring_backend_immediate_submit(backend);
|
|
1471
1472
|
RAISE_IF_EXCEPTION(resume_value);
|
|
1472
1473
|
return resume_value;
|
|
@@ -1532,7 +1533,8 @@ static inline void splice_chunks_cancel(Backend_t *backend, op_context_t *ctx) {
|
|
|
1532
1533
|
|
|
1533
1534
|
ctx->result = -ECANCELED;
|
|
1534
1535
|
sqe = io_uring_backend_get_sqe(backend);
|
|
1535
|
-
io_uring_prep_cancel(sqe,
|
|
1536
|
+
io_uring_prep_cancel(sqe, ctx, 0);
|
|
1537
|
+
io_uring_sqe_set_data(sqe, NULL);
|
|
1536
1538
|
io_uring_backend_immediate_submit(backend);
|
|
1537
1539
|
}
|
|
1538
1540
|
|
|
@@ -1699,7 +1701,7 @@ void Backend_unpark_fiber(VALUE self, VALUE fiber) {
|
|
|
1699
1701
|
backend_base_unpark_fiber(&backend->base, fiber);
|
|
1700
1702
|
}
|
|
1701
1703
|
|
|
1702
|
-
void Init_Backend() {
|
|
1704
|
+
void Init_Backend(void) {
|
|
1703
1705
|
VALUE cBackend = rb_define_class_under(mPolyphony, "Backend", rb_cObject);
|
|
1704
1706
|
rb_define_alloc_func(cBackend, Backend_allocate);
|
|
1705
1707
|
|
data/ext/polyphony/event.c
CHANGED
data/ext/polyphony/extconf.rb
CHANGED
|
@@ -15,11 +15,13 @@ def get_config
|
|
|
15
15
|
raise "Could not parse Linux kernel information (#{kernel_info.inspect})" if !m
|
|
16
16
|
|
|
17
17
|
version, major_revision, distribution = m[1].to_i, m[2].to_i, m[4]
|
|
18
|
-
|
|
18
|
+
|
|
19
|
+
combined_version = version.to_i * 100 + major_revision.to_i
|
|
20
|
+
|
|
21
|
+
config[:pidfd_open] = combined_version > 503
|
|
19
22
|
|
|
20
23
|
force_libev = ENV['POLYPHONY_LIBEV'] != nil
|
|
21
|
-
config[:io_uring] = !force_libev &&
|
|
22
|
-
(version == 5) && (major_revision >= 6) && (distribution != 'linuxkit')
|
|
24
|
+
config[:io_uring] = !force_libev && (combined_version >= 506) && (distribution != 'linuxkit')
|
|
23
25
|
config
|
|
24
26
|
end
|
|
25
27
|
|
data/ext/polyphony/fiber.c
CHANGED
|
@@ -38,24 +38,16 @@ inline VALUE Fiber_auto_watcher(VALUE self) {
|
|
|
38
38
|
return watcher;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
void Fiber_make_runnable(VALUE fiber, VALUE value) {
|
|
41
|
+
inline void Fiber_make_runnable(VALUE fiber, VALUE value) {
|
|
42
42
|
VALUE thread = rb_ivar_get(fiber, ID_ivar_thread);
|
|
43
|
-
if (thread == Qnil)
|
|
44
|
-
rb_raise(rb_eRuntimeError, "No thread set for fiber");
|
|
45
|
-
// rb_warn("No thread set for fiber");
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
43
|
+
if (thread == Qnil) rb_raise(rb_eRuntimeError, "No thread set for fiber");
|
|
48
44
|
|
|
49
45
|
Thread_schedule_fiber(thread, fiber, value);
|
|
50
46
|
}
|
|
51
47
|
|
|
52
|
-
void Fiber_make_runnable_with_priority(VALUE fiber, VALUE value) {
|
|
48
|
+
inline void Fiber_make_runnable_with_priority(VALUE fiber, VALUE value) {
|
|
53
49
|
VALUE thread = rb_ivar_get(fiber, ID_ivar_thread);
|
|
54
|
-
if (thread == Qnil)
|
|
55
|
-
rb_raise(rb_eRuntimeError, "No thread set for fiber");
|
|
56
|
-
// rb_warn("No thread set for fiber");
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
50
|
+
if (thread == Qnil) rb_raise(rb_eRuntimeError, "No thread set for fiber");
|
|
59
51
|
|
|
60
52
|
Thread_schedule_fiber_with_priority(thread, fiber, value);
|
|
61
53
|
}
|
|
@@ -130,7 +122,7 @@ VALUE Fiber_parked_p(VALUE self) {
|
|
|
130
122
|
return rb_ivar_get(self, ID_ivar_parked);
|
|
131
123
|
}
|
|
132
124
|
|
|
133
|
-
void Init_Fiber() {
|
|
125
|
+
void Init_Fiber(void) {
|
|
134
126
|
VALUE cFiber = rb_const_get(rb_cObject, rb_intern("Fiber"));
|
|
135
127
|
rb_define_method(cFiber, "safe_transfer", Fiber_safe_transfer, -1);
|
|
136
128
|
rb_define_method(cFiber, "schedule", Fiber_schedule, -1);
|
|
@@ -631,7 +631,7 @@ VALUE IO_http1_splice_chunked(VALUE self, VALUE src, VALUE dest, VALUE maxlen) {
|
|
|
631
631
|
return self;
|
|
632
632
|
}
|
|
633
633
|
|
|
634
|
-
void Init_IOExtensions() {
|
|
634
|
+
void Init_IOExtensions(void) {
|
|
635
635
|
rb_define_singleton_method(rb_cIO, "gzip", IO_gzip, -1);
|
|
636
636
|
rb_define_singleton_method(rb_cIO, "gunzip", IO_gunzip, -1);
|
|
637
637
|
rb_define_singleton_method(rb_cIO, "deflate", IO_deflate, 2);
|
data/ext/polyphony/pipe.c
CHANGED
|
@@ -96,7 +96,7 @@ VALUE Pipe_fds(VALUE self) {
|
|
|
96
96
|
return rb_ary_new_from_args(2, INT2FIX(pipe->fds[0]), INT2FIX(pipe->fds[1]));
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
void Init_Pipe() {
|
|
99
|
+
void Init_Pipe(void) {
|
|
100
100
|
cPipe = rb_define_class_under(mPolyphony, "Pipe", rb_cObject);
|
|
101
101
|
cClosedPipeError = rb_define_class_under(cPipe, "ClosedPipeError", rb_eRuntimeError);
|
|
102
102
|
|
data/ext/polyphony/polyphony.c
CHANGED
data/ext/polyphony/queue.c
CHANGED
data/ext/polyphony/ring_buffer.c
CHANGED
data/ext/polyphony/thread.c
CHANGED
|
@@ -60,7 +60,7 @@ VALUE Thread_class_backend(VALUE _self) {
|
|
|
60
60
|
return rb_ivar_get(rb_thread_current(), ID_ivar_backend);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
void Init_Thread() {
|
|
63
|
+
void Init_Thread(void) {
|
|
64
64
|
rb_define_method(rb_cThread, "setup_fiber_scheduling", Thread_setup_fiber_scheduling, 0);
|
|
65
65
|
rb_define_method(rb_cThread, "schedule_and_wakeup", Thread_fiber_schedule_and_wakeup, 2);
|
|
66
66
|
rb_define_method(rb_cThread, "switch_fiber", Thread_switch_fiber, 0);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Extensions to the Enumerator class
|
|
4
|
+
class ::Enumerator
|
|
5
|
+
alias_method :orig_next, :next
|
|
6
|
+
def next
|
|
7
|
+
Fiber.current.thread ||= Thread.current
|
|
8
|
+
orig_next
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
alias_method :orig_each, :each
|
|
12
|
+
def each(*a, &b)
|
|
13
|
+
Fiber.current.thread ||= Thread.current
|
|
14
|
+
orig_each(*a, &b)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -194,6 +194,8 @@ class ::Socket
|
|
|
194
194
|
def readpartial(maxlen, buf = +'', buf_pos = 0, raise_on_eof = true)
|
|
195
195
|
result = Polyphony.backend_recv(self, buf, maxlen, buf_pos)
|
|
196
196
|
raise EOFError if !result && raise_on_eof
|
|
197
|
+
|
|
198
|
+
result
|
|
197
199
|
end
|
|
198
200
|
|
|
199
201
|
ZERO_LINGER = [0, 0].pack('ii').freeze
|
data/lib/polyphony/extensions.rb
CHANGED
data/lib/polyphony/version.rb
CHANGED
data/polyphony.gemspec
CHANGED
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.extra_rdoc_files = ["README.md"]
|
|
20
20
|
s.extensions = ["ext/polyphony/extconf.rb"]
|
|
21
21
|
s.require_paths = ["lib"]
|
|
22
|
-
s.required_ruby_version = '>=
|
|
22
|
+
s.required_ruby_version = '>= 3.0'
|
|
23
23
|
|
|
24
24
|
s.add_development_dependency 'rake-compiler', '1.1.1'
|
|
25
25
|
s.add_development_dependency 'minitest', '5.14.4'
|
|
@@ -29,7 +29,7 @@ Gem::Specification.new do |s|
|
|
|
29
29
|
s.add_development_dependency 'pry', '0.13.1'
|
|
30
30
|
|
|
31
31
|
s.add_development_dependency 'msgpack', '1.4.2'
|
|
32
|
-
s.add_development_dependency 'httparty', '0.
|
|
32
|
+
s.add_development_dependency 'httparty', '0.21.0'
|
|
33
33
|
s.add_development_dependency 'localhost', '~>1.1.4'
|
|
34
34
|
|
|
35
35
|
# s.add_development_dependency 'jekyll', '~>3.8.6'
|
data/test/test_backend.rb
CHANGED
|
@@ -144,8 +144,12 @@ class BackendTest < MiniTest::Test
|
|
|
144
144
|
buf << :done
|
|
145
145
|
end
|
|
146
146
|
|
|
147
|
-
#
|
|
147
|
+
# Caution: we want to read in two chunks, that a race condition lurks here:
|
|
148
|
+
# writing always causes snoozing, but that might not be enough for the
|
|
149
|
+
# reader fiber to perform the read before the second write, so for the test
|
|
150
|
+
# to work consistently we add a little sleep between the two writes.
|
|
148
151
|
o << 'foo'
|
|
152
|
+
sleep 0.03
|
|
149
153
|
o << 'bar'
|
|
150
154
|
o.close
|
|
151
155
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'helper'
|
|
4
|
+
|
|
5
|
+
class EnumeratorTest < MiniTest::Test
|
|
6
|
+
def test_each_enumerator
|
|
7
|
+
o = [1, 2, 3]
|
|
8
|
+
e = o.each
|
|
9
|
+
|
|
10
|
+
r = []
|
|
11
|
+
loop do
|
|
12
|
+
r << e.next
|
|
13
|
+
rescue StopIteration
|
|
14
|
+
break
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
assert_equal o, r
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_custom_io_enumerator
|
|
21
|
+
i, o = IO.pipe
|
|
22
|
+
|
|
23
|
+
spin do
|
|
24
|
+
10.times { o.puts 'foo' }
|
|
25
|
+
o.close
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
e_fiber = nil
|
|
29
|
+
e = Enumerator.new do |y|
|
|
30
|
+
e_fiber ||= Fiber.current
|
|
31
|
+
while (l = i.gets)
|
|
32
|
+
y << l
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
r = []
|
|
37
|
+
loop do
|
|
38
|
+
r << e.next
|
|
39
|
+
rescue StopIteration
|
|
40
|
+
break
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
assert_equal ["foo\n"] * 10, r
|
|
44
|
+
assert Fiber.current != e_fiber
|
|
45
|
+
end
|
|
46
|
+
end
|