uringmachine 0.1
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 +7 -0
- data/.github/dependabot.yml +12 -0
- data/.github/workflows/test.yml +35 -0
- data/.gitignore +59 -0
- data/.gitmodules +3 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +11 -0
- data/Rakefile +39 -0
- data/TODO.md +0 -0
- data/examples/echo_server.rb +52 -0
- data/examples/event_loop.rb +69 -0
- data/examples/fibers.rb +105 -0
- data/examples/http_server.rb +56 -0
- data/examples/http_server_multishot.rb +57 -0
- data/examples/http_server_simpler.rb +34 -0
- data/ext/um/extconf.rb +71 -0
- data/ext/um/iou.h +101 -0
- data/ext/um/op_ctx.c +138 -0
- data/ext/um/ring.c +755 -0
- data/ext/um/um.c +267 -0
- data/ext/um/um.h +97 -0
- data/ext/um/um_class.c +175 -0
- data/ext/um/um_ext.c +11 -0
- data/ext/um/um_op.c +87 -0
- data/ext/um/um_utils.c +23 -0
- data/lib/uringmachine/version.rb +3 -0
- data/lib/uringmachine.rb +8 -0
- data/test/helper.rb +70 -0
- data/test/test_iou.rb +876 -0
- data/test/test_um.rb +168 -0
- data/uringmachine.gemspec +27 -0
- data/vendor/liburing/.github/actions/codespell/stopwords +7 -0
- data/vendor/liburing/.github/pull_request_template.md +86 -0
- data/vendor/liburing/.github/workflows/build.yml +137 -0
- data/vendor/liburing/.github/workflows/codespell.yml +25 -0
- data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
- data/vendor/liburing/.gitignore +41 -0
- data/vendor/liburing/CHANGELOG +111 -0
- data/vendor/liburing/CITATION.cff +11 -0
- data/vendor/liburing/COPYING +502 -0
- data/vendor/liburing/COPYING.GPL +339 -0
- data/vendor/liburing/LICENSE +20 -0
- data/vendor/liburing/Makefile +96 -0
- data/vendor/liburing/Makefile.common +7 -0
- data/vendor/liburing/Makefile.quiet +11 -0
- data/vendor/liburing/README +106 -0
- data/vendor/liburing/SECURITY.md +6 -0
- data/vendor/liburing/configure +624 -0
- data/vendor/liburing/debian/README.Debian +7 -0
- data/vendor/liburing/debian/changelog +38 -0
- data/vendor/liburing/debian/control +39 -0
- data/vendor/liburing/debian/copyright +49 -0
- data/vendor/liburing/debian/liburing-dev.install +4 -0
- data/vendor/liburing/debian/liburing-dev.manpages +5 -0
- data/vendor/liburing/debian/liburing2.install +1 -0
- data/vendor/liburing/debian/liburing2.symbols +56 -0
- data/vendor/liburing/debian/patches/series +1 -0
- data/vendor/liburing/debian/rules +29 -0
- data/vendor/liburing/debian/source/format +1 -0
- data/vendor/liburing/debian/source/local-options +2 -0
- data/vendor/liburing/debian/source/options +1 -0
- data/vendor/liburing/debian/watch +3 -0
- data/vendor/liburing/examples/Makefile +53 -0
- data/vendor/liburing/examples/helpers.c +62 -0
- data/vendor/liburing/examples/helpers.h +7 -0
- data/vendor/liburing/examples/io_uring-close-test.c +123 -0
- data/vendor/liburing/examples/io_uring-cp.c +282 -0
- data/vendor/liburing/examples/io_uring-test.c +112 -0
- data/vendor/liburing/examples/io_uring-udp.c +403 -0
- data/vendor/liburing/examples/link-cp.c +193 -0
- data/vendor/liburing/examples/napi-busy-poll-client.c +509 -0
- data/vendor/liburing/examples/napi-busy-poll-server.c +450 -0
- data/vendor/liburing/examples/poll-bench.c +101 -0
- data/vendor/liburing/examples/proxy.c +2461 -0
- data/vendor/liburing/examples/proxy.h +102 -0
- data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
- data/vendor/liburing/examples/send-zerocopy.c +658 -0
- data/vendor/liburing/examples/ucontext-cp.c +258 -0
- data/vendor/liburing/liburing-ffi.pc.in +12 -0
- data/vendor/liburing/liburing.pc.in +12 -0
- data/vendor/liburing/liburing.spec +66 -0
- data/vendor/liburing/make-debs.sh +55 -0
- data/vendor/liburing/src/Makefile +129 -0
- data/vendor/liburing/src/arch/aarch64/lib.h +47 -0
- data/vendor/liburing/src/arch/aarch64/syscall.h +91 -0
- data/vendor/liburing/src/arch/generic/lib.h +17 -0
- data/vendor/liburing/src/arch/generic/syscall.h +100 -0
- data/vendor/liburing/src/arch/riscv64/lib.h +48 -0
- data/vendor/liburing/src/arch/riscv64/syscall.h +100 -0
- data/vendor/liburing/src/arch/syscall-defs.h +94 -0
- data/vendor/liburing/src/arch/x86/lib.h +11 -0
- data/vendor/liburing/src/arch/x86/syscall.h +296 -0
- data/vendor/liburing/src/ffi.c +15 -0
- data/vendor/liburing/src/include/liburing/barrier.h +81 -0
- data/vendor/liburing/src/include/liburing/io_uring.h +818 -0
- data/vendor/liburing/src/include/liburing.h +1602 -0
- data/vendor/liburing/src/int_flags.h +11 -0
- data/vendor/liburing/src/lib.h +52 -0
- data/vendor/liburing/src/liburing-ffi.map +211 -0
- data/vendor/liburing/src/liburing.map +104 -0
- data/vendor/liburing/src/nolibc.c +55 -0
- data/vendor/liburing/src/queue.c +468 -0
- data/vendor/liburing/src/register.c +374 -0
- data/vendor/liburing/src/setup.c +689 -0
- data/vendor/liburing/src/setup.h +9 -0
- data/vendor/liburing/src/syscall.c +29 -0
- data/vendor/liburing/src/syscall.h +53 -0
- data/vendor/liburing/src/version.c +21 -0
- data/vendor/liburing/test/232c93d07b74.c +305 -0
- data/vendor/liburing/test/35fa71a030ca.c +329 -0
- data/vendor/liburing/test/500f9fbadef8.c +91 -0
- data/vendor/liburing/test/7ad0e4b2f83c.c +94 -0
- data/vendor/liburing/test/8a9973408177.c +107 -0
- data/vendor/liburing/test/917257daa0fe.c +54 -0
- data/vendor/liburing/test/Makefile +297 -0
- data/vendor/liburing/test/a0908ae19763.c +59 -0
- data/vendor/liburing/test/a4c0b3decb33.c +181 -0
- data/vendor/liburing/test/accept-link.c +255 -0
- data/vendor/liburing/test/accept-non-empty.c +256 -0
- data/vendor/liburing/test/accept-reuse.c +163 -0
- data/vendor/liburing/test/accept-test.c +83 -0
- data/vendor/liburing/test/accept.c +919 -0
- data/vendor/liburing/test/across-fork.c +284 -0
- data/vendor/liburing/test/b19062a56726.c +54 -0
- data/vendor/liburing/test/b5837bd5311d.c +78 -0
- data/vendor/liburing/test/bind-listen.c +408 -0
- data/vendor/liburing/test/buf-ring-nommap.c +123 -0
- data/vendor/liburing/test/buf-ring-put.c +83 -0
- data/vendor/liburing/test/buf-ring.c +473 -0
- data/vendor/liburing/test/ce593a6c480a.c +139 -0
- data/vendor/liburing/test/close-opath.c +123 -0
- data/vendor/liburing/test/config +14 -0
- data/vendor/liburing/test/connect-rep.c +204 -0
- data/vendor/liburing/test/connect.c +442 -0
- data/vendor/liburing/test/coredump.c +60 -0
- data/vendor/liburing/test/cq-full.c +97 -0
- data/vendor/liburing/test/cq-overflow.c +530 -0
- data/vendor/liburing/test/cq-peek-batch.c +103 -0
- data/vendor/liburing/test/cq-ready.c +95 -0
- data/vendor/liburing/test/cq-size.c +65 -0
- data/vendor/liburing/test/d4ae271dfaae.c +96 -0
- data/vendor/liburing/test/d77a67ed5f27.c +65 -0
- data/vendor/liburing/test/defer-taskrun.c +391 -0
- data/vendor/liburing/test/defer-tw-timeout.c +173 -0
- data/vendor/liburing/test/defer.c +319 -0
- data/vendor/liburing/test/double-poll-crash.c +195 -0
- data/vendor/liburing/test/drop-submit.c +94 -0
- data/vendor/liburing/test/eeed8b54e0df.c +120 -0
- data/vendor/liburing/test/empty-eownerdead.c +45 -0
- data/vendor/liburing/test/eploop.c +74 -0
- data/vendor/liburing/test/eventfd-disable.c +179 -0
- data/vendor/liburing/test/eventfd-reg.c +77 -0
- data/vendor/liburing/test/eventfd-ring.c +98 -0
- data/vendor/liburing/test/eventfd.c +113 -0
- data/vendor/liburing/test/evloop.c +73 -0
- data/vendor/liburing/test/exec-target.c +6 -0
- data/vendor/liburing/test/exit-no-cleanup.c +117 -0
- data/vendor/liburing/test/fadvise.c +202 -0
- data/vendor/liburing/test/fallocate.c +265 -0
- data/vendor/liburing/test/fc2a85cb02ef.c +132 -0
- data/vendor/liburing/test/fd-install.c +500 -0
- data/vendor/liburing/test/fd-pass.c +237 -0
- data/vendor/liburing/test/fdinfo.c +419 -0
- data/vendor/liburing/test/file-register.c +1189 -0
- data/vendor/liburing/test/file-update.c +231 -0
- data/vendor/liburing/test/file-verify.c +654 -0
- data/vendor/liburing/test/files-exit-hang-poll.c +114 -0
- data/vendor/liburing/test/files-exit-hang-timeout.c +137 -0
- data/vendor/liburing/test/fixed-buf-iter.c +115 -0
- data/vendor/liburing/test/fixed-buf-merge.c +101 -0
- data/vendor/liburing/test/fixed-hugepage.c +411 -0
- data/vendor/liburing/test/fixed-link.c +90 -0
- data/vendor/liburing/test/fixed-reuse.c +160 -0
- data/vendor/liburing/test/fpos.c +255 -0
- data/vendor/liburing/test/fsnotify.c +118 -0
- data/vendor/liburing/test/fsync.c +224 -0
- data/vendor/liburing/test/futex.c +571 -0
- data/vendor/liburing/test/hardlink.c +170 -0
- data/vendor/liburing/test/helpers.c +318 -0
- data/vendor/liburing/test/helpers.h +108 -0
- data/vendor/liburing/test/ignore-single-mmap.c +48 -0
- data/vendor/liburing/test/init-mem.c +164 -0
- data/vendor/liburing/test/io-cancel.c +561 -0
- data/vendor/liburing/test/io_uring_enter.c +264 -0
- data/vendor/liburing/test/io_uring_passthrough.c +482 -0
- data/vendor/liburing/test/io_uring_register.c +503 -0
- data/vendor/liburing/test/io_uring_setup.c +110 -0
- data/vendor/liburing/test/iopoll-leak.c +85 -0
- data/vendor/liburing/test/iopoll-overflow.c +118 -0
- data/vendor/liburing/test/iopoll.c +465 -0
- data/vendor/liburing/test/lfs-openat-write.c +119 -0
- data/vendor/liburing/test/lfs-openat.c +273 -0
- data/vendor/liburing/test/link-timeout.c +1108 -0
- data/vendor/liburing/test/link.c +497 -0
- data/vendor/liburing/test/link_drain.c +255 -0
- data/vendor/liburing/test/madvise.c +195 -0
- data/vendor/liburing/test/min-timeout-wait.c +354 -0
- data/vendor/liburing/test/min-timeout.c +233 -0
- data/vendor/liburing/test/mkdir.c +112 -0
- data/vendor/liburing/test/msg-ring-fd.c +331 -0
- data/vendor/liburing/test/msg-ring-flags.c +212 -0
- data/vendor/liburing/test/msg-ring-overflow.c +159 -0
- data/vendor/liburing/test/msg-ring.c +467 -0
- data/vendor/liburing/test/multicqes_drain.c +429 -0
- data/vendor/liburing/test/napi-test.c +215 -0
- data/vendor/liburing/test/napi-test.sh +48 -0
- data/vendor/liburing/test/no-mmap-inval.c +42 -0
- data/vendor/liburing/test/nolibc.c +62 -0
- data/vendor/liburing/test/nop-all-sizes.c +99 -0
- data/vendor/liburing/test/nop.c +177 -0
- data/vendor/liburing/test/nvme.h +169 -0
- data/vendor/liburing/test/ooo-file-unreg.c +82 -0
- data/vendor/liburing/test/open-close.c +261 -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 +312 -0
- data/vendor/liburing/test/personality.c +204 -0
- data/vendor/liburing/test/pipe-bug.c +95 -0
- data/vendor/liburing/test/pipe-eof.c +83 -0
- data/vendor/liburing/test/pipe-reuse.c +105 -0
- data/vendor/liburing/test/poll-cancel-all.c +496 -0
- data/vendor/liburing/test/poll-cancel-ton.c +135 -0
- data/vendor/liburing/test/poll-cancel.c +228 -0
- data/vendor/liburing/test/poll-link.c +221 -0
- data/vendor/liburing/test/poll-many.c +230 -0
- data/vendor/liburing/test/poll-mshot-overflow.c +265 -0
- data/vendor/liburing/test/poll-mshot-update.c +323 -0
- data/vendor/liburing/test/poll-race-mshot.c +276 -0
- data/vendor/liburing/test/poll-race.c +105 -0
- data/vendor/liburing/test/poll-ring.c +48 -0
- data/vendor/liburing/test/poll-v-poll.c +353 -0
- data/vendor/liburing/test/poll.c +327 -0
- data/vendor/liburing/test/probe.c +135 -0
- data/vendor/liburing/test/read-before-exit.c +129 -0
- data/vendor/liburing/test/read-mshot-empty.c +153 -0
- data/vendor/liburing/test/read-mshot.c +404 -0
- data/vendor/liburing/test/read-write.c +1013 -0
- data/vendor/liburing/test/recv-msgall-stream.c +398 -0
- data/vendor/liburing/test/recv-msgall.c +263 -0
- data/vendor/liburing/test/recv-multishot.c +602 -0
- data/vendor/liburing/test/recvsend_bundle.c +691 -0
- data/vendor/liburing/test/reg-fd-only.c +131 -0
- data/vendor/liburing/test/reg-hint.c +56 -0
- data/vendor/liburing/test/reg-reg-ring.c +90 -0
- data/vendor/liburing/test/regbuf-merge.c +91 -0
- data/vendor/liburing/test/register-restrictions.c +633 -0
- data/vendor/liburing/test/rename.c +132 -0
- data/vendor/liburing/test/ring-leak.c +283 -0
- data/vendor/liburing/test/ring-leak2.c +249 -0
- data/vendor/liburing/test/ringbuf-read.c +196 -0
- data/vendor/liburing/test/ringbuf-status.c +242 -0
- data/vendor/liburing/test/rsrc_tags.c +461 -0
- data/vendor/liburing/test/runtests-loop.sh +16 -0
- data/vendor/liburing/test/runtests-quiet.sh +11 -0
- data/vendor/liburing/test/runtests.sh +168 -0
- data/vendor/liburing/test/rw_merge_test.c +98 -0
- data/vendor/liburing/test/self.c +91 -0
- data/vendor/liburing/test/send-zerocopy.c +971 -0
- data/vendor/liburing/test/send_recv.c +412 -0
- data/vendor/liburing/test/send_recvmsg.c +444 -0
- data/vendor/liburing/test/shared-wq.c +84 -0
- data/vendor/liburing/test/short-read.c +75 -0
- data/vendor/liburing/test/shutdown.c +165 -0
- data/vendor/liburing/test/sigfd-deadlock.c +88 -0
- data/vendor/liburing/test/single-issuer.c +169 -0
- data/vendor/liburing/test/skip-cqe.c +428 -0
- data/vendor/liburing/test/socket-getsetsock-cmd.c +346 -0
- data/vendor/liburing/test/socket-io-cmd.c +237 -0
- data/vendor/liburing/test/socket-rw-eagain.c +149 -0
- data/vendor/liburing/test/socket-rw-offset.c +149 -0
- data/vendor/liburing/test/socket-rw.c +137 -0
- data/vendor/liburing/test/socket.c +408 -0
- data/vendor/liburing/test/splice.c +512 -0
- data/vendor/liburing/test/sq-full-cpp.cc +45 -0
- data/vendor/liburing/test/sq-full.c +45 -0
- data/vendor/liburing/test/sq-poll-dup.c +211 -0
- data/vendor/liburing/test/sq-poll-kthread.c +169 -0
- data/vendor/liburing/test/sq-poll-share.c +138 -0
- data/vendor/liburing/test/sq-space_left.c +159 -0
- data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
- data/vendor/liburing/test/sqpoll-exec.c +132 -0
- data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
- data/vendor/liburing/test/sqpoll-sleep.c +69 -0
- data/vendor/liburing/test/statx.c +172 -0
- data/vendor/liburing/test/stdout.c +232 -0
- data/vendor/liburing/test/submit-and-wait.c +108 -0
- data/vendor/liburing/test/submit-link-fail.c +156 -0
- data/vendor/liburing/test/submit-reuse.c +237 -0
- data/vendor/liburing/test/symlink.c +117 -0
- data/vendor/liburing/test/sync-cancel.c +235 -0
- data/vendor/liburing/test/teardowns.c +58 -0
- data/vendor/liburing/test/test.h +36 -0
- data/vendor/liburing/test/thread-exit.c +143 -0
- data/vendor/liburing/test/timeout-new.c +256 -0
- data/vendor/liburing/test/timeout.c +1798 -0
- data/vendor/liburing/test/truncate.c +186 -0
- data/vendor/liburing/test/tty-write-dpoll.c +60 -0
- data/vendor/liburing/test/unlink.c +112 -0
- data/vendor/liburing/test/version.c +25 -0
- data/vendor/liburing/test/wait-timeout.c +287 -0
- data/vendor/liburing/test/waitid.c +373 -0
- data/vendor/liburing/test/wakeup-hang.c +162 -0
- data/vendor/liburing/test/wq-aff.c +146 -0
- data/vendor/liburing/test/xattr.c +442 -0
- metadata +412 -0
|
@@ -0,0 +1,919 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Check that IORING_OP_ACCEPT works, and send some data across to verify we
|
|
4
|
+
* didn't get a junk fd.
|
|
5
|
+
*/
|
|
6
|
+
#include <stdio.h>
|
|
7
|
+
#include <stdlib.h>
|
|
8
|
+
#include <stdint.h>
|
|
9
|
+
#include <assert.h>
|
|
10
|
+
#include <limits.h>
|
|
11
|
+
|
|
12
|
+
#include <errno.h>
|
|
13
|
+
#include <fcntl.h>
|
|
14
|
+
#include <unistd.h>
|
|
15
|
+
#include <sys/socket.h>
|
|
16
|
+
#include <sys/time.h>
|
|
17
|
+
#include <sys/resource.h>
|
|
18
|
+
#include <sys/un.h>
|
|
19
|
+
#include <netinet/tcp.h>
|
|
20
|
+
#include <netinet/in.h>
|
|
21
|
+
#include <arpa/inet.h>
|
|
22
|
+
|
|
23
|
+
#include "helpers.h"
|
|
24
|
+
#include "liburing.h"
|
|
25
|
+
|
|
26
|
+
#define MAX_FDS 32
|
|
27
|
+
#define NOP_USER_DATA (1LLU << 50)
|
|
28
|
+
#define INITIAL_USER_DATA 1000
|
|
29
|
+
|
|
30
|
+
static int no_accept;
|
|
31
|
+
static int no_accept_multi;
|
|
32
|
+
|
|
33
|
+
struct data {
|
|
34
|
+
char buf[128];
|
|
35
|
+
struct iovec iov;
|
|
36
|
+
};
|
|
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
|
+
|
|
63
|
+
static void queue_send(struct io_uring *ring, int fd)
|
|
64
|
+
{
|
|
65
|
+
struct io_uring_sqe *sqe;
|
|
66
|
+
struct data *d;
|
|
67
|
+
|
|
68
|
+
d = t_malloc(sizeof(*d));
|
|
69
|
+
d->iov.iov_base = d->buf;
|
|
70
|
+
d->iov.iov_len = sizeof(d->buf);
|
|
71
|
+
|
|
72
|
+
sqe = io_uring_get_sqe(ring);
|
|
73
|
+
io_uring_prep_writev(sqe, fd, &d->iov, 1, 0);
|
|
74
|
+
sqe->user_data = 1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static void queue_recv(struct io_uring *ring, int fd, bool fixed)
|
|
78
|
+
{
|
|
79
|
+
struct io_uring_sqe *sqe;
|
|
80
|
+
struct data *d;
|
|
81
|
+
|
|
82
|
+
d = t_malloc(sizeof(*d));
|
|
83
|
+
d->iov.iov_base = d->buf;
|
|
84
|
+
d->iov.iov_len = sizeof(d->buf);
|
|
85
|
+
|
|
86
|
+
sqe = io_uring_get_sqe(ring);
|
|
87
|
+
io_uring_prep_readv(sqe, fd, &d->iov, 1, 0);
|
|
88
|
+
sqe->user_data = 2;
|
|
89
|
+
if (fixed)
|
|
90
|
+
sqe->flags |= IOSQE_FIXED_FILE;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static void queue_accept_multishot(struct io_uring *ring, int fd,
|
|
94
|
+
int idx, bool fixed)
|
|
95
|
+
{
|
|
96
|
+
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
|
|
97
|
+
int ret;
|
|
98
|
+
|
|
99
|
+
if (fixed)
|
|
100
|
+
io_uring_prep_multishot_accept_direct(sqe, fd,
|
|
101
|
+
NULL, NULL,
|
|
102
|
+
0);
|
|
103
|
+
else
|
|
104
|
+
io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0);
|
|
105
|
+
|
|
106
|
+
io_uring_sqe_set_data64(sqe, idx);
|
|
107
|
+
ret = io_uring_submit(ring);
|
|
108
|
+
assert(ret != -1);
|
|
109
|
+
}
|
|
110
|
+
|
|
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
|
+
}
|
|
123
|
+
|
|
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) {
|
|
165
|
+
if (ret > 0) {
|
|
166
|
+
if (!multishot) {
|
|
167
|
+
close(ret);
|
|
168
|
+
return -EINVAL;
|
|
169
|
+
}
|
|
170
|
+
} else if (!ret) {
|
|
171
|
+
ret = fixed_idx;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return ret;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static int start_accept_listen(struct sockaddr_in *addr, int port_off,
|
|
178
|
+
int extra_flags)
|
|
179
|
+
{
|
|
180
|
+
int fd, ret;
|
|
181
|
+
|
|
182
|
+
fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC | extra_flags,
|
|
183
|
+
IPPROTO_TCP);
|
|
184
|
+
|
|
185
|
+
int32_t val = 1;
|
|
186
|
+
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
|
|
187
|
+
assert(ret != -1);
|
|
188
|
+
ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
|
189
|
+
assert(ret != -1);
|
|
190
|
+
|
|
191
|
+
struct sockaddr_in laddr;
|
|
192
|
+
|
|
193
|
+
if (!addr)
|
|
194
|
+
addr = &laddr;
|
|
195
|
+
|
|
196
|
+
addr->sin_family = AF_INET;
|
|
197
|
+
addr->sin_addr.s_addr = inet_addr("127.0.0.1");
|
|
198
|
+
ret = t_bind_ephemeral_port(fd, addr);
|
|
199
|
+
assert(!ret);
|
|
200
|
+
ret = listen(fd, 128);
|
|
201
|
+
assert(ret != -1);
|
|
202
|
+
|
|
203
|
+
return fd;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
static int set_client_fd(struct sockaddr_in *addr)
|
|
207
|
+
{
|
|
208
|
+
int32_t val;
|
|
209
|
+
int fd, ret;
|
|
210
|
+
|
|
211
|
+
fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
|
|
212
|
+
|
|
213
|
+
val = 1;
|
|
214
|
+
ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
|
|
215
|
+
assert(ret != -1);
|
|
216
|
+
|
|
217
|
+
int32_t flags = fcntl(fd, F_GETFL, 0);
|
|
218
|
+
assert(flags != -1);
|
|
219
|
+
|
|
220
|
+
flags |= O_NONBLOCK;
|
|
221
|
+
ret = fcntl(fd, F_SETFL, flags);
|
|
222
|
+
assert(ret != -1);
|
|
223
|
+
|
|
224
|
+
ret = connect(fd, (struct sockaddr *)addr, sizeof(*addr));
|
|
225
|
+
assert(ret == -1);
|
|
226
|
+
|
|
227
|
+
flags = fcntl(fd, F_GETFL, 0);
|
|
228
|
+
assert(flags != -1);
|
|
229
|
+
|
|
230
|
+
flags &= ~O_NONBLOCK;
|
|
231
|
+
ret = fcntl(fd, F_SETFL, flags);
|
|
232
|
+
assert(ret != -1);
|
|
233
|
+
|
|
234
|
+
return fd;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
static void cause_overflow(struct io_uring *ring)
|
|
238
|
+
{
|
|
239
|
+
int i, ret;
|
|
240
|
+
|
|
241
|
+
for (i = 0; i < ring->cq.ring_entries; i++) {
|
|
242
|
+
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
|
|
243
|
+
|
|
244
|
+
io_uring_prep_nop(sqe);
|
|
245
|
+
io_uring_sqe_set_data64(sqe, NOP_USER_DATA);
|
|
246
|
+
ret = io_uring_submit(ring);
|
|
247
|
+
assert(ret != -1);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
static void clear_overflow(struct io_uring *ring)
|
|
253
|
+
{
|
|
254
|
+
struct io_uring_cqe *cqe;
|
|
255
|
+
|
|
256
|
+
while (!io_uring_peek_cqe(ring, &cqe)) {
|
|
257
|
+
if (cqe->user_data != NOP_USER_DATA)
|
|
258
|
+
break;
|
|
259
|
+
io_uring_cqe_seen(ring, cqe);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
static int test_loop(struct io_uring *ring,
|
|
264
|
+
struct accept_test_args args,
|
|
265
|
+
int recv_s0,
|
|
266
|
+
struct sockaddr_in *addr)
|
|
267
|
+
{
|
|
268
|
+
struct io_uring_cqe *cqe;
|
|
269
|
+
uint32_t head, count = 0;
|
|
270
|
+
int i, ret, s_fd[MAX_FDS], c_fd[MAX_FDS], done = 0;
|
|
271
|
+
bool fixed = args.fixed;
|
|
272
|
+
bool multishot = args.multishot;
|
|
273
|
+
uint32_t multishot_mask = 0;
|
|
274
|
+
int nr_fds = multishot ? MAX_FDS : 1;
|
|
275
|
+
int multishot_idx = multishot ? INITIAL_USER_DATA : 0;
|
|
276
|
+
int err_ret = T_EXIT_FAIL;
|
|
277
|
+
|
|
278
|
+
if (args.overflow)
|
|
279
|
+
cause_overflow(ring);
|
|
280
|
+
|
|
281
|
+
for (i = 0; i < nr_fds; i++) {
|
|
282
|
+
c_fd[i] = set_client_fd(addr);
|
|
283
|
+
if (args.overflow && i == nr_fds / 2)
|
|
284
|
+
clear_overflow(ring);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (!args.queue_accept_before_connect)
|
|
288
|
+
queue_accept_conn(ring, recv_s0, args);
|
|
289
|
+
|
|
290
|
+
for (i = 0; i < nr_fds; i++) {
|
|
291
|
+
s_fd[i] = accept_conn(ring, fixed ? 0 : -1, &multishot_idx, recv_s0);
|
|
292
|
+
if (s_fd[i] == -EINVAL) {
|
|
293
|
+
if (args.accept_should_error)
|
|
294
|
+
goto out;
|
|
295
|
+
fprintf(stdout,
|
|
296
|
+
"%s %s Accept not supported, skipping\n",
|
|
297
|
+
fixed ? "Fixed" : "",
|
|
298
|
+
multishot ? "Multishot" : "");
|
|
299
|
+
if (multishot)
|
|
300
|
+
no_accept_multi = 1;
|
|
301
|
+
else
|
|
302
|
+
no_accept = 1;
|
|
303
|
+
ret = T_EXIT_SKIP;
|
|
304
|
+
goto out;
|
|
305
|
+
} else if (s_fd[i] < 0) {
|
|
306
|
+
if (args.accept_should_error &&
|
|
307
|
+
(s_fd[i] == -EBADF || s_fd[i] == -EINVAL))
|
|
308
|
+
goto out;
|
|
309
|
+
fprintf(stderr, "%s %s Accept[%d] got %d\n",
|
|
310
|
+
fixed ? "Fixed" : "",
|
|
311
|
+
multishot ? "Multishot" : "",
|
|
312
|
+
i, s_fd[i]);
|
|
313
|
+
goto err;
|
|
314
|
+
} else if (s_fd[i] == 195 && args.overflow) {
|
|
315
|
+
fprintf(stderr, "Broken overflow handling\n");
|
|
316
|
+
goto err;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (multishot && fixed) {
|
|
320
|
+
if (s_fd[i] >= MAX_FDS) {
|
|
321
|
+
fprintf(stderr,
|
|
322
|
+
"Fixed Multishot Accept[%d] got outbound index: %d\n",
|
|
323
|
+
i, s_fd[i]);
|
|
324
|
+
goto err;
|
|
325
|
+
}
|
|
326
|
+
/*
|
|
327
|
+
* for fixed multishot accept test, the file slots
|
|
328
|
+
* allocated are [0, 32), this means we finally end up
|
|
329
|
+
* with each bit of a u32 being 1.
|
|
330
|
+
*/
|
|
331
|
+
multishot_mask |= (1U << s_fd[i]);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (multishot) {
|
|
336
|
+
if (fixed && (~multishot_mask != 0U)) {
|
|
337
|
+
fprintf(stderr, "Fixed Multishot Accept misses events\n");
|
|
338
|
+
goto err;
|
|
339
|
+
}
|
|
340
|
+
goto out;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
queue_send(ring, c_fd[0]);
|
|
344
|
+
queue_recv(ring, s_fd[0], fixed);
|
|
345
|
+
|
|
346
|
+
ret = io_uring_submit_and_wait(ring, 2);
|
|
347
|
+
assert(ret != -1);
|
|
348
|
+
|
|
349
|
+
while (count < 2) {
|
|
350
|
+
io_uring_for_each_cqe(ring, head, cqe) {
|
|
351
|
+
if (cqe->res < 0) {
|
|
352
|
+
fprintf(stderr, "Got cqe res %d, user_data %i\n",
|
|
353
|
+
cqe->res, (int)cqe->user_data);
|
|
354
|
+
done = 1;
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
assert(cqe->res == 128);
|
|
358
|
+
count++;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
assert(count <= 2);
|
|
362
|
+
io_uring_cq_advance(ring, count);
|
|
363
|
+
if (done)
|
|
364
|
+
goto err;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
out:
|
|
368
|
+
close_sock_fds(s_fd, c_fd, nr_fds, fixed);
|
|
369
|
+
return T_EXIT_PASS;
|
|
370
|
+
err:
|
|
371
|
+
close_sock_fds(s_fd, c_fd, nr_fds, fixed);
|
|
372
|
+
return err_ret;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
static int test(struct io_uring *ring, struct accept_test_args args)
|
|
376
|
+
{
|
|
377
|
+
struct sockaddr_in addr;
|
|
378
|
+
int ret = 0;
|
|
379
|
+
int loop;
|
|
380
|
+
int32_t recv_s0 = start_accept_listen(&addr, 0,
|
|
381
|
+
args.nonblock ? SOCK_NONBLOCK : 0);
|
|
382
|
+
if (args.queue_accept_before_connect)
|
|
383
|
+
queue_accept_conn(ring, recv_s0, args);
|
|
384
|
+
for (loop = 0; loop < 1 + args.extra_loops; loop++) {
|
|
385
|
+
ret = test_loop(ring, args, recv_s0, &addr);
|
|
386
|
+
if (ret)
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
close(recv_s0);
|
|
391
|
+
return ret;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
static void sig_alrm(int sig)
|
|
395
|
+
{
|
|
396
|
+
exit(0);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
static int test_accept_pending_on_exit(void)
|
|
400
|
+
{
|
|
401
|
+
struct io_uring m_io_uring;
|
|
402
|
+
struct io_uring_cqe *cqe;
|
|
403
|
+
struct io_uring_sqe *sqe;
|
|
404
|
+
int fd, ret;
|
|
405
|
+
|
|
406
|
+
ret = io_uring_queue_init(32, &m_io_uring, 0);
|
|
407
|
+
assert(ret >= 0);
|
|
408
|
+
|
|
409
|
+
fd = start_accept_listen(NULL, 0, 0);
|
|
410
|
+
|
|
411
|
+
sqe = io_uring_get_sqe(&m_io_uring);
|
|
412
|
+
io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
|
|
413
|
+
ret = io_uring_submit(&m_io_uring);
|
|
414
|
+
assert(ret != -1);
|
|
415
|
+
|
|
416
|
+
signal(SIGALRM, sig_alrm);
|
|
417
|
+
alarm(1);
|
|
418
|
+
ret = io_uring_wait_cqe(&m_io_uring, &cqe);
|
|
419
|
+
assert(!ret);
|
|
420
|
+
io_uring_cqe_seen(&m_io_uring, cqe);
|
|
421
|
+
|
|
422
|
+
io_uring_queue_exit(&m_io_uring);
|
|
423
|
+
return 0;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
struct test_accept_many_args {
|
|
427
|
+
unsigned int usecs;
|
|
428
|
+
bool nonblock;
|
|
429
|
+
bool single_sock;
|
|
430
|
+
bool close_fds;
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
/*
|
|
434
|
+
* Test issue many accepts and see if we handle cancelation on exit
|
|
435
|
+
*/
|
|
436
|
+
static int test_accept_many(struct test_accept_many_args args)
|
|
437
|
+
{
|
|
438
|
+
struct io_uring m_io_uring;
|
|
439
|
+
struct io_uring_cqe *cqe;
|
|
440
|
+
struct io_uring_sqe *sqe;
|
|
441
|
+
unsigned long cur_lim;
|
|
442
|
+
struct rlimit rlim;
|
|
443
|
+
int *fds, i, ret;
|
|
444
|
+
unsigned int nr = 128;
|
|
445
|
+
int nr_socks = args.single_sock ? 1 : nr;
|
|
446
|
+
|
|
447
|
+
if (getrlimit(RLIMIT_NPROC, &rlim) < 0) {
|
|
448
|
+
perror("getrlimit");
|
|
449
|
+
return 1;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
cur_lim = rlim.rlim_cur;
|
|
453
|
+
rlim.rlim_cur = nr / 4;
|
|
454
|
+
|
|
455
|
+
if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
|
|
456
|
+
perror("setrlimit");
|
|
457
|
+
return 1;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
ret = io_uring_queue_init(2 * nr, &m_io_uring, 0);
|
|
461
|
+
assert(ret >= 0);
|
|
462
|
+
|
|
463
|
+
fds = t_calloc(nr_socks, sizeof(int));
|
|
464
|
+
|
|
465
|
+
for (i = 0; i < nr_socks; i++)
|
|
466
|
+
fds[i] = start_accept_listen(NULL, i,
|
|
467
|
+
args.nonblock ? SOCK_NONBLOCK : 0);
|
|
468
|
+
|
|
469
|
+
for (i = 0; i < nr; i++) {
|
|
470
|
+
int sock_idx = args.single_sock ? 0 : i;
|
|
471
|
+
sqe = io_uring_get_sqe(&m_io_uring);
|
|
472
|
+
io_uring_prep_accept(sqe, fds[sock_idx], NULL, NULL, 0);
|
|
473
|
+
sqe->user_data = 1 + i;
|
|
474
|
+
ret = io_uring_submit(&m_io_uring);
|
|
475
|
+
assert(ret == 1);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if (args.usecs)
|
|
479
|
+
usleep(args.usecs);
|
|
480
|
+
|
|
481
|
+
if (args.close_fds)
|
|
482
|
+
for (i = 0; i < nr_socks; i++)
|
|
483
|
+
close(fds[i]);
|
|
484
|
+
|
|
485
|
+
for (i = 0; i < nr; i++) {
|
|
486
|
+
if (io_uring_peek_cqe(&m_io_uring, &cqe))
|
|
487
|
+
break;
|
|
488
|
+
if (cqe->res != -ECANCELED) {
|
|
489
|
+
fprintf(stderr, "Expected cqe to be canceled %d\n", cqe->res);
|
|
490
|
+
ret = 1;
|
|
491
|
+
goto out;
|
|
492
|
+
}
|
|
493
|
+
io_uring_cqe_seen(&m_io_uring, cqe);
|
|
494
|
+
}
|
|
495
|
+
ret = 0;
|
|
496
|
+
out:
|
|
497
|
+
rlim.rlim_cur = cur_lim;
|
|
498
|
+
if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
|
|
499
|
+
perror("setrlimit");
|
|
500
|
+
return 1;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
free(fds);
|
|
504
|
+
io_uring_queue_exit(&m_io_uring);
|
|
505
|
+
return ret;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
static int test_accept_cancel(unsigned usecs, unsigned int nr, bool multishot)
|
|
509
|
+
{
|
|
510
|
+
struct io_uring m_io_uring;
|
|
511
|
+
struct io_uring_cqe *cqe;
|
|
512
|
+
struct io_uring_sqe *sqe;
|
|
513
|
+
int fd, i, ret;
|
|
514
|
+
|
|
515
|
+
if (multishot && no_accept_multi)
|
|
516
|
+
return T_EXIT_SKIP;
|
|
517
|
+
|
|
518
|
+
ret = io_uring_queue_init(32, &m_io_uring, 0);
|
|
519
|
+
assert(ret >= 0);
|
|
520
|
+
|
|
521
|
+
fd = start_accept_listen(NULL, 0, 0);
|
|
522
|
+
|
|
523
|
+
for (i = 1; i <= nr; i++) {
|
|
524
|
+
sqe = io_uring_get_sqe(&m_io_uring);
|
|
525
|
+
if (!multishot)
|
|
526
|
+
io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
|
|
527
|
+
else
|
|
528
|
+
io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0);
|
|
529
|
+
sqe->user_data = i;
|
|
530
|
+
ret = io_uring_submit(&m_io_uring);
|
|
531
|
+
assert(ret == 1);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (usecs)
|
|
535
|
+
usleep(usecs);
|
|
536
|
+
|
|
537
|
+
for (i = 1; i <= nr; i++) {
|
|
538
|
+
sqe = io_uring_get_sqe(&m_io_uring);
|
|
539
|
+
io_uring_prep_cancel64(sqe, i, 0);
|
|
540
|
+
sqe->user_data = nr + i;
|
|
541
|
+
ret = io_uring_submit(&m_io_uring);
|
|
542
|
+
assert(ret == 1);
|
|
543
|
+
}
|
|
544
|
+
for (i = 0; i < nr * 2; i++) {
|
|
545
|
+
ret = io_uring_wait_cqe(&m_io_uring, &cqe);
|
|
546
|
+
assert(!ret);
|
|
547
|
+
/*
|
|
548
|
+
* Two cases here:
|
|
549
|
+
*
|
|
550
|
+
* 1) We cancel the accept4() before it got started, we should
|
|
551
|
+
* get '0' for the cancel request and '-ECANCELED' for the
|
|
552
|
+
* accept request.
|
|
553
|
+
* 2) We cancel the accept4() after it's already running, we
|
|
554
|
+
* should get '-EALREADY' for the cancel request and
|
|
555
|
+
* '-EINTR' for the accept request.
|
|
556
|
+
*/
|
|
557
|
+
if (cqe->user_data == 0) {
|
|
558
|
+
fprintf(stderr, "unexpected 0 user data\n");
|
|
559
|
+
goto err;
|
|
560
|
+
} else if (cqe->user_data <= nr) {
|
|
561
|
+
/* no multishot */
|
|
562
|
+
if (cqe->res == -EINVAL)
|
|
563
|
+
return T_EXIT_SKIP;
|
|
564
|
+
if (cqe->res != -EINTR && cqe->res != -ECANCELED) {
|
|
565
|
+
fprintf(stderr, "Cancelled accept got %d\n", cqe->res);
|
|
566
|
+
goto err;
|
|
567
|
+
}
|
|
568
|
+
} else if (cqe->user_data <= nr * 2) {
|
|
569
|
+
if (cqe->res != -EALREADY && cqe->res != 0) {
|
|
570
|
+
fprintf(stderr, "Cancel got %d\n", cqe->res);
|
|
571
|
+
goto err;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
io_uring_cqe_seen(&m_io_uring, cqe);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
io_uring_queue_exit(&m_io_uring);
|
|
578
|
+
close(fd);
|
|
579
|
+
return 0;
|
|
580
|
+
err:
|
|
581
|
+
io_uring_queue_exit(&m_io_uring);
|
|
582
|
+
close(fd);
|
|
583
|
+
return 1;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
static int test_accept(int count, bool before)
|
|
587
|
+
{
|
|
588
|
+
struct io_uring m_io_uring;
|
|
589
|
+
int ret;
|
|
590
|
+
struct accept_test_args args = {
|
|
591
|
+
.queue_accept_before_connect = before,
|
|
592
|
+
.extra_loops = count - 1
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
ret = io_uring_queue_init(32, &m_io_uring, 0);
|
|
596
|
+
assert(ret >= 0);
|
|
597
|
+
ret = test(&m_io_uring, args);
|
|
598
|
+
io_uring_queue_exit(&m_io_uring);
|
|
599
|
+
return ret;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
static int test_multishot_accept(int count, bool before, bool overflow)
|
|
603
|
+
{
|
|
604
|
+
struct io_uring m_io_uring;
|
|
605
|
+
int ret;
|
|
606
|
+
struct accept_test_args args = {
|
|
607
|
+
.queue_accept_before_connect = before,
|
|
608
|
+
.multishot = true,
|
|
609
|
+
.extra_loops = count - 1,
|
|
610
|
+
.overflow = overflow
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
if (no_accept_multi)
|
|
614
|
+
return T_EXIT_SKIP;
|
|
615
|
+
|
|
616
|
+
ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
|
|
617
|
+
assert(ret >= 0);
|
|
618
|
+
ret = test(&m_io_uring, args);
|
|
619
|
+
io_uring_queue_exit(&m_io_uring);
|
|
620
|
+
return ret;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
static int test_accept_multishot_wrong_arg(void)
|
|
624
|
+
{
|
|
625
|
+
struct io_uring m_io_uring;
|
|
626
|
+
struct io_uring_cqe *cqe;
|
|
627
|
+
struct io_uring_sqe *sqe;
|
|
628
|
+
int fd, ret;
|
|
629
|
+
|
|
630
|
+
ret = io_uring_queue_init(4, &m_io_uring, 0);
|
|
631
|
+
assert(ret >= 0);
|
|
632
|
+
|
|
633
|
+
fd = start_accept_listen(NULL, 0, 0);
|
|
634
|
+
|
|
635
|
+
sqe = io_uring_get_sqe(&m_io_uring);
|
|
636
|
+
io_uring_prep_multishot_accept_direct(sqe, fd, NULL, NULL, 0);
|
|
637
|
+
sqe->file_index = 1;
|
|
638
|
+
ret = io_uring_submit(&m_io_uring);
|
|
639
|
+
assert(ret == 1);
|
|
640
|
+
|
|
641
|
+
ret = io_uring_wait_cqe(&m_io_uring, &cqe);
|
|
642
|
+
assert(!ret);
|
|
643
|
+
if (cqe->res != -EINVAL) {
|
|
644
|
+
fprintf(stderr, "file index should be IORING_FILE_INDEX_ALLOC \
|
|
645
|
+
if its accept in multishot direct mode\n");
|
|
646
|
+
goto err;
|
|
647
|
+
}
|
|
648
|
+
io_uring_cqe_seen(&m_io_uring, cqe);
|
|
649
|
+
|
|
650
|
+
io_uring_queue_exit(&m_io_uring);
|
|
651
|
+
close(fd);
|
|
652
|
+
return 0;
|
|
653
|
+
err:
|
|
654
|
+
io_uring_queue_exit(&m_io_uring);
|
|
655
|
+
close(fd);
|
|
656
|
+
return 1;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
|
|
660
|
+
static int test_accept_nonblock(bool queue_before_connect, int count)
|
|
661
|
+
{
|
|
662
|
+
struct io_uring m_io_uring;
|
|
663
|
+
int ret;
|
|
664
|
+
struct accept_test_args args = {
|
|
665
|
+
.nonblock = true,
|
|
666
|
+
.queue_accept_before_connect = queue_before_connect,
|
|
667
|
+
.extra_loops = count - 1
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
ret = io_uring_queue_init(32, &m_io_uring, 0);
|
|
671
|
+
assert(ret >= 0);
|
|
672
|
+
ret = test(&m_io_uring, args);
|
|
673
|
+
io_uring_queue_exit(&m_io_uring);
|
|
674
|
+
return ret;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
static int test_accept_fixed(void)
|
|
678
|
+
{
|
|
679
|
+
struct io_uring m_io_uring;
|
|
680
|
+
int ret, fd = -1;
|
|
681
|
+
struct accept_test_args args = {
|
|
682
|
+
.fixed = true
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
ret = io_uring_queue_init(32, &m_io_uring, 0);
|
|
686
|
+
assert(ret >= 0);
|
|
687
|
+
ret = io_uring_register_files(&m_io_uring, &fd, 1);
|
|
688
|
+
if (ret) {
|
|
689
|
+
/* kernel doesn't support sparse registered files, skip */
|
|
690
|
+
if (ret == -EBADF || ret == -EINVAL)
|
|
691
|
+
return T_EXIT_SKIP;
|
|
692
|
+
return T_EXIT_FAIL;
|
|
693
|
+
}
|
|
694
|
+
ret = test(&m_io_uring, args);
|
|
695
|
+
io_uring_queue_exit(&m_io_uring);
|
|
696
|
+
return ret;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
static int test_multishot_fixed_accept(void)
|
|
700
|
+
{
|
|
701
|
+
struct io_uring m_io_uring;
|
|
702
|
+
int ret, fd[MAX_FDS];
|
|
703
|
+
struct accept_test_args args = {
|
|
704
|
+
.fixed = true,
|
|
705
|
+
.multishot = true
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
if (no_accept_multi)
|
|
709
|
+
return T_EXIT_SKIP;
|
|
710
|
+
|
|
711
|
+
memset(fd, -1, sizeof(fd));
|
|
712
|
+
ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
|
|
713
|
+
assert(ret >= 0);
|
|
714
|
+
ret = io_uring_register_files(&m_io_uring, fd, MAX_FDS);
|
|
715
|
+
if (ret) {
|
|
716
|
+
/* kernel doesn't support sparse registered files, skip */
|
|
717
|
+
if (ret == -EBADF || ret == -EINVAL)
|
|
718
|
+
return T_EXIT_SKIP;
|
|
719
|
+
return T_EXIT_FAIL;
|
|
720
|
+
}
|
|
721
|
+
ret = test(&m_io_uring, args);
|
|
722
|
+
io_uring_queue_exit(&m_io_uring);
|
|
723
|
+
return ret;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
static int test_accept_sqpoll(void)
|
|
727
|
+
{
|
|
728
|
+
struct io_uring m_io_uring;
|
|
729
|
+
struct io_uring_params p = { };
|
|
730
|
+
int ret;
|
|
731
|
+
struct accept_test_args args = { };
|
|
732
|
+
|
|
733
|
+
p.flags = IORING_SETUP_SQPOLL;
|
|
734
|
+
ret = t_create_ring_params(32, &m_io_uring, &p);
|
|
735
|
+
if (ret == T_SETUP_SKIP)
|
|
736
|
+
return 0;
|
|
737
|
+
else if (ret < 0)
|
|
738
|
+
return ret;
|
|
739
|
+
|
|
740
|
+
args.accept_should_error = 1;
|
|
741
|
+
if (p.features & IORING_FEAT_SQPOLL_NONFIXED)
|
|
742
|
+
args.accept_should_error = 0;
|
|
743
|
+
|
|
744
|
+
ret = test(&m_io_uring, args);
|
|
745
|
+
io_uring_queue_exit(&m_io_uring);
|
|
746
|
+
return ret;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
int main(int argc, char *argv[])
|
|
750
|
+
{
|
|
751
|
+
int ret;
|
|
752
|
+
|
|
753
|
+
if (argc > 1)
|
|
754
|
+
return T_EXIT_SKIP;
|
|
755
|
+
|
|
756
|
+
ret = test_accept(1, false);
|
|
757
|
+
if (ret == T_EXIT_FAIL) {
|
|
758
|
+
fprintf(stderr, "test_accept failed\n");
|
|
759
|
+
return ret;
|
|
760
|
+
}
|
|
761
|
+
if (no_accept)
|
|
762
|
+
return T_EXIT_SKIP;
|
|
763
|
+
|
|
764
|
+
ret = test_accept(2, false);
|
|
765
|
+
if (ret == T_EXIT_FAIL) {
|
|
766
|
+
fprintf(stderr, "test_accept(2) failed\n");
|
|
767
|
+
return ret;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
ret = test_accept(2, true);
|
|
771
|
+
if (ret == T_EXIT_FAIL) {
|
|
772
|
+
fprintf(stderr, "test_accept(2, true) failed\n");
|
|
773
|
+
return ret;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
ret = test_accept_nonblock(false, 1);
|
|
777
|
+
if (ret == T_EXIT_FAIL) {
|
|
778
|
+
fprintf(stderr, "test_accept_nonblock failed\n");
|
|
779
|
+
return ret;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
ret = test_accept_nonblock(true, 1);
|
|
783
|
+
if (ret == T_EXIT_FAIL) {
|
|
784
|
+
fprintf(stderr, "test_accept_nonblock(before, 1) failed\n");
|
|
785
|
+
return ret;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
ret = test_accept_nonblock(true, 3);
|
|
789
|
+
if (ret == T_EXIT_FAIL) {
|
|
790
|
+
fprintf(stderr, "test_accept_nonblock(before,3) failed\n");
|
|
791
|
+
return ret;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
ret = test_accept_fixed();
|
|
795
|
+
if (ret == T_EXIT_FAIL) {
|
|
796
|
+
fprintf(stderr, "test_accept_fixed failed\n");
|
|
797
|
+
return ret;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
ret = test_multishot_fixed_accept();
|
|
801
|
+
if (ret == T_EXIT_FAIL) {
|
|
802
|
+
fprintf(stderr, "test_multishot_fixed_accept failed\n");
|
|
803
|
+
return ret;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
ret = test_accept_multishot_wrong_arg();
|
|
807
|
+
if (ret == T_EXIT_FAIL) {
|
|
808
|
+
fprintf(stderr, "test_accept_multishot_wrong_arg failed\n");
|
|
809
|
+
return ret;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
ret = test_accept_sqpoll();
|
|
813
|
+
if (ret == T_EXIT_FAIL) {
|
|
814
|
+
fprintf(stderr, "test_accept_sqpoll failed\n");
|
|
815
|
+
return ret;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
ret = test_accept_cancel(0, 1, false);
|
|
819
|
+
if (ret == T_EXIT_FAIL) {
|
|
820
|
+
fprintf(stderr, "test_accept_cancel nodelay failed\n");
|
|
821
|
+
return ret;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
ret = test_accept_cancel(10000, 1, false);
|
|
825
|
+
if (ret == T_EXIT_FAIL) {
|
|
826
|
+
fprintf(stderr, "test_accept_cancel delay failed\n");
|
|
827
|
+
return ret;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
ret = test_accept_cancel(0, 4, false);
|
|
831
|
+
if (ret == T_EXIT_FAIL) {
|
|
832
|
+
fprintf(stderr, "test_accept_cancel nodelay failed\n");
|
|
833
|
+
return ret;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
ret = test_accept_cancel(10000, 4, false);
|
|
837
|
+
if (ret == T_EXIT_FAIL) {
|
|
838
|
+
fprintf(stderr, "test_accept_cancel delay failed\n");
|
|
839
|
+
return ret;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
ret = test_accept_cancel(0, 1, true);
|
|
843
|
+
if (ret == T_EXIT_FAIL) {
|
|
844
|
+
fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
|
|
845
|
+
return ret;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
ret = test_accept_cancel(10000, 1, true);
|
|
849
|
+
if (ret == T_EXIT_FAIL) {
|
|
850
|
+
fprintf(stderr, "test_accept_cancel multishot delay failed\n");
|
|
851
|
+
return ret;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
ret = test_accept_cancel(0, 4, true);
|
|
855
|
+
if (ret == T_EXIT_FAIL) {
|
|
856
|
+
fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
|
|
857
|
+
return ret;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
ret = test_accept_cancel(10000, 4, true);
|
|
861
|
+
if (ret == T_EXIT_FAIL) {
|
|
862
|
+
fprintf(stderr, "test_accept_cancel multishot delay failed\n");
|
|
863
|
+
return ret;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
ret = test_multishot_accept(1, true, true);
|
|
867
|
+
if (ret == T_EXIT_FAIL) {
|
|
868
|
+
fprintf(stderr, "test_multishot_accept(1, false, true) failed\n");
|
|
869
|
+
return ret;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
ret = test_multishot_accept(1, false, false);
|
|
873
|
+
if (ret == T_EXIT_FAIL) {
|
|
874
|
+
fprintf(stderr, "test_multishot_accept(1, false, false) failed\n");
|
|
875
|
+
return ret;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
ret = test_multishot_accept(1, true, false);
|
|
879
|
+
if (ret == T_EXIT_FAIL) {
|
|
880
|
+
fprintf(stderr, "test_multishot_accept(1, true, false) failed\n");
|
|
881
|
+
return ret;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
ret = test_accept_many((struct test_accept_many_args) {});
|
|
885
|
+
if (ret == T_EXIT_FAIL) {
|
|
886
|
+
fprintf(stderr, "test_accept_many failed\n");
|
|
887
|
+
return ret;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
ret = test_accept_many((struct test_accept_many_args) {
|
|
891
|
+
.usecs = 100000 });
|
|
892
|
+
if (ret == T_EXIT_FAIL) {
|
|
893
|
+
fprintf(stderr, "test_accept_many(sleep) failed\n");
|
|
894
|
+
return ret;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
ret = test_accept_many((struct test_accept_many_args) {
|
|
898
|
+
.nonblock = true });
|
|
899
|
+
if (ret == T_EXIT_FAIL) {
|
|
900
|
+
fprintf(stderr, "test_accept_many(nonblock) failed\n");
|
|
901
|
+
return ret;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
ret = test_accept_many((struct test_accept_many_args) {
|
|
905
|
+
.nonblock = true,
|
|
906
|
+
.single_sock = true,
|
|
907
|
+
.close_fds = true });
|
|
908
|
+
if (ret == T_EXIT_FAIL) {
|
|
909
|
+
fprintf(stderr, "test_accept_many(nonblock,close) failed\n");
|
|
910
|
+
return ret;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
ret = test_accept_pending_on_exit();
|
|
914
|
+
if (ret == T_EXIT_FAIL) {
|
|
915
|
+
fprintf(stderr, "test_accept_pending_on_exit failed\n");
|
|
916
|
+
return ret;
|
|
917
|
+
}
|
|
918
|
+
return T_EXIT_PASS;
|
|
919
|
+
}
|