polyphony 0.98 → 0.99.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 +4 -4
- data/.github/FUNDING.yml +1 -1
- data/.rubocop.yml +3 -3
- data/.yardopts +30 -0
- data/CHANGELOG.md +11 -0
- data/LICENSE +1 -1
- data/README.md +63 -29
- data/Rakefile +1 -5
- data/TODO.md +0 -4
- data/docs/{main-concepts/concurrency.md → concurrency.md} +2 -9
- data/docs/{main-concepts/design-principles.md → design-principles.md} +3 -9
- data/docs/{main-concepts/exception-handling.md → exception-handling.md} +2 -9
- data/docs/{main-concepts/extending.md → extending.md} +2 -9
- data/docs/faq.md +3 -16
- data/docs/{main-concepts/fiber-scheduling.md → fiber-scheduling.md} +1 -9
- data/docs/link_rewriter.rb +16 -0
- data/docs/{getting-started/overview.md → overview.md} +1 -30
- data/docs/{getting-started/tutorial.md → tutorial.md} +3 -28
- data/docs/{_posts/2020-07-26-polyphony-0.44.md → whats-new.md} +3 -1
- data/examples/adapters/redis_client.rb +3 -2
- data/examples/io/echo_server.rb +1 -1
- data/examples/io/echo_server_plain_ruby.rb +26 -0
- data/examples/io/https_server_sni_2.rb +14 -8
- data/ext/polyphony/backend_io_uring.c +154 -9
- data/ext/polyphony/backend_io_uring_context.c +21 -12
- data/ext/polyphony/backend_io_uring_context.h +12 -7
- data/ext/polyphony/backend_libev.c +1 -1
- data/ext/polyphony/extconf.rb +25 -8
- data/ext/polyphony/fiber.c +79 -2
- data/ext/polyphony/io_extensions.c +53 -0
- data/ext/polyphony/libev.h +0 -2
- data/ext/polyphony/pipe.c +42 -2
- data/ext/polyphony/polyphony.c +345 -31
- data/ext/polyphony/polyphony.h +9 -2
- data/ext/polyphony/queue.c +181 -0
- data/ext/polyphony/ring_buffer.c +0 -1
- data/ext/polyphony/runqueue.c +8 -1
- data/ext/polyphony/runqueue_ring_buffer.c +13 -0
- data/ext/polyphony/runqueue_ring_buffer.h +2 -1
- data/ext/polyphony/socket_extensions.c +6 -0
- data/ext/polyphony/thread.c +34 -2
- data/lib/polyphony/adapters/process.rb +11 -1
- data/lib/polyphony/adapters/sequel.rb +1 -1
- data/lib/polyphony/core/channel.rb +2 -0
- data/lib/polyphony/core/debug.rb +1 -1
- data/lib/polyphony/core/global_api.rb +25 -24
- data/lib/polyphony/core/resource_pool.rb +7 -6
- data/lib/polyphony/core/sync.rb +55 -2
- data/lib/polyphony/core/thread_pool.rb +3 -3
- data/lib/polyphony/core/timer.rb +8 -8
- data/lib/polyphony/extensions/exception.rb +2 -0
- data/lib/polyphony/extensions/fiber.rb +15 -13
- data/lib/polyphony/extensions/io.rb +161 -16
- data/lib/polyphony/extensions/kernel.rb +20 -2
- data/lib/polyphony/extensions/openssl.rb +101 -12
- data/lib/polyphony/extensions/pipe.rb +103 -7
- data/lib/polyphony/extensions/process.rb +13 -1
- data/lib/polyphony/extensions/socket.rb +93 -27
- data/lib/polyphony/extensions/thread.rb +9 -1
- data/lib/polyphony/extensions/timeout.rb +1 -1
- data/lib/polyphony/version.rb +2 -1
- data/lib/polyphony.rb +27 -7
- data/polyphony.gemspec +1 -8
- data/test/stress.rb +1 -1
- data/test/test_global_api.rb +45 -7
- data/test/test_io.rb +6 -7
- data/test/test_socket.rb +157 -0
- data/test/test_sync.rb +42 -1
- data/test/test_timer.rb +5 -5
- data/vendor/liburing/.github/workflows/build.yml +7 -16
- data/vendor/liburing/.gitignore +5 -0
- data/vendor/liburing/CHANGELOG +23 -1
- data/vendor/liburing/Makefile +4 -3
- data/vendor/liburing/Makefile.common +1 -0
- data/vendor/liburing/README +48 -0
- data/vendor/liburing/configure +76 -6
- data/vendor/liburing/debian/changelog +11 -0
- data/vendor/liburing/debian/control +7 -16
- data/vendor/liburing/debian/liburing-dev.manpages +3 -6
- data/vendor/liburing/debian/liburing2.install +1 -0
- data/vendor/liburing/debian/liburing2.symbols +56 -0
- data/vendor/liburing/debian/rules +15 -68
- data/vendor/liburing/examples/Makefile +4 -0
- data/vendor/liburing/examples/io_uring-close-test.c +123 -0
- data/vendor/liburing/examples/io_uring-udp.c +1 -1
- data/vendor/liburing/examples/send-zerocopy.c +315 -56
- data/vendor/liburing/examples/ucontext-cp.c +2 -17
- data/vendor/liburing/liburing-ffi.pc.in +12 -0
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/make-debs.sh +3 -3
- data/vendor/liburing/man/IO_URING_CHECK_VERSION.3 +1 -0
- data/vendor/liburing/man/IO_URING_VERSION_MAJOR.3 +1 -0
- data/vendor/liburing/man/IO_URING_VERSION_MINOR.3 +1 -0
- data/vendor/liburing/man/io_uring_buf_ring_add.3 +6 -6
- data/vendor/liburing/man/io_uring_check_version.3 +72 -0
- data/vendor/liburing/man/io_uring_close_ring_fd.3 +43 -0
- data/vendor/liburing/man/io_uring_major_version.3 +1 -0
- data/vendor/liburing/man/io_uring_minor_version.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_accept.3 +1 -1
- data/vendor/liburing/man/io_uring_prep_fgetxattr.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_fsetxattr.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_getxattr.3 +61 -0
- data/vendor/liburing/man/io_uring_prep_link_timeout.3 +94 -0
- data/vendor/liburing/man/io_uring_prep_msg_ring.3 +22 -2
- data/vendor/liburing/man/io_uring_prep_msg_ring_cqe_flags.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_poll_add.3 +1 -1
- data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +18 -9
- data/vendor/liburing/man/io_uring_prep_readv.3 +3 -3
- data/vendor/liburing/man/io_uring_prep_readv2.3 +3 -3
- data/vendor/liburing/man/io_uring_prep_recv.3 +5 -5
- data/vendor/liburing/man/io_uring_prep_recvmsg.3 +4 -4
- data/vendor/liburing/man/io_uring_prep_send.3 +9 -0
- data/vendor/liburing/man/io_uring_prep_send_set_addr.3 +38 -0
- data/vendor/liburing/man/io_uring_prep_send_zc.3 +39 -7
- data/vendor/liburing/man/io_uring_prep_send_zc_fixed.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_sendmsg.3 +20 -0
- data/vendor/liburing/man/io_uring_prep_sendmsg_zc.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_setxattr.3 +64 -0
- data/vendor/liburing/man/io_uring_prep_splice.3 +40 -0
- data/vendor/liburing/man/io_uring_prep_writev.3 +2 -2
- data/vendor/liburing/man/io_uring_prep_writev2.3 +2 -2
- data/vendor/liburing/man/io_uring_recvmsg_out.3 +13 -9
- data/vendor/liburing/man/io_uring_register.2 +15 -9
- data/vendor/liburing/man/io_uring_register_buf_ring.3 +4 -4
- data/vendor/liburing/man/io_uring_register_buffers.3 +49 -6
- data/vendor/liburing/man/io_uring_register_buffers_sparse.3 +1 -0
- data/vendor/liburing/man/io_uring_register_buffers_tags.3 +1 -0
- data/vendor/liburing/man/io_uring_register_buffers_update_tag.3 +1 -0
- data/vendor/liburing/man/io_uring_register_files.3 +60 -5
- data/vendor/liburing/man/io_uring_register_files_tags.3 +1 -0
- data/vendor/liburing/man/io_uring_register_files_update.3 +1 -0
- data/vendor/liburing/man/io_uring_register_files_update_tag.3 +1 -0
- data/vendor/liburing/man/io_uring_setup.2 +31 -2
- data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +1 -1
- data/vendor/liburing/src/Makefile +25 -3
- data/vendor/liburing/src/ffi.c +15 -0
- data/vendor/liburing/src/include/liburing/io_uring.h +30 -7
- data/vendor/liburing/src/include/liburing.h +190 -148
- data/vendor/liburing/src/int_flags.h +1 -0
- data/vendor/liburing/src/lib.h +5 -16
- data/vendor/liburing/src/liburing-ffi.map +172 -0
- data/vendor/liburing/src/liburing.map +11 -0
- data/vendor/liburing/src/nolibc.c +9 -2
- data/vendor/liburing/src/queue.c +2 -2
- data/vendor/liburing/src/register.c +66 -96
- data/vendor/liburing/src/setup.c +5 -4
- data/vendor/liburing/src/version.c +21 -0
- data/vendor/liburing/test/232c93d07b74.c +3 -3
- data/vendor/liburing/test/35fa71a030ca.c +3 -3
- data/vendor/liburing/test/500f9fbadef8.c +2 -0
- data/vendor/liburing/test/917257daa0fe.c +1 -1
- data/vendor/liburing/test/Makefile +27 -7
- data/vendor/liburing/test/a0908ae19763.c +2 -2
- data/vendor/liburing/test/a4c0b3decb33.c +2 -2
- data/vendor/liburing/test/accept-link.c +4 -4
- data/vendor/liburing/test/accept-reuse.c +5 -7
- data/vendor/liburing/test/accept.c +34 -31
- data/vendor/liburing/test/b19062a56726.c +1 -1
- data/vendor/liburing/test/buf-ring.c +58 -4
- data/vendor/liburing/test/ce593a6c480a.c +2 -2
- data/vendor/liburing/test/close-opath.c +2 -1
- data/vendor/liburing/test/connect.c +8 -0
- data/vendor/liburing/test/cq-overflow.c +14 -8
- data/vendor/liburing/test/d4ae271dfaae.c +1 -1
- data/vendor/liburing/test/defer-taskrun.c +64 -9
- data/vendor/liburing/test/defer.c +1 -1
- data/vendor/liburing/test/double-poll-crash.c +3 -3
- data/vendor/liburing/test/eeed8b54e0df.c +8 -3
- data/vendor/liburing/test/eploop.c +74 -0
- data/vendor/liburing/test/eventfd-ring.c +1 -1
- data/vendor/liburing/test/eventfd.c +1 -1
- data/vendor/liburing/test/evloop.c +73 -0
- data/vendor/liburing/test/exit-no-cleanup.c +1 -1
- data/vendor/liburing/test/fadvise.c +1 -1
- data/vendor/liburing/test/fc2a85cb02ef.c +3 -3
- data/vendor/liburing/test/fd-pass.c +35 -16
- data/vendor/liburing/test/file-register.c +61 -0
- data/vendor/liburing/test/file-verify.c +2 -2
- data/vendor/liburing/test/files-exit-hang-timeout.c +2 -2
- data/vendor/liburing/test/fixed-link.c +1 -1
- data/vendor/liburing/test/fsnotify.c +118 -0
- data/vendor/liburing/test/hardlink.c +1 -1
- data/vendor/liburing/test/helpers.c +54 -2
- data/vendor/liburing/test/helpers.h +4 -0
- data/vendor/liburing/test/io-cancel.c +3 -1
- data/vendor/liburing/test/io_uring_passthrough.c +39 -8
- data/vendor/liburing/test/io_uring_setup.c +3 -80
- data/vendor/liburing/test/iopoll-overflow.c +118 -0
- data/vendor/liburing/test/iopoll.c +90 -4
- data/vendor/liburing/test/lfs-openat-write.c +7 -9
- data/vendor/liburing/test/lfs-openat.c +6 -8
- data/vendor/liburing/test/link_drain.c +31 -5
- data/vendor/liburing/test/madvise.c +1 -1
- data/vendor/liburing/test/msg-ring-flags.c +192 -0
- data/vendor/liburing/test/msg-ring-overflow.c +159 -0
- data/vendor/liburing/test/msg-ring.c +173 -13
- data/vendor/liburing/test/multicqes_drain.c +22 -19
- data/vendor/liburing/test/nvme.h +4 -3
- data/vendor/liburing/test/pipe-bug.c +95 -0
- data/vendor/liburing/test/poll-link.c +3 -3
- data/vendor/liburing/test/poll-many.c +41 -19
- data/vendor/liburing/test/poll-mshot-overflow.c +105 -2
- data/vendor/liburing/test/poll-race-mshot.c +292 -0
- data/vendor/liburing/test/poll-race.c +105 -0
- data/vendor/liburing/test/poll.c +244 -26
- data/vendor/liburing/test/pollfree.c +5 -5
- data/vendor/liburing/test/read-before-exit.c +20 -3
- data/vendor/liburing/test/read-write.c +2 -0
- data/vendor/liburing/test/recv-multishot.c +96 -3
- data/vendor/liburing/test/reg-reg-ring.c +90 -0
- data/vendor/liburing/test/rename.c +1 -1
- data/vendor/liburing/test/ring-leak.c +0 -1
- data/vendor/liburing/test/ring-leak2.c +1 -1
- data/vendor/liburing/test/ringbuf-read.c +10 -6
- data/vendor/liburing/test/send-zerocopy.c +273 -103
- data/vendor/liburing/test/send_recv.c +7 -4
- data/vendor/liburing/test/sendmsg_fs_cve.c +2 -2
- data/vendor/liburing/test/single-issuer.c +7 -9
- data/vendor/liburing/test/skip-cqe.c +3 -4
- data/vendor/liburing/test/socket.c +0 -1
- data/vendor/liburing/test/sq-poll-dup.c +10 -3
- data/vendor/liburing/test/sq-poll-kthread.c +1 -1
- data/vendor/liburing/test/sq-poll-share.c +3 -2
- data/vendor/liburing/test/sqpoll-cancel-hang.c +17 -6
- data/vendor/liburing/test/sqpoll-disable-exit.c +4 -4
- data/vendor/liburing/test/symlink.c +2 -1
- data/vendor/liburing/test/test.h +2 -1
- data/vendor/liburing/test/timeout-new.c +11 -7
- data/vendor/liburing/test/timeout.c +1 -2
- data/vendor/liburing/test/unlink.c +1 -1
- data/vendor/liburing/test/version.c +25 -0
- data/vendor/liburing/test/wakeup-hang.c +1 -1
- data/vendor/liburing/test/xattr.c +8 -4
- metadata +57 -44
- data/docs/_config.yml +0 -64
- data/docs/_includes/head.html +0 -40
- data/docs/_includes/title.html +0 -1
- data/docs/_sass/custom/custom.scss +0 -10
- data/docs/_sass/overrides.scss +0 -0
- data/docs/api-reference/exception.md +0 -31
- data/docs/api-reference/fiber.md +0 -425
- data/docs/api-reference/index.md +0 -9
- data/docs/api-reference/io.md +0 -36
- data/docs/api-reference/object.md +0 -99
- data/docs/api-reference/polyphony-baseexception.md +0 -33
- data/docs/api-reference/polyphony-cancel.md +0 -26
- data/docs/api-reference/polyphony-moveon.md +0 -24
- data/docs/api-reference/polyphony-net.md +0 -20
- data/docs/api-reference/polyphony-process.md +0 -28
- data/docs/api-reference/polyphony-resourcepool.md +0 -59
- data/docs/api-reference/polyphony-restart.md +0 -18
- data/docs/api-reference/polyphony-terminate.md +0 -18
- data/docs/api-reference/polyphony-threadpool.md +0 -67
- data/docs/api-reference/polyphony-throttler.md +0 -77
- data/docs/api-reference/polyphony.md +0 -36
- data/docs/api-reference/thread.md +0 -88
- data/docs/favicon.ico +0 -0
- data/docs/getting-started/index.md +0 -10
- data/docs/getting-started/installing.md +0 -34
- data/vendor/liburing/debian/compat +0 -1
- data/vendor/liburing/debian/liburing1-udeb.install +0 -1
- data/vendor/liburing/debian/liburing1.install +0 -1
- data/vendor/liburing/debian/liburing1.symbols +0 -32
- /data/{docs/assets/img → assets}/echo-fibers.svg +0 -0
- /data/{docs → assets}/polyphony-logo.png +0 -0
- /data/{docs/assets/img → assets}/sleeping-fiber.svg +0 -0
data/vendor/liburing/test/poll.c
CHANGED
|
@@ -11,16 +11,27 @@
|
|
|
11
11
|
#include <signal.h>
|
|
12
12
|
#include <poll.h>
|
|
13
13
|
#include <sys/wait.h>
|
|
14
|
+
#include <assert.h>
|
|
14
15
|
|
|
16
|
+
#include "helpers.h"
|
|
15
17
|
#include "liburing.h"
|
|
16
18
|
|
|
17
|
-
static void
|
|
19
|
+
static void do_setsockopt(int fd, int level, int optname, int val)
|
|
18
20
|
{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
if (setsockopt(fd, level, optname, &val, sizeof(val)))
|
|
22
|
+
t_error(1, errno, "setsockopt %d.%d: %d", level, optname, val);
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
static bool check_cq_empty(struct io_uring *ring)
|
|
26
|
+
{
|
|
27
|
+
struct io_uring_cqe *cqe = NULL;
|
|
28
|
+
int ret;
|
|
29
|
+
|
|
30
|
+
ret = io_uring_peek_cqe(ring, &cqe); /* nothing should be there */
|
|
31
|
+
return ret == -EAGAIN;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static int test_basic(void)
|
|
24
35
|
{
|
|
25
36
|
struct io_uring_cqe *cqe;
|
|
26
37
|
struct io_uring_sqe *sqe;
|
|
@@ -29,34 +40,22 @@ int main(int argc, char *argv[])
|
|
|
29
40
|
pid_t p;
|
|
30
41
|
int ret;
|
|
31
42
|
|
|
32
|
-
if (argc > 1)
|
|
33
|
-
return 0;
|
|
34
|
-
|
|
35
43
|
if (pipe(pipe1) != 0) {
|
|
36
44
|
perror("pipe");
|
|
37
45
|
return 1;
|
|
38
46
|
}
|
|
39
47
|
|
|
40
48
|
p = fork();
|
|
41
|
-
|
|
42
|
-
case -1:
|
|
49
|
+
if (p == -1) {
|
|
43
50
|
perror("fork");
|
|
44
51
|
exit(2);
|
|
45
|
-
|
|
46
|
-
struct sigaction act;
|
|
47
|
-
|
|
52
|
+
} else if (p == 0) {
|
|
48
53
|
ret = io_uring_queue_init(1, &ring, 0);
|
|
49
54
|
if (ret) {
|
|
50
55
|
fprintf(stderr, "child: ring setup failed: %d\n", ret);
|
|
51
56
|
return 1;
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
memset(&act, 0, sizeof(act));
|
|
55
|
-
act.sa_handler = sig_alrm;
|
|
56
|
-
act.sa_flags = SA_RESTART;
|
|
57
|
-
sigaction(SIGALRM, &act, NULL);
|
|
58
|
-
alarm(1);
|
|
59
|
-
|
|
60
59
|
sqe = io_uring_get_sqe(&ring);
|
|
61
60
|
if (!sqe) {
|
|
62
61
|
fprintf(stderr, "get sqe failed\n");
|
|
@@ -92,18 +91,237 @@ int main(int argc, char *argv[])
|
|
|
92
91
|
(long) cqe->res);
|
|
93
92
|
return 1;
|
|
94
93
|
}
|
|
94
|
+
|
|
95
|
+
io_uring_queue_exit(&ring);
|
|
95
96
|
exit(0);
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
do {
|
|
100
|
+
errno = 0;
|
|
101
|
+
ret = write(pipe1[1], "foo", 3);
|
|
102
|
+
} while (ret == -1 && errno == EINTR);
|
|
103
|
+
|
|
104
|
+
if (ret != 3) {
|
|
105
|
+
fprintf(stderr, "parent: bad write return %d\n", ret);
|
|
106
|
+
return 1;
|
|
107
|
+
}
|
|
108
|
+
close(pipe1[0]);
|
|
109
|
+
close(pipe1[1]);
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static int test_missing_events(void)
|
|
114
|
+
{
|
|
115
|
+
struct io_uring_cqe *cqe;
|
|
116
|
+
struct io_uring_sqe *sqe;
|
|
117
|
+
struct io_uring ring;
|
|
118
|
+
int i, ret, sp[2];
|
|
119
|
+
char buf[2] = {};
|
|
120
|
+
int res_mask = 0;
|
|
121
|
+
|
|
122
|
+
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
|
|
123
|
+
IORING_SETUP_DEFER_TASKRUN);
|
|
124
|
+
if (ret) {
|
|
125
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
|
126
|
+
return 1;
|
|
127
|
+
}
|
|
102
128
|
|
|
103
|
-
|
|
104
|
-
|
|
129
|
+
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) {
|
|
130
|
+
perror("Failed to create Unix-domain socket pair\n");
|
|
131
|
+
return 1;
|
|
132
|
+
}
|
|
133
|
+
do_setsockopt(sp[0], SOL_SOCKET, SO_SNDBUF, 1);
|
|
134
|
+
ret = send(sp[0], buf, sizeof(buf), 0);
|
|
135
|
+
if (ret != sizeof(buf)) {
|
|
136
|
+
perror("send failed\n");
|
|
137
|
+
return 1;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
sqe = io_uring_get_sqe(&ring);
|
|
141
|
+
io_uring_prep_poll_multishot(sqe, sp[0], POLLIN|POLLOUT);
|
|
142
|
+
ret = io_uring_submit(&ring);
|
|
143
|
+
if (ret != 1) {
|
|
144
|
+
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
|
145
|
+
return 1;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* trigger EPOLLIN */
|
|
149
|
+
ret = send(sp[1], buf, sizeof(buf), 0);
|
|
150
|
+
if (ret != sizeof(buf)) {
|
|
151
|
+
fprintf(stderr, "send sp[1] failed %i %i\n", ret, errno);
|
|
152
|
+
return 1;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/* trigger EPOLLOUT */
|
|
156
|
+
ret = recv(sp[1], buf, sizeof(buf), 0);
|
|
157
|
+
if (ret != sizeof(buf)) {
|
|
158
|
+
perror("recv failed\n");
|
|
159
|
+
return 1;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
for (i = 0; ; i++) {
|
|
163
|
+
if (i == 0)
|
|
164
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
165
|
+
else
|
|
166
|
+
ret = io_uring_peek_cqe(&ring, &cqe);
|
|
167
|
+
|
|
168
|
+
if (i != 0 && ret == -EAGAIN) {
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
if (ret) {
|
|
172
|
+
fprintf(stderr, "wait completion %d, %i\n", ret, i);
|
|
105
173
|
return 1;
|
|
106
174
|
}
|
|
175
|
+
res_mask |= cqe->res;
|
|
176
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if ((res_mask & (POLLIN|POLLOUT)) != (POLLIN|POLLOUT)) {
|
|
180
|
+
fprintf(stderr, "missing poll events %i\n", res_mask);
|
|
181
|
+
return 1;
|
|
182
|
+
}
|
|
183
|
+
io_uring_queue_exit(&ring);
|
|
184
|
+
close(sp[0]);
|
|
185
|
+
close(sp[1]);
|
|
186
|
+
return 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
#define NR_SQES 2048
|
|
190
|
+
|
|
191
|
+
static int test_self_poll(void)
|
|
192
|
+
{
|
|
193
|
+
struct io_uring_cqe *cqe;
|
|
194
|
+
struct io_uring_sqe *sqe;
|
|
195
|
+
struct io_uring ring;
|
|
196
|
+
int ret, i, j;
|
|
197
|
+
|
|
198
|
+
ret = io_uring_queue_init(NR_SQES, &ring, 0);
|
|
199
|
+
if (ret) {
|
|
200
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
|
201
|
+
return T_EXIT_FAIL;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
for (j = 0; j < 32; j++) {
|
|
205
|
+
for (i = 0; i < NR_SQES; i++) {
|
|
206
|
+
sqe = io_uring_get_sqe(&ring);
|
|
207
|
+
io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
ret = io_uring_submit(&ring);
|
|
211
|
+
assert(ret == NR_SQES);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
sqe = io_uring_get_sqe(&ring);
|
|
215
|
+
io_uring_prep_nop(sqe);
|
|
216
|
+
ret = io_uring_submit(&ring);
|
|
217
|
+
assert(ret == 1);
|
|
218
|
+
|
|
219
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
220
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
221
|
+
|
|
222
|
+
io_uring_queue_exit(&ring);
|
|
223
|
+
return T_EXIT_PASS;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
static int test_disabled_ring_lazy_polling(int early_poll)
|
|
227
|
+
{
|
|
228
|
+
struct io_uring_cqe *cqe;
|
|
229
|
+
struct io_uring_sqe *sqe;
|
|
230
|
+
struct io_uring ring, ring2;
|
|
231
|
+
unsigned head;
|
|
232
|
+
int ret, i = 0;
|
|
233
|
+
|
|
234
|
+
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
|
|
235
|
+
IORING_SETUP_DEFER_TASKRUN |
|
|
236
|
+
IORING_SETUP_R_DISABLED);
|
|
237
|
+
if (ret) {
|
|
238
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
|
239
|
+
return 1;
|
|
240
|
+
}
|
|
241
|
+
ret = io_uring_queue_init(8, &ring2, 0);
|
|
242
|
+
if (ret) {
|
|
243
|
+
fprintf(stderr, "ring2 setup failed: %d\n", ret);
|
|
244
|
+
return 1;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (early_poll) {
|
|
248
|
+
/* start polling disabled DEFER_TASKRUN ring */
|
|
249
|
+
sqe = io_uring_get_sqe(&ring2);
|
|
250
|
+
io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN);
|
|
251
|
+
ret = io_uring_submit(&ring2);
|
|
252
|
+
assert(ret == 1);
|
|
253
|
+
assert(check_cq_empty(&ring2));
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* enable rings, which should also activate pollwq */
|
|
257
|
+
ret = io_uring_enable_rings(&ring);
|
|
258
|
+
assert(ret >= 0);
|
|
259
|
+
|
|
260
|
+
if (!early_poll) {
|
|
261
|
+
/* start polling enabled DEFER_TASKRUN ring */
|
|
262
|
+
sqe = io_uring_get_sqe(&ring2);
|
|
263
|
+
io_uring_prep_poll_add(sqe, ring.ring_fd, POLLIN);
|
|
264
|
+
ret = io_uring_submit(&ring2);
|
|
265
|
+
assert(ret == 1);
|
|
266
|
+
assert(check_cq_empty(&ring2));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
sqe = io_uring_get_sqe(&ring);
|
|
270
|
+
io_uring_prep_nop(sqe);
|
|
271
|
+
ret = io_uring_submit(&ring);
|
|
272
|
+
assert(ret == 1);
|
|
273
|
+
|
|
274
|
+
io_uring_for_each_cqe(&ring2, head, cqe) {
|
|
275
|
+
i++;
|
|
276
|
+
}
|
|
277
|
+
if (i != 1) {
|
|
278
|
+
fprintf(stderr, "fail, polling stuck\n");
|
|
279
|
+
return 1;
|
|
280
|
+
}
|
|
281
|
+
io_uring_queue_exit(&ring);
|
|
282
|
+
io_uring_queue_exit(&ring2);
|
|
283
|
+
return 0;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
int main(int argc, char *argv[])
|
|
287
|
+
{
|
|
288
|
+
int ret;
|
|
289
|
+
|
|
290
|
+
if (argc > 1)
|
|
107
291
|
return 0;
|
|
292
|
+
|
|
293
|
+
ret = test_basic();
|
|
294
|
+
if (ret) {
|
|
295
|
+
fprintf(stderr, "test_basic() failed %i\n", ret);
|
|
296
|
+
return T_EXIT_FAIL;
|
|
108
297
|
}
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
if (t_probe_defer_taskrun()) {
|
|
301
|
+
ret = test_missing_events();
|
|
302
|
+
if (ret) {
|
|
303
|
+
fprintf(stderr, "test_missing_events() failed %i\n", ret);
|
|
304
|
+
return T_EXIT_FAIL;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
ret = test_disabled_ring_lazy_polling(false);
|
|
308
|
+
if (ret) {
|
|
309
|
+
fprintf(stderr, "test_disabled_ring_lazy_polling(false) failed %i\n", ret);
|
|
310
|
+
return T_EXIT_FAIL;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
ret = test_disabled_ring_lazy_polling(true);
|
|
314
|
+
if (ret) {
|
|
315
|
+
fprintf(stderr, "test_disabled_ring_lazy_polling(true) failed %i\n", ret);
|
|
316
|
+
return T_EXIT_FAIL;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
ret = test_self_poll();
|
|
321
|
+
if (ret) {
|
|
322
|
+
fprintf(stderr, "test_self_poll failed\n");
|
|
323
|
+
return T_EXIT_FAIL;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return 0;
|
|
109
327
|
}
|
|
@@ -252,7 +252,7 @@ static void kill_and_wait(int pid, int* status)
|
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
static void setup_test()
|
|
255
|
+
static void setup_test(void)
|
|
256
256
|
{
|
|
257
257
|
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
|
|
258
258
|
setpgrp();
|
|
@@ -342,7 +342,7 @@ static void loop(void)
|
|
|
342
342
|
#define __NR_io_uring_enter 426
|
|
343
343
|
#endif
|
|
344
344
|
|
|
345
|
-
uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0};
|
|
345
|
+
static uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0x0};
|
|
346
346
|
|
|
347
347
|
void execute_call(int call)
|
|
348
348
|
{
|
|
@@ -403,13 +403,13 @@ int main(int argc, char *argv[])
|
|
|
403
403
|
if (argc > 1)
|
|
404
404
|
return 0;
|
|
405
405
|
|
|
406
|
-
ret = mmap((void *)0x1ffff000ul, 0x1000ul, 0ul,
|
|
406
|
+
ret = mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
|
|
407
407
|
if (ret == MAP_FAILED)
|
|
408
408
|
return 0;
|
|
409
|
-
ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul,
|
|
409
|
+
ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
|
|
410
410
|
if (ret == MAP_FAILED)
|
|
411
411
|
return 0;
|
|
412
|
-
ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul,
|
|
412
|
+
ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
|
|
413
413
|
if (ret == MAP_FAILED)
|
|
414
414
|
return 0;
|
|
415
415
|
loop();
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
#include "liburing.h"
|
|
15
15
|
#include "helpers.h"
|
|
16
16
|
|
|
17
|
+
static int no_iopoll;
|
|
18
|
+
|
|
17
19
|
struct data {
|
|
18
20
|
struct io_uring *ring;
|
|
19
21
|
int timer_fd1;
|
|
@@ -22,7 +24,7 @@ struct data {
|
|
|
22
24
|
uint64_t buf2;
|
|
23
25
|
};
|
|
24
26
|
|
|
25
|
-
void *submit(void *data)
|
|
27
|
+
static void *submit(void *data)
|
|
26
28
|
{
|
|
27
29
|
struct io_uring_sqe *sqe;
|
|
28
30
|
struct data *d = data;
|
|
@@ -35,8 +37,21 @@ void *submit(void *data)
|
|
|
35
37
|
io_uring_prep_read(sqe, d->timer_fd2, &d->buf2, sizeof(d->buf2), 0);
|
|
36
38
|
|
|
37
39
|
ret = io_uring_submit(d->ring);
|
|
38
|
-
if (ret != 2)
|
|
40
|
+
if (ret != 2) {
|
|
41
|
+
struct io_uring_cqe *cqe;
|
|
42
|
+
|
|
43
|
+
/*
|
|
44
|
+
* Kernels without submit-all-on-error behavior will
|
|
45
|
+
* fail submitting all, check if that's the case and
|
|
46
|
+
* don't error
|
|
47
|
+
*/
|
|
48
|
+
ret = io_uring_peek_cqe(d->ring, &cqe);
|
|
49
|
+
if (!ret && cqe->res == -EOPNOTSUPP) {
|
|
50
|
+
no_iopoll = 1;
|
|
51
|
+
return NULL;
|
|
52
|
+
}
|
|
39
53
|
return (void *) (uintptr_t) 1;
|
|
54
|
+
}
|
|
40
55
|
|
|
41
56
|
/* Exit suddenly. */
|
|
42
57
|
return NULL;
|
|
@@ -95,9 +110,11 @@ int main(int argc, char *argv[])
|
|
|
95
110
|
for (i = 0; i < 1000; i++) {
|
|
96
111
|
ret = test(IORING_SETUP_IOPOLL);
|
|
97
112
|
if (ret) {
|
|
98
|
-
fprintf(stderr, "Test IOPOLL failed\n");
|
|
113
|
+
fprintf(stderr, "Test IOPOLL failed loop %d\n", ret);
|
|
99
114
|
return ret;
|
|
100
115
|
}
|
|
116
|
+
if (no_iopoll)
|
|
117
|
+
break;
|
|
101
118
|
}
|
|
102
119
|
|
|
103
120
|
for (i = 0; i < 100; i++) {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#include <sys/types.h>
|
|
10
10
|
#include <sys/socket.h>
|
|
11
11
|
#include <pthread.h>
|
|
12
|
+
#include <assert.h>
|
|
12
13
|
|
|
13
14
|
#include "liburing.h"
|
|
14
15
|
#include "helpers.h"
|
|
@@ -264,11 +265,19 @@ static int test(struct args *args)
|
|
|
264
265
|
|
|
265
266
|
bool const is_last = i == recv_cqes - 1;
|
|
266
267
|
|
|
268
|
+
/*
|
|
269
|
+
* Older kernels could terminate multishot early due to overflow,
|
|
270
|
+
* but later ones will not. So discriminate based on the MORE flag.
|
|
271
|
+
*/
|
|
272
|
+
bool const early_last = args->early_error == ERROR_EARLY_OVERFLOW &&
|
|
273
|
+
!args->wait_each &&
|
|
274
|
+
i == N_CQE_OVERFLOW &&
|
|
275
|
+
!(cqe->flags & IORING_CQE_F_MORE);
|
|
276
|
+
|
|
267
277
|
bool const should_be_last =
|
|
268
278
|
(cqe->res <= 0) ||
|
|
269
279
|
(args->stream && is_last) ||
|
|
270
|
-
|
|
271
|
-
!args->wait_each && i == N_CQE_OVERFLOW);
|
|
280
|
+
early_last;
|
|
272
281
|
int *this_recv;
|
|
273
282
|
int orig_payload_size = cqe->res;
|
|
274
283
|
|
|
@@ -328,7 +337,7 @@ static int test(struct args *args)
|
|
|
328
337
|
case ERROR_EARLY_LAST:
|
|
329
338
|
fprintf(stderr, "bad error_early\n");
|
|
330
339
|
goto cleanup;
|
|
331
|
-
}
|
|
340
|
+
}
|
|
332
341
|
|
|
333
342
|
if (cqe->res <= 0 && cqe->flags & IORING_CQE_F_BUFFER) {
|
|
334
343
|
fprintf(stderr, "final BUFFER flag set\n");
|
|
@@ -461,6 +470,84 @@ cleanup:
|
|
|
461
470
|
return ret;
|
|
462
471
|
}
|
|
463
472
|
|
|
473
|
+
static int test_enobuf(void)
|
|
474
|
+
{
|
|
475
|
+
struct io_uring ring;
|
|
476
|
+
struct io_uring_sqe *sqe;
|
|
477
|
+
struct io_uring_cqe *cqes[16];
|
|
478
|
+
char buffs[256];
|
|
479
|
+
int ret, i, fds[2];
|
|
480
|
+
|
|
481
|
+
if (t_create_ring(8, &ring, 0) != T_SETUP_OK) {
|
|
482
|
+
fprintf(stderr, "ring create\n");
|
|
483
|
+
return -1;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
ret = t_create_socket_pair(fds, false);
|
|
487
|
+
if (ret) {
|
|
488
|
+
fprintf(stderr, "t_create_socket_pair\n");
|
|
489
|
+
return ret;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
sqe = io_uring_get_sqe(&ring);
|
|
493
|
+
assert(sqe);
|
|
494
|
+
/* deliberately only 2 provided buffers */
|
|
495
|
+
io_uring_prep_provide_buffers(sqe, &buffs[0], 1, 2, 0, 0);
|
|
496
|
+
io_uring_sqe_set_data64(sqe, 0);
|
|
497
|
+
|
|
498
|
+
sqe = io_uring_get_sqe(&ring);
|
|
499
|
+
assert(sqe);
|
|
500
|
+
io_uring_prep_recv_multishot(sqe, fds[0], NULL, 0, 0);
|
|
501
|
+
io_uring_sqe_set_data64(sqe, 1);
|
|
502
|
+
sqe->buf_group = 0;
|
|
503
|
+
sqe->flags |= IOSQE_BUFFER_SELECT;
|
|
504
|
+
|
|
505
|
+
ret = io_uring_submit(&ring);
|
|
506
|
+
if (ret != 2) {
|
|
507
|
+
fprintf(stderr, "bad submit %d\n", ret);
|
|
508
|
+
return -1;
|
|
509
|
+
}
|
|
510
|
+
for (i = 0; i < 3; i++) {
|
|
511
|
+
do {
|
|
512
|
+
ret = write(fds[1], "?", 1);
|
|
513
|
+
} while (ret == -1 && errno == EINTR);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
ret = io_uring_wait_cqes(&ring, &cqes[0], 4, NULL, NULL);
|
|
517
|
+
if (ret) {
|
|
518
|
+
fprintf(stderr, "wait cqes\n");
|
|
519
|
+
return ret;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
ret = io_uring_peek_batch_cqe(&ring, &cqes[0], 4);
|
|
523
|
+
if (ret != 4) {
|
|
524
|
+
fprintf(stderr, "peek batch cqes\n");
|
|
525
|
+
return -1;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/* provide buffers */
|
|
529
|
+
assert(cqes[0]->user_data == 0);
|
|
530
|
+
assert(cqes[0]->res == 0);
|
|
531
|
+
|
|
532
|
+
/* valid recv */
|
|
533
|
+
assert(cqes[1]->user_data == 1);
|
|
534
|
+
assert(cqes[2]->user_data == 1);
|
|
535
|
+
assert(cqes[1]->res == 1);
|
|
536
|
+
assert(cqes[2]->res == 1);
|
|
537
|
+
assert(cqes[1]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE));
|
|
538
|
+
assert(cqes[2]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE));
|
|
539
|
+
|
|
540
|
+
/* missing buffer */
|
|
541
|
+
assert(cqes[3]->user_data == 1);
|
|
542
|
+
assert(cqes[3]->res == -ENOBUFS);
|
|
543
|
+
assert(!(cqes[3]->flags & (IORING_CQE_F_BUFFER | IORING_CQE_F_MORE)));
|
|
544
|
+
|
|
545
|
+
close(fds[0]);
|
|
546
|
+
close(fds[1]);
|
|
547
|
+
io_uring_queue_exit(&ring);
|
|
548
|
+
return 0;
|
|
549
|
+
}
|
|
550
|
+
|
|
464
551
|
int main(int argc, char *argv[])
|
|
465
552
|
{
|
|
466
553
|
int ret;
|
|
@@ -501,5 +588,11 @@ int main(int argc, char *argv[])
|
|
|
501
588
|
}
|
|
502
589
|
}
|
|
503
590
|
|
|
591
|
+
ret = test_enobuf();
|
|
592
|
+
if (ret) {
|
|
593
|
+
fprintf(stderr, "test_enobuf() failed: %d\n", ret);
|
|
594
|
+
return T_EXIT_FAIL;
|
|
595
|
+
}
|
|
596
|
+
|
|
504
597
|
return T_EXIT_PASS;
|
|
505
598
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Test io_uring_register with a registered ring (IORING_REGISTER_USE_REGISTERED_RING)
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
#include <stdio.h>
|
|
7
|
+
|
|
8
|
+
#include "helpers.h"
|
|
9
|
+
|
|
10
|
+
int main(int argc, char *argv[])
|
|
11
|
+
{
|
|
12
|
+
struct io_uring ring;
|
|
13
|
+
unsigned values[2];
|
|
14
|
+
int ret;
|
|
15
|
+
|
|
16
|
+
if (argc > 1)
|
|
17
|
+
return T_EXIT_SKIP;
|
|
18
|
+
|
|
19
|
+
ret = io_uring_queue_init(8, &ring, 0);
|
|
20
|
+
if (ret) {
|
|
21
|
+
fprintf(stderr, "ring setup failed\n");
|
|
22
|
+
return T_EXIT_FAIL;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!(ring.features & IORING_FEAT_REG_REG_RING)) {
|
|
26
|
+
fprintf(stderr, "IORING_FEAT_REG_REG_RING not available in kernel\n");
|
|
27
|
+
io_uring_queue_exit(&ring);
|
|
28
|
+
return T_EXIT_SKIP;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
ret = io_uring_close_ring_fd(&ring);
|
|
32
|
+
if (ret != -EINVAL) {
|
|
33
|
+
fprintf(stderr, "closing ring fd should EINVAL before register\n");
|
|
34
|
+
goto err;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
ret = io_uring_unregister_ring_fd(&ring);
|
|
38
|
+
if (ret != -EINVAL) {
|
|
39
|
+
fprintf(stderr, "unregistering not-registered ring fd should fail\n");
|
|
40
|
+
goto err;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
ret = io_uring_register_ring_fd(&ring);
|
|
44
|
+
if (ret != 1) {
|
|
45
|
+
fprintf(stderr, "registering ring fd failed\n");
|
|
46
|
+
goto err;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
ret = io_uring_register_ring_fd(&ring);
|
|
50
|
+
if (ret != -EEXIST) {
|
|
51
|
+
fprintf(stderr, "registering already-registered ring fd should fail\n");
|
|
52
|
+
goto err;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Test a simple io_uring_register operation expected to work.
|
|
56
|
+
* io_uring_register_iowq_max_workers is arbitrary.
|
|
57
|
+
*/
|
|
58
|
+
values[0] = values[1] = 0;
|
|
59
|
+
ret = io_uring_register_iowq_max_workers(&ring, values);
|
|
60
|
+
if (ret || (values[0] == 0 && values[1] == 0)) {
|
|
61
|
+
fprintf(stderr, "io_uring_register operation failed before closing ring fd\n");
|
|
62
|
+
goto err;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
ret = io_uring_close_ring_fd(&ring);
|
|
66
|
+
if (ret != 1) {
|
|
67
|
+
fprintf(stderr, "closing ring fd failed\n");
|
|
68
|
+
goto err;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
values[0] = values[1] = 0;
|
|
72
|
+
ret = io_uring_register_iowq_max_workers(&ring, values);
|
|
73
|
+
if (ret || (values[0] == 0 && values[1] == 0)) {
|
|
74
|
+
fprintf(stderr, "io_uring_register operation failed after closing ring fd\n");
|
|
75
|
+
goto err;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ret = io_uring_close_ring_fd(&ring);
|
|
79
|
+
if (ret != -EBADF) {
|
|
80
|
+
fprintf(stderr, "closing already-closed ring fd should fail\n");
|
|
81
|
+
goto err;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
io_uring_queue_exit(&ring);
|
|
85
|
+
return T_EXIT_PASS;
|
|
86
|
+
|
|
87
|
+
err:
|
|
88
|
+
io_uring_queue_exit(&ring);
|
|
89
|
+
return T_EXIT_FAIL;
|
|
90
|
+
}
|