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
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#include <errno.h>
|
|
4
|
+
#include <stdio.h>
|
|
5
|
+
#include <stdlib.h>
|
|
6
|
+
#include <string.h>
|
|
7
|
+
#include <unistd.h>
|
|
8
|
+
#include <arpa/inet.h>
|
|
9
|
+
#include <sys/types.h>
|
|
10
|
+
#include <sys/socket.h>
|
|
11
|
+
#include <pthread.h>
|
|
12
|
+
|
|
13
|
+
#include "liburing.h"
|
|
14
|
+
#include "helpers.h"
|
|
15
|
+
|
|
16
|
+
#define ENORECVMULTISHOT 9999
|
|
17
|
+
|
|
18
|
+
enum early_error_t {
|
|
19
|
+
ERROR_NONE = 0,
|
|
20
|
+
ERROR_NOT_ENOUGH_BUFFERS,
|
|
21
|
+
ERROR_EARLY_CLOSE_SENDER,
|
|
22
|
+
ERROR_EARLY_CLOSE_RECEIVER,
|
|
23
|
+
ERROR_EARLY_OVERFLOW,
|
|
24
|
+
ERROR_EARLY_LAST
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
struct args {
|
|
28
|
+
bool stream;
|
|
29
|
+
bool wait_each;
|
|
30
|
+
bool recvmsg;
|
|
31
|
+
enum early_error_t early_error;
|
|
32
|
+
bool defer;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
static int check_sockaddr(struct sockaddr_in *in)
|
|
36
|
+
{
|
|
37
|
+
struct in_addr expected;
|
|
38
|
+
|
|
39
|
+
inet_pton(AF_INET, "127.0.0.1", &expected);
|
|
40
|
+
if (in->sin_family != AF_INET) {
|
|
41
|
+
fprintf(stderr, "bad family %d\n", (int)htons(in->sin_family));
|
|
42
|
+
return -1;
|
|
43
|
+
}
|
|
44
|
+
if (memcmp(&expected, &in->sin_addr, sizeof(in->sin_addr))) {
|
|
45
|
+
char buff[256];
|
|
46
|
+
const char *addr = inet_ntop(AF_INET, &in->sin_addr, buff, sizeof(buff));
|
|
47
|
+
|
|
48
|
+
fprintf(stderr, "unexpected address %s\n", addr ? addr : "INVALID");
|
|
49
|
+
return -1;
|
|
50
|
+
}
|
|
51
|
+
return 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static int test(struct args *args)
|
|
55
|
+
{
|
|
56
|
+
int const N = 8;
|
|
57
|
+
int const N_BUFFS = N * 64;
|
|
58
|
+
int const N_CQE_OVERFLOW = 4;
|
|
59
|
+
int const min_cqes = 2;
|
|
60
|
+
int const NAME_LEN = sizeof(struct sockaddr_storage);
|
|
61
|
+
int const CONTROL_LEN = CMSG_ALIGN(sizeof(struct sockaddr_storage))
|
|
62
|
+
+ sizeof(struct cmsghdr);
|
|
63
|
+
struct io_uring ring;
|
|
64
|
+
struct io_uring_cqe *cqe;
|
|
65
|
+
struct io_uring_sqe *sqe;
|
|
66
|
+
int fds[2], ret, i, j;
|
|
67
|
+
int total_sent_bytes = 0, total_recv_bytes = 0, total_dropped_bytes = 0;
|
|
68
|
+
int send_buff[256];
|
|
69
|
+
int *sent_buffs[N_BUFFS];
|
|
70
|
+
int *recv_buffs[N_BUFFS];
|
|
71
|
+
int *at;
|
|
72
|
+
struct io_uring_cqe recv_cqe[N_BUFFS];
|
|
73
|
+
int recv_cqes = 0;
|
|
74
|
+
bool early_error = false;
|
|
75
|
+
bool early_error_started = false;
|
|
76
|
+
struct __kernel_timespec timeout = {
|
|
77
|
+
.tv_sec = 1,
|
|
78
|
+
};
|
|
79
|
+
struct msghdr msg;
|
|
80
|
+
struct io_uring_params params = { };
|
|
81
|
+
int n_sqe = 32;
|
|
82
|
+
|
|
83
|
+
memset(recv_buffs, 0, sizeof(recv_buffs));
|
|
84
|
+
|
|
85
|
+
if (args->defer)
|
|
86
|
+
params.flags |= IORING_SETUP_SINGLE_ISSUER |
|
|
87
|
+
IORING_SETUP_DEFER_TASKRUN;
|
|
88
|
+
|
|
89
|
+
if (args->early_error == ERROR_EARLY_OVERFLOW) {
|
|
90
|
+
params.flags |= IORING_SETUP_CQSIZE;
|
|
91
|
+
params.cq_entries = N_CQE_OVERFLOW;
|
|
92
|
+
n_sqe = N_CQE_OVERFLOW;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
ret = io_uring_queue_init_params(n_sqe, &ring, ¶ms);
|
|
96
|
+
if (ret) {
|
|
97
|
+
fprintf(stderr, "queue init failed: %d\n", ret);
|
|
98
|
+
return ret;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
ret = t_create_socket_pair(fds, args->stream);
|
|
102
|
+
if (ret) {
|
|
103
|
+
fprintf(stderr, "t_create_socket_pair failed: %d\n", ret);
|
|
104
|
+
return ret;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!args->stream) {
|
|
108
|
+
bool val = true;
|
|
109
|
+
|
|
110
|
+
/* force some cmsgs to come back to us */
|
|
111
|
+
ret = setsockopt(fds[0], IPPROTO_IP, IP_RECVORIGDSTADDR, &val,
|
|
112
|
+
sizeof(val));
|
|
113
|
+
if (ret) {
|
|
114
|
+
fprintf(stderr, "setsockopt failed %d\n", errno);
|
|
115
|
+
goto cleanup;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
for (i = 0; i < ARRAY_SIZE(send_buff); i++)
|
|
120
|
+
send_buff[i] = i;
|
|
121
|
+
|
|
122
|
+
for (i = 0; i < ARRAY_SIZE(recv_buffs); i++) {
|
|
123
|
+
/* prepare some different sized buffers */
|
|
124
|
+
int buffer_size = (i % 2 == 0 && (args->stream || args->recvmsg)) ? 1 : N;
|
|
125
|
+
|
|
126
|
+
buffer_size *= sizeof(int);
|
|
127
|
+
if (args->recvmsg) {
|
|
128
|
+
buffer_size +=
|
|
129
|
+
sizeof(struct io_uring_recvmsg_out) +
|
|
130
|
+
NAME_LEN +
|
|
131
|
+
CONTROL_LEN;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
recv_buffs[i] = malloc(buffer_size);
|
|
135
|
+
|
|
136
|
+
if (i > 2 && args->early_error == ERROR_NOT_ENOUGH_BUFFERS)
|
|
137
|
+
continue;
|
|
138
|
+
|
|
139
|
+
sqe = io_uring_get_sqe(&ring);
|
|
140
|
+
io_uring_prep_provide_buffers(sqe, recv_buffs[i],
|
|
141
|
+
buffer_size, 1, 7, i);
|
|
142
|
+
io_uring_sqe_set_data64(sqe, 0x999);
|
|
143
|
+
memset(recv_buffs[i], 0xcc, buffer_size);
|
|
144
|
+
if (io_uring_submit_and_wait_timeout(&ring, &cqe, 1, &timeout, NULL) < 0) {
|
|
145
|
+
fprintf(stderr, "provide buffers failed: %d\n", ret);
|
|
146
|
+
ret = -1;
|
|
147
|
+
goto cleanup;
|
|
148
|
+
}
|
|
149
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
sqe = io_uring_get_sqe(&ring);
|
|
153
|
+
if (args->recvmsg) {
|
|
154
|
+
unsigned int flags = 0;
|
|
155
|
+
|
|
156
|
+
if (!args->stream)
|
|
157
|
+
flags |= MSG_TRUNC;
|
|
158
|
+
|
|
159
|
+
memset(&msg, 0, sizeof(msg));
|
|
160
|
+
msg.msg_namelen = NAME_LEN;
|
|
161
|
+
msg.msg_controllen = CONTROL_LEN;
|
|
162
|
+
io_uring_prep_recvmsg_multishot(sqe, fds[0], &msg, flags);
|
|
163
|
+
} else {
|
|
164
|
+
io_uring_prep_recv_multishot(sqe, fds[0], NULL, 0, 0);
|
|
165
|
+
}
|
|
166
|
+
sqe->flags |= IOSQE_BUFFER_SELECT;
|
|
167
|
+
sqe->buf_group = 7;
|
|
168
|
+
io_uring_sqe_set_data64(sqe, 1234);
|
|
169
|
+
io_uring_submit(&ring);
|
|
170
|
+
|
|
171
|
+
at = &send_buff[0];
|
|
172
|
+
total_sent_bytes = 0;
|
|
173
|
+
for (i = 0; i < N; i++) {
|
|
174
|
+
int to_send = sizeof(*at) * (i+1);
|
|
175
|
+
|
|
176
|
+
total_sent_bytes += to_send;
|
|
177
|
+
sent_buffs[i] = at;
|
|
178
|
+
if (send(fds[1], at, to_send, 0) != to_send) {
|
|
179
|
+
if (early_error_started)
|
|
180
|
+
break;
|
|
181
|
+
fprintf(stderr, "send failed %d\n", errno);
|
|
182
|
+
ret = -1;
|
|
183
|
+
goto cleanup;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (i == 2) {
|
|
187
|
+
if (args->early_error == ERROR_EARLY_CLOSE_RECEIVER) {
|
|
188
|
+
/* allow previous sends to complete */
|
|
189
|
+
usleep(1000);
|
|
190
|
+
io_uring_get_events(&ring);
|
|
191
|
+
|
|
192
|
+
sqe = io_uring_get_sqe(&ring);
|
|
193
|
+
io_uring_prep_recv(sqe, fds[0], NULL, 0, 0);
|
|
194
|
+
io_uring_prep_cancel64(sqe, 1234, 0);
|
|
195
|
+
io_uring_sqe_set_data64(sqe, 0x888);
|
|
196
|
+
sqe->flags |= IOSQE_CQE_SKIP_SUCCESS;
|
|
197
|
+
io_uring_submit(&ring);
|
|
198
|
+
early_error_started = true;
|
|
199
|
+
|
|
200
|
+
/* allow the cancel to complete */
|
|
201
|
+
usleep(1000);
|
|
202
|
+
io_uring_get_events(&ring);
|
|
203
|
+
}
|
|
204
|
+
if (args->early_error == ERROR_EARLY_CLOSE_SENDER) {
|
|
205
|
+
early_error_started = true;
|
|
206
|
+
shutdown(fds[1], SHUT_RDWR);
|
|
207
|
+
close(fds[1]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
at += (i+1);
|
|
211
|
+
|
|
212
|
+
if (args->wait_each) {
|
|
213
|
+
ret = io_uring_wait_cqes(&ring, &cqe, 1, &timeout, NULL);
|
|
214
|
+
if (ret) {
|
|
215
|
+
fprintf(stderr, "wait_each failed: %d\n", ret);
|
|
216
|
+
ret = -1;
|
|
217
|
+
goto cleanup;
|
|
218
|
+
}
|
|
219
|
+
while (io_uring_peek_cqe(&ring, &cqe) == 0) {
|
|
220
|
+
recv_cqe[recv_cqes++] = *cqe;
|
|
221
|
+
if (cqe->flags & IORING_CQE_F_MORE) {
|
|
222
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
223
|
+
} else {
|
|
224
|
+
early_error = true;
|
|
225
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (early_error)
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
close(fds[1]);
|
|
234
|
+
|
|
235
|
+
/* allow sends to finish */
|
|
236
|
+
usleep(1000);
|
|
237
|
+
|
|
238
|
+
if ((args->stream && !early_error) || recv_cqes < min_cqes) {
|
|
239
|
+
ret = io_uring_wait_cqes(&ring, &cqe, 1, &timeout, NULL);
|
|
240
|
+
if (ret && ret != -ETIME) {
|
|
241
|
+
fprintf(stderr, "wait final failed: %d\n", ret);
|
|
242
|
+
ret = -1;
|
|
243
|
+
goto cleanup;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
while (io_uring_peek_cqe(&ring, &cqe) == 0) {
|
|
248
|
+
recv_cqe[recv_cqes++] = *cqe;
|
|
249
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
ret = -1;
|
|
253
|
+
at = &send_buff[0];
|
|
254
|
+
if (recv_cqes < min_cqes) {
|
|
255
|
+
if (recv_cqes > 0 && recv_cqe[0].res == -EINVAL) {
|
|
256
|
+
return -ENORECVMULTISHOT;
|
|
257
|
+
}
|
|
258
|
+
/* some kernels apparently don't check ->ioprio, skip */
|
|
259
|
+
ret = -ENORECVMULTISHOT;
|
|
260
|
+
goto cleanup;
|
|
261
|
+
}
|
|
262
|
+
for (i = 0; i < recv_cqes; i++) {
|
|
263
|
+
cqe = &recv_cqe[i];
|
|
264
|
+
|
|
265
|
+
bool const is_last = i == recv_cqes - 1;
|
|
266
|
+
|
|
267
|
+
bool const should_be_last =
|
|
268
|
+
(cqe->res <= 0) ||
|
|
269
|
+
(args->stream && is_last) ||
|
|
270
|
+
(args->early_error == ERROR_EARLY_OVERFLOW &&
|
|
271
|
+
!args->wait_each && i == N_CQE_OVERFLOW);
|
|
272
|
+
int *this_recv;
|
|
273
|
+
int orig_payload_size = cqe->res;
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
if (should_be_last) {
|
|
277
|
+
int used_res = cqe->res;
|
|
278
|
+
|
|
279
|
+
if (!is_last) {
|
|
280
|
+
fprintf(stderr, "not last cqe had error %d\n", i);
|
|
281
|
+
goto cleanup;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
switch (args->early_error) {
|
|
285
|
+
case ERROR_NOT_ENOUGH_BUFFERS:
|
|
286
|
+
if (cqe->res != -ENOBUFS) {
|
|
287
|
+
fprintf(stderr,
|
|
288
|
+
"ERROR_NOT_ENOUGH_BUFFERS: res %d\n", cqe->res);
|
|
289
|
+
goto cleanup;
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
case ERROR_EARLY_OVERFLOW:
|
|
293
|
+
if (cqe->res < 0) {
|
|
294
|
+
fprintf(stderr,
|
|
295
|
+
"ERROR_EARLY_OVERFLOW: res %d\n", cqe->res);
|
|
296
|
+
goto cleanup;
|
|
297
|
+
}
|
|
298
|
+
break;
|
|
299
|
+
case ERROR_EARLY_CLOSE_RECEIVER:
|
|
300
|
+
if (cqe->res != -ECANCELED) {
|
|
301
|
+
fprintf(stderr,
|
|
302
|
+
"ERROR_EARLY_CLOSE_RECEIVER: res %d\n", cqe->res);
|
|
303
|
+
goto cleanup;
|
|
304
|
+
}
|
|
305
|
+
break;
|
|
306
|
+
case ERROR_NONE:
|
|
307
|
+
case ERROR_EARLY_CLOSE_SENDER:
|
|
308
|
+
if (args->recvmsg && (cqe->flags & IORING_CQE_F_BUFFER)) {
|
|
309
|
+
void *buff = recv_buffs[cqe->flags >> 16];
|
|
310
|
+
struct io_uring_recvmsg_out *o =
|
|
311
|
+
io_uring_recvmsg_validate(buff, cqe->res, &msg);
|
|
312
|
+
|
|
313
|
+
if (!o) {
|
|
314
|
+
fprintf(stderr, "invalid buff\n");
|
|
315
|
+
goto cleanup;
|
|
316
|
+
}
|
|
317
|
+
if (o->payloadlen != 0) {
|
|
318
|
+
fprintf(stderr, "expected 0 payloadlen, got %u\n",
|
|
319
|
+
o->payloadlen);
|
|
320
|
+
goto cleanup;
|
|
321
|
+
}
|
|
322
|
+
used_res = 0;
|
|
323
|
+
} else if (cqe->res != 0) {
|
|
324
|
+
fprintf(stderr, "early error: res %d\n", cqe->res);
|
|
325
|
+
goto cleanup;
|
|
326
|
+
}
|
|
327
|
+
break;
|
|
328
|
+
case ERROR_EARLY_LAST:
|
|
329
|
+
fprintf(stderr, "bad error_early\n");
|
|
330
|
+
goto cleanup;
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
if (cqe->res <= 0 && cqe->flags & IORING_CQE_F_BUFFER) {
|
|
334
|
+
fprintf(stderr, "final BUFFER flag set\n");
|
|
335
|
+
goto cleanup;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (cqe->flags & IORING_CQE_F_MORE) {
|
|
339
|
+
fprintf(stderr, "final MORE flag set\n");
|
|
340
|
+
goto cleanup;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (used_res <= 0)
|
|
344
|
+
continue;
|
|
345
|
+
} else {
|
|
346
|
+
if (!(cqe->flags & IORING_CQE_F_MORE)) {
|
|
347
|
+
fprintf(stderr, "MORE flag not set\n");
|
|
348
|
+
goto cleanup;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (!(cqe->flags & IORING_CQE_F_BUFFER)) {
|
|
353
|
+
fprintf(stderr, "BUFFER flag not set\n");
|
|
354
|
+
goto cleanup;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
this_recv = recv_buffs[cqe->flags >> 16];
|
|
358
|
+
|
|
359
|
+
if (args->recvmsg) {
|
|
360
|
+
struct io_uring_recvmsg_out *o = io_uring_recvmsg_validate(
|
|
361
|
+
this_recv, cqe->res, &msg);
|
|
362
|
+
|
|
363
|
+
if (!o) {
|
|
364
|
+
fprintf(stderr, "bad recvmsg\n");
|
|
365
|
+
goto cleanup;
|
|
366
|
+
}
|
|
367
|
+
orig_payload_size = o->payloadlen;
|
|
368
|
+
|
|
369
|
+
if (!args->stream) {
|
|
370
|
+
orig_payload_size = o->payloadlen;
|
|
371
|
+
|
|
372
|
+
struct cmsghdr *cmsg;
|
|
373
|
+
|
|
374
|
+
if (o->namelen < sizeof(struct sockaddr_in)) {
|
|
375
|
+
fprintf(stderr, "bad addr len %d",
|
|
376
|
+
o->namelen);
|
|
377
|
+
goto cleanup;
|
|
378
|
+
}
|
|
379
|
+
if (check_sockaddr((struct sockaddr_in *)io_uring_recvmsg_name(o)))
|
|
380
|
+
goto cleanup;
|
|
381
|
+
|
|
382
|
+
cmsg = io_uring_recvmsg_cmsg_firsthdr(o, &msg);
|
|
383
|
+
if (!cmsg ||
|
|
384
|
+
cmsg->cmsg_level != IPPROTO_IP ||
|
|
385
|
+
cmsg->cmsg_type != IP_RECVORIGDSTADDR) {
|
|
386
|
+
fprintf(stderr, "bad cmsg");
|
|
387
|
+
goto cleanup;
|
|
388
|
+
}
|
|
389
|
+
if (check_sockaddr((struct sockaddr_in *)CMSG_DATA(cmsg)))
|
|
390
|
+
goto cleanup;
|
|
391
|
+
cmsg = io_uring_recvmsg_cmsg_nexthdr(o, &msg, cmsg);
|
|
392
|
+
if (cmsg) {
|
|
393
|
+
fprintf(stderr, "unexpected extra cmsg\n");
|
|
394
|
+
goto cleanup;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
this_recv = (int *)io_uring_recvmsg_payload(o, &msg);
|
|
400
|
+
cqe->res = io_uring_recvmsg_payload_length(o, cqe->res, &msg);
|
|
401
|
+
if (o->payloadlen != cqe->res) {
|
|
402
|
+
if (!(o->flags & MSG_TRUNC)) {
|
|
403
|
+
fprintf(stderr, "expected truncated flag\n");
|
|
404
|
+
goto cleanup;
|
|
405
|
+
}
|
|
406
|
+
total_dropped_bytes += (o->payloadlen - cqe->res);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
total_recv_bytes += cqe->res;
|
|
411
|
+
|
|
412
|
+
if (cqe->res % 4 != 0) {
|
|
413
|
+
/*
|
|
414
|
+
* doesn't seem to happen in practice, would need some
|
|
415
|
+
* work to remove this requirement
|
|
416
|
+
*/
|
|
417
|
+
fprintf(stderr, "unexpectedly aligned buffer cqe->res=%d\n", cqe->res);
|
|
418
|
+
goto cleanup;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/*
|
|
422
|
+
* for tcp: check buffer arrived in order
|
|
423
|
+
* for udp: based on size validate data based on size
|
|
424
|
+
*/
|
|
425
|
+
if (!args->stream) {
|
|
426
|
+
int sent_idx = orig_payload_size / sizeof(*at) - 1;
|
|
427
|
+
|
|
428
|
+
if (sent_idx < 0 || sent_idx > N) {
|
|
429
|
+
fprintf(stderr, "Bad sent idx: %d\n", sent_idx);
|
|
430
|
+
goto cleanup;
|
|
431
|
+
}
|
|
432
|
+
at = sent_buffs[sent_idx];
|
|
433
|
+
}
|
|
434
|
+
for (j = 0; j < cqe->res / 4; j++) {
|
|
435
|
+
int sent = *at++;
|
|
436
|
+
int recv = *this_recv++;
|
|
437
|
+
|
|
438
|
+
if (sent != recv) {
|
|
439
|
+
fprintf(stderr, "recv=%d sent=%d\n", recv, sent);
|
|
440
|
+
goto cleanup;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (args->early_error == ERROR_NONE &&
|
|
446
|
+
total_recv_bytes + total_dropped_bytes < total_sent_bytes) {
|
|
447
|
+
fprintf(stderr,
|
|
448
|
+
"missing recv: recv=%d dropped=%d sent=%d\n",
|
|
449
|
+
total_recv_bytes, total_sent_bytes, total_dropped_bytes);
|
|
450
|
+
goto cleanup;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
ret = 0;
|
|
454
|
+
cleanup:
|
|
455
|
+
for (i = 0; i < ARRAY_SIZE(recv_buffs); i++)
|
|
456
|
+
free(recv_buffs[i]);
|
|
457
|
+
close(fds[0]);
|
|
458
|
+
close(fds[1]);
|
|
459
|
+
io_uring_queue_exit(&ring);
|
|
460
|
+
|
|
461
|
+
return ret;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
int main(int argc, char *argv[])
|
|
465
|
+
{
|
|
466
|
+
int ret;
|
|
467
|
+
int loop;
|
|
468
|
+
int early_error = 0;
|
|
469
|
+
bool has_defer;
|
|
470
|
+
|
|
471
|
+
if (argc > 1)
|
|
472
|
+
return T_EXIT_SKIP;
|
|
473
|
+
|
|
474
|
+
has_defer = t_probe_defer_taskrun();
|
|
475
|
+
|
|
476
|
+
for (loop = 0; loop < 16; loop++) {
|
|
477
|
+
struct args a = {
|
|
478
|
+
.stream = loop & 0x01,
|
|
479
|
+
.wait_each = loop & 0x2,
|
|
480
|
+
.recvmsg = loop & 0x04,
|
|
481
|
+
.defer = loop & 0x08,
|
|
482
|
+
};
|
|
483
|
+
if (a.defer && !has_defer)
|
|
484
|
+
continue;
|
|
485
|
+
for (early_error = 0; early_error < ERROR_EARLY_LAST; early_error++) {
|
|
486
|
+
a.early_error = (enum early_error_t)early_error;
|
|
487
|
+
ret = test(&a);
|
|
488
|
+
if (ret) {
|
|
489
|
+
if (ret == -ENORECVMULTISHOT) {
|
|
490
|
+
if (loop == 0)
|
|
491
|
+
return T_EXIT_SKIP;
|
|
492
|
+
fprintf(stderr,
|
|
493
|
+
"ENORECVMULTISHOT received but loop>0\n");
|
|
494
|
+
}
|
|
495
|
+
fprintf(stderr,
|
|
496
|
+
"test stream=%d wait_each=%d recvmsg=%d early_error=%d "
|
|
497
|
+
" defer=%d failed\n",
|
|
498
|
+
a.stream, a.wait_each, a.recvmsg, a.early_error, a.defer);
|
|
499
|
+
return T_EXIT_FAIL;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return T_EXIT_PASS;
|
|
505
|
+
}
|
|
@@ -26,11 +26,8 @@ static int test_rename(struct io_uring *ring, const char *old, const char *new)
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
memset(sqe, 0, sizeof(*sqe));
|
|
29
|
-
|
|
30
|
-
sqe
|
|
31
|
-
sqe->addr2 = (unsigned long) new;
|
|
32
|
-
sqe->addr = (unsigned long) old;
|
|
33
|
-
sqe->len = AT_FDCWD;
|
|
29
|
+
|
|
30
|
+
io_uring_prep_rename(sqe, old, new);
|
|
34
31
|
|
|
35
32
|
ret = io_uring_submit(ring);
|
|
36
33
|
if (ret <= 0) {
|
|
@@ -131,12 +131,97 @@ static int test_iowq_request_cancel(void)
|
|
|
131
131
|
ret = read(fds[0], buffer, 10);
|
|
132
132
|
if (ret < 0)
|
|
133
133
|
perror("read");
|
|
134
|
+
close(fds[0]);
|
|
135
|
+
return 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
static void trigger_unix_gc(void)
|
|
139
|
+
{
|
|
140
|
+
int fd;
|
|
141
|
+
|
|
142
|
+
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
|
143
|
+
if (fd < 0)
|
|
144
|
+
perror("socket dgram");
|
|
145
|
+
else
|
|
146
|
+
close(fd);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static int test_scm_cycles(bool update)
|
|
150
|
+
{
|
|
151
|
+
char buffer[128];
|
|
152
|
+
struct io_uring ring;
|
|
153
|
+
int i, ret;
|
|
154
|
+
int sp[2], fds[2], reg_fds[4];
|
|
155
|
+
|
|
156
|
+
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) != 0) {
|
|
157
|
+
perror("Failed to create Unix-domain socket pair\n");
|
|
158
|
+
return 1;
|
|
159
|
+
}
|
|
160
|
+
ret = io_uring_queue_init(8, &ring, 0);
|
|
161
|
+
if (ret < 0) {
|
|
162
|
+
fprintf(stderr, "failed to init io_uring: %s\n", strerror(-ret));
|
|
163
|
+
return ret;
|
|
164
|
+
}
|
|
165
|
+
if (pipe(fds)) {
|
|
166
|
+
perror("pipe");
|
|
167
|
+
return -1;
|
|
168
|
+
}
|
|
169
|
+
send_fd(sp[0], ring.ring_fd);
|
|
170
|
+
|
|
171
|
+
/* register an empty set for updates */
|
|
172
|
+
if (update) {
|
|
173
|
+
for (i = 0; i < 4; i++)
|
|
174
|
+
reg_fds[i] = -1;
|
|
175
|
+
ret = io_uring_register_files(&ring, reg_fds, 4);
|
|
176
|
+
if (ret) {
|
|
177
|
+
fprintf(stderr, "file_register: %d\n", ret);
|
|
178
|
+
return ret;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
reg_fds[0] = fds[0];
|
|
183
|
+
reg_fds[1] = fds[1];
|
|
184
|
+
reg_fds[2] = sp[0];
|
|
185
|
+
reg_fds[3] = sp[1];
|
|
186
|
+
if (update) {
|
|
187
|
+
ret = io_uring_register_files_update(&ring, 0, reg_fds, 4);
|
|
188
|
+
if (ret != 4) {
|
|
189
|
+
fprintf(stderr, "file_register: %d\n", ret);
|
|
190
|
+
return ret;
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
ret = io_uring_register_files(&ring, reg_fds, 4);
|
|
194
|
+
if (ret) {
|
|
195
|
+
fprintf(stderr, "file_register: %d\n", ret);
|
|
196
|
+
return ret;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
close(fds[1]);
|
|
201
|
+
close(sp[0]);
|
|
202
|
+
close(sp[1]);
|
|
203
|
+
|
|
204
|
+
/* should unregister files and close the write fd */
|
|
205
|
+
io_uring_queue_exit(&ring);
|
|
206
|
+
|
|
207
|
+
trigger_unix_gc();
|
|
208
|
+
|
|
209
|
+
/*
|
|
210
|
+
* We're trying to wait for the ring to "really" exit, that will be
|
|
211
|
+
* done async. For that rely on the registered write end to be closed
|
|
212
|
+
* after ring quiesce, so failing read from the other pipe end.
|
|
213
|
+
*/
|
|
214
|
+
ret = read(fds[0], buffer, 10);
|
|
215
|
+
if (ret < 0)
|
|
216
|
+
perror("read");
|
|
217
|
+
close(fds[0]);
|
|
134
218
|
return 0;
|
|
135
219
|
}
|
|
136
220
|
|
|
137
221
|
int main(int argc, char *argv[])
|
|
138
222
|
{
|
|
139
223
|
int sp[2], pid, ring_fd, ret;
|
|
224
|
+
int i;
|
|
140
225
|
|
|
141
226
|
if (argc > 1)
|
|
142
227
|
return 0;
|
|
@@ -147,6 +232,18 @@ int main(int argc, char *argv[])
|
|
|
147
232
|
return 1;
|
|
148
233
|
}
|
|
149
234
|
|
|
235
|
+
for (i = 0; i < 2; i++) {
|
|
236
|
+
bool update = !!(i & 1);
|
|
237
|
+
|
|
238
|
+
ret = test_scm_cycles(update);
|
|
239
|
+
if (ret) {
|
|
240
|
+
fprintf(stderr, "test_scm_cycles() failed %i\n",
|
|
241
|
+
update);
|
|
242
|
+
return 1;
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
|
|
150
247
|
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sp) != 0) {
|
|
151
248
|
perror("Failed to create Unix-domain socket pair\n");
|
|
152
249
|
return 1;
|