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
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
#include <stdlib.h>
|
|
8
8
|
#include <stdint.h>
|
|
9
9
|
#include <assert.h>
|
|
10
|
+
#include <limits.h>
|
|
10
11
|
|
|
11
12
|
#include <errno.h>
|
|
12
13
|
#include <fcntl.h>
|
|
@@ -22,13 +23,43 @@
|
|
|
22
23
|
#include "helpers.h"
|
|
23
24
|
#include "liburing.h"
|
|
24
25
|
|
|
26
|
+
#define MAX_FDS 32
|
|
27
|
+
#define NOP_USER_DATA (1LLU << 50)
|
|
28
|
+
#define INITIAL_USER_DATA 1000
|
|
29
|
+
|
|
25
30
|
static int no_accept;
|
|
31
|
+
static int no_accept_multi;
|
|
26
32
|
|
|
27
33
|
struct data {
|
|
28
34
|
char buf[128];
|
|
29
35
|
struct iovec iov;
|
|
30
36
|
};
|
|
31
37
|
|
|
38
|
+
struct accept_test_args {
|
|
39
|
+
int accept_should_error;
|
|
40
|
+
bool fixed;
|
|
41
|
+
bool nonblock;
|
|
42
|
+
bool queue_accept_before_connect;
|
|
43
|
+
bool multishot;
|
|
44
|
+
int extra_loops;
|
|
45
|
+
bool overflow;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
static void close_fds(int fds[], int nr)
|
|
49
|
+
{
|
|
50
|
+
int i;
|
|
51
|
+
|
|
52
|
+
for (i = 0; i < nr; i++)
|
|
53
|
+
close(fds[i]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static void close_sock_fds(int s_fd[], int c_fd[], int nr, bool fixed)
|
|
57
|
+
{
|
|
58
|
+
if (!fixed)
|
|
59
|
+
close_fds(s_fd, nr);
|
|
60
|
+
close_fds(c_fd, nr);
|
|
61
|
+
}
|
|
62
|
+
|
|
32
63
|
static void queue_send(struct io_uring *ring, int fd)
|
|
33
64
|
{
|
|
34
65
|
struct io_uring_sqe *sqe;
|
|
@@ -59,30 +90,83 @@ static void queue_recv(struct io_uring *ring, int fd, bool fixed)
|
|
|
59
90
|
sqe->flags |= IOSQE_FIXED_FILE;
|
|
60
91
|
}
|
|
61
92
|
|
|
62
|
-
static
|
|
93
|
+
static void queue_accept_multishot(struct io_uring *ring, int fd,
|
|
94
|
+
int idx, bool fixed)
|
|
63
95
|
{
|
|
64
|
-
struct io_uring_sqe *sqe;
|
|
65
|
-
|
|
66
|
-
int ret, fixed_idx = 0;
|
|
96
|
+
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
|
|
97
|
+
int ret;
|
|
67
98
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
99
|
+
if (fixed)
|
|
100
|
+
io_uring_prep_multishot_accept_direct(sqe, fd,
|
|
101
|
+
NULL, NULL,
|
|
102
|
+
0);
|
|
71
103
|
else
|
|
72
|
-
|
|
104
|
+
io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0);
|
|
73
105
|
|
|
106
|
+
io_uring_sqe_set_data64(sqe, idx);
|
|
74
107
|
ret = io_uring_submit(ring);
|
|
75
108
|
assert(ret != -1);
|
|
109
|
+
}
|
|
76
110
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
111
|
+
static void queue_accept_conn(struct io_uring *ring, int fd,
|
|
112
|
+
struct accept_test_args args)
|
|
113
|
+
{
|
|
114
|
+
struct io_uring_sqe *sqe;
|
|
115
|
+
int ret;
|
|
116
|
+
int fixed_idx = args.fixed ? 0 : -1;
|
|
117
|
+
int count = 1 + args.extra_loops;
|
|
118
|
+
|
|
119
|
+
if (args.multishot) {
|
|
120
|
+
queue_accept_multishot(ring, fd, INITIAL_USER_DATA, args.fixed);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
81
123
|
|
|
82
|
-
|
|
124
|
+
while (count--) {
|
|
125
|
+
sqe = io_uring_get_sqe(ring);
|
|
126
|
+
if (fixed_idx < 0) {
|
|
127
|
+
io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
|
|
128
|
+
} else {
|
|
129
|
+
io_uring_prep_accept_direct(sqe, fd, NULL, NULL,
|
|
130
|
+
0, fixed_idx);
|
|
131
|
+
}
|
|
132
|
+
ret = io_uring_submit(ring);
|
|
133
|
+
assert(ret != -1);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static int accept_conn(struct io_uring *ring, int fixed_idx, int *multishot, int fd)
|
|
138
|
+
{
|
|
139
|
+
struct io_uring_cqe *pcqe;
|
|
140
|
+
struct io_uring_cqe cqe;
|
|
141
|
+
int ret;
|
|
142
|
+
|
|
143
|
+
do {
|
|
144
|
+
ret = io_uring_wait_cqe(ring, &pcqe);
|
|
145
|
+
assert(!ret);
|
|
146
|
+
cqe = *pcqe;
|
|
147
|
+
io_uring_cqe_seen(ring, pcqe);
|
|
148
|
+
} while (cqe.user_data == NOP_USER_DATA);
|
|
149
|
+
|
|
150
|
+
if (*multishot) {
|
|
151
|
+
if (!(cqe.flags & IORING_CQE_F_MORE)) {
|
|
152
|
+
(*multishot)++;
|
|
153
|
+
queue_accept_multishot(ring, fd, *multishot, fixed_idx == 0);
|
|
154
|
+
} else {
|
|
155
|
+
if (cqe.user_data != *multishot) {
|
|
156
|
+
fprintf(stderr, "received multishot after told done!\n");
|
|
157
|
+
return -ECANCELED;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
ret = cqe.res;
|
|
163
|
+
|
|
164
|
+
if (fixed_idx >= 0) {
|
|
83
165
|
if (ret > 0) {
|
|
84
|
-
|
|
85
|
-
|
|
166
|
+
if (!multishot) {
|
|
167
|
+
close(ret);
|
|
168
|
+
return -EINVAL;
|
|
169
|
+
}
|
|
86
170
|
} else if (!ret) {
|
|
87
171
|
ret = fixed_idx;
|
|
88
172
|
}
|
|
@@ -90,11 +174,13 @@ static int accept_conn(struct io_uring *ring, int fd, bool fixed)
|
|
|
90
174
|
return ret;
|
|
91
175
|
}
|
|
92
176
|
|
|
93
|
-
static int start_accept_listen(struct sockaddr_in *addr, int port_off
|
|
177
|
+
static int start_accept_listen(struct sockaddr_in *addr, int port_off,
|
|
178
|
+
int extra_flags)
|
|
94
179
|
{
|
|
95
180
|
int fd, ret;
|
|
96
181
|
|
|
97
|
-
fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC,
|
|
182
|
+
fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC | extra_flags,
|
|
183
|
+
IPPROTO_TCP);
|
|
98
184
|
|
|
99
185
|
int32_t val = 1;
|
|
100
186
|
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
|
|
@@ -108,69 +194,148 @@ static int start_accept_listen(struct sockaddr_in *addr, int port_off)
|
|
|
108
194
|
addr = &laddr;
|
|
109
195
|
|
|
110
196
|
addr->sin_family = AF_INET;
|
|
111
|
-
addr->sin_port = htons(0x1235 + port_off);
|
|
112
197
|
addr->sin_addr.s_addr = inet_addr("127.0.0.1");
|
|
113
|
-
|
|
114
|
-
ret = bind(fd, (struct sockaddr*)addr, sizeof(*addr));
|
|
115
|
-
assert(ret != -1);
|
|
198
|
+
assert(!t_bind_ephemeral_port(fd, addr));
|
|
116
199
|
ret = listen(fd, 128);
|
|
117
200
|
assert(ret != -1);
|
|
118
201
|
|
|
119
202
|
return fd;
|
|
120
203
|
}
|
|
121
204
|
|
|
122
|
-
static int
|
|
205
|
+
static int set_client_fd(struct sockaddr_in *addr)
|
|
123
206
|
{
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
uint32_t head, count = 0;
|
|
127
|
-
int ret, p_fd[2], done = 0;
|
|
128
|
-
|
|
129
|
-
int32_t val, recv_s0 = start_accept_listen(&addr, 0);
|
|
207
|
+
int32_t val;
|
|
208
|
+
int fd, ret;
|
|
130
209
|
|
|
131
|
-
|
|
210
|
+
fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
|
|
132
211
|
|
|
133
212
|
val = 1;
|
|
134
|
-
ret = setsockopt(
|
|
213
|
+
ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
|
|
135
214
|
assert(ret != -1);
|
|
136
215
|
|
|
137
|
-
int32_t flags = fcntl(
|
|
216
|
+
int32_t flags = fcntl(fd, F_GETFL, 0);
|
|
138
217
|
assert(flags != -1);
|
|
139
218
|
|
|
140
219
|
flags |= O_NONBLOCK;
|
|
141
|
-
ret = fcntl(
|
|
220
|
+
ret = fcntl(fd, F_SETFL, flags);
|
|
142
221
|
assert(ret != -1);
|
|
143
222
|
|
|
144
|
-
ret = connect(
|
|
223
|
+
ret = connect(fd, (struct sockaddr *)addr, sizeof(*addr));
|
|
145
224
|
assert(ret == -1);
|
|
146
225
|
|
|
147
|
-
flags = fcntl(
|
|
226
|
+
flags = fcntl(fd, F_GETFL, 0);
|
|
148
227
|
assert(flags != -1);
|
|
149
228
|
|
|
150
229
|
flags &= ~O_NONBLOCK;
|
|
151
|
-
ret = fcntl(
|
|
230
|
+
ret = fcntl(fd, F_SETFL, flags);
|
|
152
231
|
assert(ret != -1);
|
|
153
232
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
233
|
+
return fd;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
static void cause_overflow(struct io_uring *ring)
|
|
237
|
+
{
|
|
238
|
+
int i, ret;
|
|
239
|
+
|
|
240
|
+
for (i = 0; i < ring->cq.ring_entries; i++) {
|
|
241
|
+
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
|
|
242
|
+
|
|
243
|
+
io_uring_prep_nop(sqe);
|
|
244
|
+
io_uring_sqe_set_data64(sqe, NOP_USER_DATA);
|
|
245
|
+
ret = io_uring_submit(ring);
|
|
246
|
+
assert(ret != -1);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
static void clear_overflow(struct io_uring *ring)
|
|
252
|
+
{
|
|
253
|
+
struct io_uring_cqe *cqe;
|
|
254
|
+
|
|
255
|
+
while (!io_uring_peek_cqe(ring, &cqe)) {
|
|
256
|
+
if (cqe->user_data != NOP_USER_DATA)
|
|
257
|
+
break;
|
|
258
|
+
io_uring_cqe_seen(ring, cqe);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
static int test_loop(struct io_uring *ring,
|
|
263
|
+
struct accept_test_args args,
|
|
264
|
+
int recv_s0,
|
|
265
|
+
struct sockaddr_in *addr)
|
|
266
|
+
{
|
|
267
|
+
struct io_uring_cqe *cqe;
|
|
268
|
+
uint32_t head, count = 0;
|
|
269
|
+
int i, ret, s_fd[MAX_FDS], c_fd[MAX_FDS], done = 0;
|
|
270
|
+
bool fixed = args.fixed;
|
|
271
|
+
bool multishot = args.multishot;
|
|
272
|
+
uint32_t multishot_mask = 0;
|
|
273
|
+
int nr_fds = multishot ? MAX_FDS : 1;
|
|
274
|
+
int multishot_idx = multishot ? INITIAL_USER_DATA : 0;
|
|
275
|
+
|
|
276
|
+
if (args.overflow)
|
|
277
|
+
cause_overflow(ring);
|
|
278
|
+
|
|
279
|
+
for (i = 0; i < nr_fds; i++) {
|
|
280
|
+
c_fd[i] = set_client_fd(addr);
|
|
281
|
+
if (args.overflow && i == nr_fds / 2)
|
|
282
|
+
clear_overflow(ring);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!args.queue_accept_before_connect)
|
|
286
|
+
queue_accept_conn(ring, recv_s0, args);
|
|
287
|
+
|
|
288
|
+
for (i = 0; i < nr_fds; i++) {
|
|
289
|
+
s_fd[i] = accept_conn(ring, fixed ? 0 : -1, &multishot_idx, recv_s0);
|
|
290
|
+
if (s_fd[i] == -EINVAL) {
|
|
291
|
+
if (args.accept_should_error)
|
|
292
|
+
goto out;
|
|
293
|
+
fprintf(stdout,
|
|
294
|
+
"%s %s Accept not supported, skipping\n",
|
|
295
|
+
fixed ? "Fixed" : "",
|
|
296
|
+
multishot ? "Multishot" : "");
|
|
297
|
+
if (multishot)
|
|
298
|
+
no_accept_multi = 1;
|
|
299
|
+
else
|
|
300
|
+
no_accept = 1;
|
|
157
301
|
goto out;
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
302
|
+
} else if (s_fd[i] < 0) {
|
|
303
|
+
if (args.accept_should_error &&
|
|
304
|
+
(s_fd[i] == -EBADF || s_fd[i] == -EINVAL))
|
|
305
|
+
goto out;
|
|
306
|
+
fprintf(stderr, "%s %s Accept[%d] got %d\n",
|
|
307
|
+
fixed ? "Fixed" : "",
|
|
308
|
+
multishot ? "Multishot" : "",
|
|
309
|
+
i, s_fd[i]);
|
|
310
|
+
goto err;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (multishot && fixed) {
|
|
314
|
+
if (s_fd[i] >= MAX_FDS) {
|
|
315
|
+
fprintf(stderr,
|
|
316
|
+
"Fixed Multishot Accept[%d] got outbound index: %d\n",
|
|
317
|
+
i, s_fd[i]);
|
|
318
|
+
goto err;
|
|
319
|
+
}
|
|
320
|
+
/*
|
|
321
|
+
* for fixed multishot accept test, the file slots
|
|
322
|
+
* allocated are [0, 32), this means we finally end up
|
|
323
|
+
* with each bit of a u32 being 1.
|
|
324
|
+
*/
|
|
325
|
+
multishot_mask |= (1U << s_fd[i]);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (multishot) {
|
|
330
|
+
if (fixed && (~multishot_mask != 0U)) {
|
|
331
|
+
fprintf(stderr, "Fixed Multishot Accept misses events\n");
|
|
332
|
+
goto err;
|
|
333
|
+
}
|
|
163
334
|
goto out;
|
|
164
|
-
} else if (p_fd[0] < 0) {
|
|
165
|
-
if (accept_should_error &&
|
|
166
|
-
(p_fd[0] == -EBADF || p_fd[0] == -EINVAL))
|
|
167
|
-
goto out;
|
|
168
|
-
fprintf(stderr, "Accept got %d\n", p_fd[0]);
|
|
169
|
-
goto err;
|
|
170
335
|
}
|
|
171
336
|
|
|
172
|
-
queue_send(ring,
|
|
173
|
-
queue_recv(ring,
|
|
337
|
+
queue_send(ring, c_fd[0]);
|
|
338
|
+
queue_recv(ring, s_fd[0], fixed);
|
|
174
339
|
|
|
175
340
|
ret = io_uring_submit_and_wait(ring, 2);
|
|
176
341
|
assert(ret != -1);
|
|
@@ -194,19 +359,32 @@ static int test(struct io_uring *ring, int accept_should_error, bool fixed)
|
|
|
194
359
|
}
|
|
195
360
|
|
|
196
361
|
out:
|
|
197
|
-
|
|
198
|
-
close(p_fd[0]);
|
|
199
|
-
close(p_fd[1]);
|
|
200
|
-
close(recv_s0);
|
|
362
|
+
close_sock_fds(s_fd, c_fd, nr_fds, fixed);
|
|
201
363
|
return 0;
|
|
202
364
|
err:
|
|
203
|
-
|
|
204
|
-
close(p_fd[0]);
|
|
205
|
-
close(p_fd[1]);
|
|
206
|
-
close(recv_s0);
|
|
365
|
+
close_sock_fds(s_fd, c_fd, nr_fds, fixed);
|
|
207
366
|
return 1;
|
|
208
367
|
}
|
|
209
368
|
|
|
369
|
+
static int test(struct io_uring *ring, struct accept_test_args args)
|
|
370
|
+
{
|
|
371
|
+
struct sockaddr_in addr;
|
|
372
|
+
int ret = 0;
|
|
373
|
+
int loop;
|
|
374
|
+
int32_t recv_s0 = start_accept_listen(&addr, 0,
|
|
375
|
+
args.nonblock ? O_NONBLOCK : 0);
|
|
376
|
+
if (args.queue_accept_before_connect)
|
|
377
|
+
queue_accept_conn(ring, recv_s0, args);
|
|
378
|
+
for (loop = 0; loop < 1 + args.extra_loops; loop++) {
|
|
379
|
+
ret = test_loop(ring, args, recv_s0, &addr);
|
|
380
|
+
if (ret)
|
|
381
|
+
break;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
close(recv_s0);
|
|
385
|
+
return ret;
|
|
386
|
+
}
|
|
387
|
+
|
|
210
388
|
static void sig_alrm(int sig)
|
|
211
389
|
{
|
|
212
390
|
exit(0);
|
|
@@ -222,7 +400,7 @@ static int test_accept_pending_on_exit(void)
|
|
|
222
400
|
ret = io_uring_queue_init(32, &m_io_uring, 0);
|
|
223
401
|
assert(ret >= 0);
|
|
224
402
|
|
|
225
|
-
fd = start_accept_listen(NULL, 0);
|
|
403
|
+
fd = start_accept_listen(NULL, 0, 0);
|
|
226
404
|
|
|
227
405
|
sqe = io_uring_get_sqe(&m_io_uring);
|
|
228
406
|
io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
|
|
@@ -239,10 +417,17 @@ static int test_accept_pending_on_exit(void)
|
|
|
239
417
|
return 0;
|
|
240
418
|
}
|
|
241
419
|
|
|
420
|
+
struct test_accept_many_args {
|
|
421
|
+
unsigned int usecs;
|
|
422
|
+
bool nonblock;
|
|
423
|
+
bool single_sock;
|
|
424
|
+
bool close_fds;
|
|
425
|
+
};
|
|
426
|
+
|
|
242
427
|
/*
|
|
243
428
|
* Test issue many accepts and see if we handle cancellation on exit
|
|
244
429
|
*/
|
|
245
|
-
static int test_accept_many(
|
|
430
|
+
static int test_accept_many(struct test_accept_many_args args)
|
|
246
431
|
{
|
|
247
432
|
struct io_uring m_io_uring;
|
|
248
433
|
struct io_uring_cqe *cqe;
|
|
@@ -250,6 +435,8 @@ static int test_accept_many(unsigned nr, unsigned usecs)
|
|
|
250
435
|
unsigned long cur_lim;
|
|
251
436
|
struct rlimit rlim;
|
|
252
437
|
int *fds, i, ret;
|
|
438
|
+
unsigned int nr = 128;
|
|
439
|
+
int nr_socks = args.single_sock ? 1 : nr;
|
|
253
440
|
|
|
254
441
|
if (getrlimit(RLIMIT_NPROC, &rlim) < 0) {
|
|
255
442
|
perror("getrlimit");
|
|
@@ -267,31 +454,39 @@ static int test_accept_many(unsigned nr, unsigned usecs)
|
|
|
267
454
|
ret = io_uring_queue_init(2 * nr, &m_io_uring, 0);
|
|
268
455
|
assert(ret >= 0);
|
|
269
456
|
|
|
270
|
-
fds = t_calloc(
|
|
457
|
+
fds = t_calloc(nr_socks, sizeof(int));
|
|
271
458
|
|
|
272
|
-
for (i = 0; i <
|
|
273
|
-
fds[i] = start_accept_listen(NULL, i
|
|
459
|
+
for (i = 0; i < nr_socks; i++)
|
|
460
|
+
fds[i] = start_accept_listen(NULL, i,
|
|
461
|
+
args.nonblock ? O_NONBLOCK : 0);
|
|
274
462
|
|
|
275
463
|
for (i = 0; i < nr; i++) {
|
|
464
|
+
int sock_idx = args.single_sock ? 0 : i;
|
|
276
465
|
sqe = io_uring_get_sqe(&m_io_uring);
|
|
277
|
-
io_uring_prep_accept(sqe, fds[
|
|
466
|
+
io_uring_prep_accept(sqe, fds[sock_idx], NULL, NULL, 0);
|
|
278
467
|
sqe->user_data = 1 + i;
|
|
279
468
|
ret = io_uring_submit(&m_io_uring);
|
|
280
469
|
assert(ret == 1);
|
|
281
470
|
}
|
|
282
471
|
|
|
283
|
-
if (usecs)
|
|
284
|
-
usleep(usecs);
|
|
472
|
+
if (args.usecs)
|
|
473
|
+
usleep(args.usecs);
|
|
474
|
+
|
|
475
|
+
if (args.close_fds)
|
|
476
|
+
for (i = 0; i < nr_socks; i++)
|
|
477
|
+
close(fds[i]);
|
|
285
478
|
|
|
286
479
|
for (i = 0; i < nr; i++) {
|
|
287
480
|
if (io_uring_peek_cqe(&m_io_uring, &cqe))
|
|
288
481
|
break;
|
|
289
482
|
if (cqe->res != -ECANCELED) {
|
|
290
|
-
fprintf(stderr, "Expected cqe to be cancelled\n");
|
|
291
|
-
|
|
483
|
+
fprintf(stderr, "Expected cqe to be cancelled %d\n", cqe->res);
|
|
484
|
+
ret = 1;
|
|
485
|
+
goto out;
|
|
292
486
|
}
|
|
293
487
|
io_uring_cqe_seen(&m_io_uring, cqe);
|
|
294
488
|
}
|
|
489
|
+
ret = 0;
|
|
295
490
|
out:
|
|
296
491
|
rlim.rlim_cur = cur_lim;
|
|
297
492
|
if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
|
|
@@ -301,40 +496,46 @@ out:
|
|
|
301
496
|
|
|
302
497
|
free(fds);
|
|
303
498
|
io_uring_queue_exit(&m_io_uring);
|
|
304
|
-
return
|
|
305
|
-
err:
|
|
306
|
-
ret = 1;
|
|
307
|
-
goto out;
|
|
499
|
+
return ret;
|
|
308
500
|
}
|
|
309
501
|
|
|
310
|
-
static int test_accept_cancel(unsigned usecs)
|
|
502
|
+
static int test_accept_cancel(unsigned usecs, unsigned int nr, bool multishot)
|
|
311
503
|
{
|
|
312
504
|
struct io_uring m_io_uring;
|
|
313
505
|
struct io_uring_cqe *cqe;
|
|
314
506
|
struct io_uring_sqe *sqe;
|
|
315
507
|
int fd, i, ret;
|
|
316
508
|
|
|
509
|
+
if (multishot && no_accept_multi)
|
|
510
|
+
return T_EXIT_SKIP;
|
|
511
|
+
|
|
317
512
|
ret = io_uring_queue_init(32, &m_io_uring, 0);
|
|
318
513
|
assert(ret >= 0);
|
|
319
514
|
|
|
320
|
-
fd = start_accept_listen(NULL, 0);
|
|
515
|
+
fd = start_accept_listen(NULL, 0, 0);
|
|
321
516
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
517
|
+
for (i = 1; i <= nr; i++) {
|
|
518
|
+
sqe = io_uring_get_sqe(&m_io_uring);
|
|
519
|
+
if (!multishot)
|
|
520
|
+
io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
|
|
521
|
+
else
|
|
522
|
+
io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0);
|
|
523
|
+
sqe->user_data = i;
|
|
524
|
+
ret = io_uring_submit(&m_io_uring);
|
|
525
|
+
assert(ret == 1);
|
|
526
|
+
}
|
|
327
527
|
|
|
328
528
|
if (usecs)
|
|
329
529
|
usleep(usecs);
|
|
330
530
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
531
|
+
for (i = 1; i <= nr; i++) {
|
|
532
|
+
sqe = io_uring_get_sqe(&m_io_uring);
|
|
533
|
+
io_uring_prep_cancel64(sqe, i, 0);
|
|
534
|
+
sqe->user_data = nr + i;
|
|
535
|
+
ret = io_uring_submit(&m_io_uring);
|
|
536
|
+
assert(ret == 1);
|
|
537
|
+
}
|
|
538
|
+
for (i = 0; i < nr * 2; i++) {
|
|
338
539
|
ret = io_uring_wait_cqe(&m_io_uring, &cqe);
|
|
339
540
|
assert(!ret);
|
|
340
541
|
/*
|
|
@@ -347,12 +548,15 @@ static int test_accept_cancel(unsigned usecs)
|
|
|
347
548
|
* should get '-EALREADY' for the cancel request and
|
|
348
549
|
* '-EINTR' for the accept request.
|
|
349
550
|
*/
|
|
350
|
-
if (cqe->user_data ==
|
|
551
|
+
if (cqe->user_data == 0) {
|
|
552
|
+
fprintf(stderr, "unexpected 0 user data\n");
|
|
553
|
+
goto err;
|
|
554
|
+
} else if (cqe->user_data <= nr) {
|
|
351
555
|
if (cqe->res != -EINTR && cqe->res != -ECANCELED) {
|
|
352
556
|
fprintf(stderr, "Cancelled accept got %d\n", cqe->res);
|
|
353
557
|
goto err;
|
|
354
558
|
}
|
|
355
|
-
} else if (cqe->user_data
|
|
559
|
+
} else if (cqe->user_data <= nr * 2) {
|
|
356
560
|
if (cqe->res != -EALREADY && cqe->res != 0) {
|
|
357
561
|
fprintf(stderr, "Cancel got %d\n", cqe->res);
|
|
358
562
|
goto err;
|
|
@@ -362,20 +566,101 @@ static int test_accept_cancel(unsigned usecs)
|
|
|
362
566
|
}
|
|
363
567
|
|
|
364
568
|
io_uring_queue_exit(&m_io_uring);
|
|
569
|
+
close(fd);
|
|
570
|
+
return 0;
|
|
571
|
+
err:
|
|
572
|
+
io_uring_queue_exit(&m_io_uring);
|
|
573
|
+
close(fd);
|
|
574
|
+
return 1;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
static int test_accept(int count, bool before)
|
|
578
|
+
{
|
|
579
|
+
struct io_uring m_io_uring;
|
|
580
|
+
int ret;
|
|
581
|
+
struct accept_test_args args = {
|
|
582
|
+
.queue_accept_before_connect = before,
|
|
583
|
+
.extra_loops = count - 1
|
|
584
|
+
};
|
|
585
|
+
|
|
586
|
+
ret = io_uring_queue_init(32, &m_io_uring, 0);
|
|
587
|
+
assert(ret >= 0);
|
|
588
|
+
ret = test(&m_io_uring, args);
|
|
589
|
+
io_uring_queue_exit(&m_io_uring);
|
|
590
|
+
return ret;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
static int test_multishot_accept(int count, bool before, bool overflow)
|
|
594
|
+
{
|
|
595
|
+
struct io_uring m_io_uring;
|
|
596
|
+
int ret;
|
|
597
|
+
struct accept_test_args args = {
|
|
598
|
+
.queue_accept_before_connect = before,
|
|
599
|
+
.multishot = true,
|
|
600
|
+
.extra_loops = count - 1,
|
|
601
|
+
.overflow = overflow
|
|
602
|
+
};
|
|
603
|
+
|
|
604
|
+
if (no_accept_multi)
|
|
605
|
+
return T_EXIT_SKIP;
|
|
606
|
+
|
|
607
|
+
ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
|
|
608
|
+
assert(ret >= 0);
|
|
609
|
+
ret = test(&m_io_uring, args);
|
|
610
|
+
io_uring_queue_exit(&m_io_uring);
|
|
611
|
+
return ret;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
static int test_accept_multishot_wrong_arg()
|
|
615
|
+
{
|
|
616
|
+
struct io_uring m_io_uring;
|
|
617
|
+
struct io_uring_cqe *cqe;
|
|
618
|
+
struct io_uring_sqe *sqe;
|
|
619
|
+
int fd, ret;
|
|
620
|
+
|
|
621
|
+
ret = io_uring_queue_init(4, &m_io_uring, 0);
|
|
622
|
+
assert(ret >= 0);
|
|
623
|
+
|
|
624
|
+
fd = start_accept_listen(NULL, 0, 0);
|
|
625
|
+
|
|
626
|
+
sqe = io_uring_get_sqe(&m_io_uring);
|
|
627
|
+
io_uring_prep_multishot_accept_direct(sqe, fd, NULL, NULL, 0);
|
|
628
|
+
sqe->file_index = 1;
|
|
629
|
+
ret = io_uring_submit(&m_io_uring);
|
|
630
|
+
assert(ret == 1);
|
|
631
|
+
|
|
632
|
+
ret = io_uring_wait_cqe(&m_io_uring, &cqe);
|
|
633
|
+
assert(!ret);
|
|
634
|
+
if (cqe->res != -EINVAL) {
|
|
635
|
+
fprintf(stderr, "file index should be IORING_FILE_INDEX_ALLOC \
|
|
636
|
+
if its accept in multishot direct mode\n");
|
|
637
|
+
goto err;
|
|
638
|
+
}
|
|
639
|
+
io_uring_cqe_seen(&m_io_uring, cqe);
|
|
640
|
+
|
|
641
|
+
io_uring_queue_exit(&m_io_uring);
|
|
642
|
+
close(fd);
|
|
365
643
|
return 0;
|
|
366
644
|
err:
|
|
367
645
|
io_uring_queue_exit(&m_io_uring);
|
|
646
|
+
close(fd);
|
|
368
647
|
return 1;
|
|
369
648
|
}
|
|
370
649
|
|
|
371
|
-
|
|
650
|
+
|
|
651
|
+
static int test_accept_nonblock(bool queue_before_connect, int count)
|
|
372
652
|
{
|
|
373
653
|
struct io_uring m_io_uring;
|
|
374
654
|
int ret;
|
|
655
|
+
struct accept_test_args args = {
|
|
656
|
+
.nonblock = true,
|
|
657
|
+
.queue_accept_before_connect = queue_before_connect,
|
|
658
|
+
.extra_loops = count - 1
|
|
659
|
+
};
|
|
375
660
|
|
|
376
661
|
ret = io_uring_queue_init(32, &m_io_uring, 0);
|
|
377
662
|
assert(ret >= 0);
|
|
378
|
-
ret = test(&m_io_uring,
|
|
663
|
+
ret = test(&m_io_uring, args);
|
|
379
664
|
io_uring_queue_exit(&m_io_uring);
|
|
380
665
|
return ret;
|
|
381
666
|
}
|
|
@@ -384,12 +669,37 @@ static int test_accept_fixed(void)
|
|
|
384
669
|
{
|
|
385
670
|
struct io_uring m_io_uring;
|
|
386
671
|
int ret, fd = -1;
|
|
672
|
+
struct accept_test_args args = {
|
|
673
|
+
.fixed = true
|
|
674
|
+
};
|
|
387
675
|
|
|
388
676
|
ret = io_uring_queue_init(32, &m_io_uring, 0);
|
|
389
677
|
assert(ret >= 0);
|
|
390
678
|
ret = io_uring_register_files(&m_io_uring, &fd, 1);
|
|
391
679
|
assert(ret == 0);
|
|
392
|
-
ret = test(&m_io_uring,
|
|
680
|
+
ret = test(&m_io_uring, args);
|
|
681
|
+
io_uring_queue_exit(&m_io_uring);
|
|
682
|
+
return ret;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
static int test_multishot_fixed_accept(void)
|
|
686
|
+
{
|
|
687
|
+
struct io_uring m_io_uring;
|
|
688
|
+
int ret, fd[MAX_FDS];
|
|
689
|
+
struct accept_test_args args = {
|
|
690
|
+
.fixed = true,
|
|
691
|
+
.multishot = true
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
if (no_accept_multi)
|
|
695
|
+
return T_EXIT_SKIP;
|
|
696
|
+
|
|
697
|
+
memset(fd, -1, sizeof(fd));
|
|
698
|
+
ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
|
|
699
|
+
assert(ret >= 0);
|
|
700
|
+
ret = io_uring_register_files(&m_io_uring, fd, MAX_FDS);
|
|
701
|
+
assert(ret == 0);
|
|
702
|
+
ret = test(&m_io_uring, args);
|
|
393
703
|
io_uring_queue_exit(&m_io_uring);
|
|
394
704
|
return ret;
|
|
395
705
|
}
|
|
@@ -398,7 +708,8 @@ static int test_accept_sqpoll(void)
|
|
|
398
708
|
{
|
|
399
709
|
struct io_uring m_io_uring;
|
|
400
710
|
struct io_uring_params p = { };
|
|
401
|
-
int ret
|
|
711
|
+
int ret;
|
|
712
|
+
struct accept_test_args args = { };
|
|
402
713
|
|
|
403
714
|
p.flags = IORING_SETUP_SQPOLL;
|
|
404
715
|
ret = t_create_ring_params(32, &m_io_uring, &p);
|
|
@@ -407,11 +718,11 @@ static int test_accept_sqpoll(void)
|
|
|
407
718
|
else if (ret < 0)
|
|
408
719
|
return ret;
|
|
409
720
|
|
|
410
|
-
|
|
721
|
+
args.accept_should_error = 1;
|
|
411
722
|
if (p.features & IORING_FEAT_SQPOLL_NONFIXED)
|
|
412
|
-
|
|
723
|
+
args.accept_should_error = 0;
|
|
413
724
|
|
|
414
|
-
ret = test(&m_io_uring,
|
|
725
|
+
ret = test(&m_io_uring, args);
|
|
415
726
|
io_uring_queue_exit(&m_io_uring);
|
|
416
727
|
return ret;
|
|
417
728
|
}
|
|
@@ -421,15 +732,44 @@ int main(int argc, char *argv[])
|
|
|
421
732
|
int ret;
|
|
422
733
|
|
|
423
734
|
if (argc > 1)
|
|
424
|
-
return
|
|
425
|
-
|
|
426
|
-
ret = test_accept();
|
|
735
|
+
return T_EXIT_SKIP;
|
|
736
|
+
ret = test_accept(1, false);
|
|
427
737
|
if (ret) {
|
|
428
738
|
fprintf(stderr, "test_accept failed\n");
|
|
429
739
|
return ret;
|
|
430
740
|
}
|
|
431
741
|
if (no_accept)
|
|
432
|
-
return
|
|
742
|
+
return T_EXIT_SKIP;
|
|
743
|
+
|
|
744
|
+
ret = test_accept(2, false);
|
|
745
|
+
if (ret) {
|
|
746
|
+
fprintf(stderr, "test_accept(2) failed\n");
|
|
747
|
+
return ret;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
ret = test_accept(2, true);
|
|
751
|
+
if (ret) {
|
|
752
|
+
fprintf(stderr, "test_accept(2, true) failed\n");
|
|
753
|
+
return ret;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
ret = test_accept_nonblock(false, 1);
|
|
757
|
+
if (ret) {
|
|
758
|
+
fprintf(stderr, "test_accept_nonblock failed\n");
|
|
759
|
+
return ret;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
ret = test_accept_nonblock(true, 1);
|
|
763
|
+
if (ret) {
|
|
764
|
+
fprintf(stderr, "test_accept_nonblock(before, 1) failed\n");
|
|
765
|
+
return ret;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
ret = test_accept_nonblock(true, 3);
|
|
769
|
+
if (ret) {
|
|
770
|
+
fprintf(stderr, "test_accept_nonblock(before,3) failed\n");
|
|
771
|
+
return ret;
|
|
772
|
+
}
|
|
433
773
|
|
|
434
774
|
ret = test_accept_fixed();
|
|
435
775
|
if (ret) {
|
|
@@ -437,41 +777,123 @@ int main(int argc, char *argv[])
|
|
|
437
777
|
return ret;
|
|
438
778
|
}
|
|
439
779
|
|
|
780
|
+
ret = test_multishot_fixed_accept();
|
|
781
|
+
if (ret) {
|
|
782
|
+
fprintf(stderr, "test_multishot_fixed_accept failed\n");
|
|
783
|
+
return ret;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
ret = test_accept_multishot_wrong_arg();
|
|
787
|
+
if (ret) {
|
|
788
|
+
fprintf(stderr, "test_accept_multishot_wrong_arg failed\n");
|
|
789
|
+
return ret;
|
|
790
|
+
}
|
|
791
|
+
|
|
440
792
|
ret = test_accept_sqpoll();
|
|
441
793
|
if (ret) {
|
|
442
794
|
fprintf(stderr, "test_accept_sqpoll failed\n");
|
|
443
795
|
return ret;
|
|
444
796
|
}
|
|
445
797
|
|
|
446
|
-
ret = test_accept_cancel(0);
|
|
798
|
+
ret = test_accept_cancel(0, 1, false);
|
|
447
799
|
if (ret) {
|
|
448
800
|
fprintf(stderr, "test_accept_cancel nodelay failed\n");
|
|
449
801
|
return ret;
|
|
450
802
|
}
|
|
451
803
|
|
|
452
|
-
ret = test_accept_cancel(10000);
|
|
804
|
+
ret = test_accept_cancel(10000, 1, false);
|
|
453
805
|
if (ret) {
|
|
454
806
|
fprintf(stderr, "test_accept_cancel delay failed\n");
|
|
455
807
|
return ret;
|
|
456
808
|
}
|
|
457
809
|
|
|
458
|
-
ret =
|
|
810
|
+
ret = test_accept_cancel(0, 4, false);
|
|
459
811
|
if (ret) {
|
|
460
|
-
fprintf(stderr, "
|
|
812
|
+
fprintf(stderr, "test_accept_cancel nodelay failed\n");
|
|
813
|
+
return ret;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
ret = test_accept_cancel(10000, 4, false);
|
|
817
|
+
if (ret) {
|
|
818
|
+
fprintf(stderr, "test_accept_cancel delay failed\n");
|
|
819
|
+
return ret;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
ret = test_accept_cancel(0, 1, true);
|
|
823
|
+
if (ret) {
|
|
824
|
+
fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
|
|
825
|
+
return ret;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
ret = test_accept_cancel(10000, 1, true);
|
|
829
|
+
if (ret) {
|
|
830
|
+
fprintf(stderr, "test_accept_cancel multishot delay failed\n");
|
|
831
|
+
return ret;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
ret = test_accept_cancel(0, 4, true);
|
|
835
|
+
if (ret) {
|
|
836
|
+
fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
|
|
461
837
|
return ret;
|
|
462
838
|
}
|
|
463
839
|
|
|
464
|
-
ret =
|
|
840
|
+
ret = test_accept_cancel(10000, 4, true);
|
|
841
|
+
if (ret) {
|
|
842
|
+
fprintf(stderr, "test_accept_cancel multishot delay failed\n");
|
|
843
|
+
return ret;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
ret = test_multishot_accept(1, true, true);
|
|
847
|
+
if (ret) {
|
|
848
|
+
fprintf(stderr, "test_multishot_accept(1, false, true) failed\n");
|
|
849
|
+
return ret;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
ret = test_multishot_accept(1, false, false);
|
|
853
|
+
if (ret) {
|
|
854
|
+
fprintf(stderr, "test_multishot_accept(1, false, false) failed\n");
|
|
855
|
+
return ret;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
ret = test_multishot_accept(1, true, false);
|
|
859
|
+
if (ret) {
|
|
860
|
+
fprintf(stderr, "test_multishot_accept(1, true, false) failed\n");
|
|
861
|
+
return ret;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
ret = test_accept_many((struct test_accept_many_args) {});
|
|
465
865
|
if (ret) {
|
|
466
866
|
fprintf(stderr, "test_accept_many failed\n");
|
|
467
867
|
return ret;
|
|
468
868
|
}
|
|
469
869
|
|
|
870
|
+
ret = test_accept_many((struct test_accept_many_args) {
|
|
871
|
+
.usecs = 100000 });
|
|
872
|
+
if (ret) {
|
|
873
|
+
fprintf(stderr, "test_accept_many(sleep) failed\n");
|
|
874
|
+
return ret;
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
ret = test_accept_many((struct test_accept_many_args) {
|
|
878
|
+
.nonblock = true });
|
|
879
|
+
if (ret) {
|
|
880
|
+
fprintf(stderr, "test_accept_many(nonblock) failed\n");
|
|
881
|
+
return ret;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
ret = test_accept_many((struct test_accept_many_args) {
|
|
885
|
+
.nonblock = true,
|
|
886
|
+
.single_sock = true,
|
|
887
|
+
.close_fds = true });
|
|
888
|
+
if (ret) {
|
|
889
|
+
fprintf(stderr, "test_accept_many(nonblock,close) failed\n");
|
|
890
|
+
return ret;
|
|
891
|
+
}
|
|
892
|
+
|
|
470
893
|
ret = test_accept_pending_on_exit();
|
|
471
894
|
if (ret) {
|
|
472
895
|
fprintf(stderr, "test_accept_pending_on_exit failed\n");
|
|
473
896
|
return ret;
|
|
474
897
|
}
|
|
475
|
-
|
|
476
|
-
return 0;
|
|
898
|
+
return T_EXIT_PASS;
|
|
477
899
|
}
|