uringmachine 0.4 → 0.5.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/workflows/test.yml +2 -1
- data/CHANGELOG.md +16 -0
- data/README.md +44 -1
- data/TODO.md +12 -3
- data/examples/bm_snooze.rb +89 -0
- data/examples/bm_sqlite.rb +89 -0
- data/examples/bm_write.rb +56 -0
- data/examples/dns_client.rb +12 -0
- data/examples/http_server.rb +42 -43
- data/examples/pg.rb +85 -0
- data/examples/server_client.rb +64 -0
- data/examples/snooze.rb +44 -0
- data/examples/stream.rb +85 -0
- data/examples/write_dev_null.rb +16 -0
- data/ext/um/extconf.rb +81 -14
- data/ext/um/um.c +468 -414
- data/ext/um/um.h +149 -40
- data/ext/um/um_async_op.c +40 -0
- data/ext/um/um_async_op_class.c +136 -0
- data/ext/um/um_buffer.c +49 -0
- data/ext/um/um_class.c +176 -44
- data/ext/um/um_const.c +174 -9
- data/ext/um/um_ext.c +8 -0
- data/ext/um/um_mutex_class.c +47 -0
- data/ext/um/um_op.c +89 -111
- data/ext/um/um_queue_class.c +58 -0
- data/ext/um/um_ssl.c +850 -0
- data/ext/um/um_ssl.h +22 -0
- data/ext/um/um_ssl_class.c +138 -0
- data/ext/um/um_sync.c +273 -0
- data/ext/um/um_utils.c +1 -1
- data/lib/uringmachine/dns_resolver.rb +84 -0
- data/lib/uringmachine/ssl/context_builder.rb +96 -0
- data/lib/uringmachine/ssl.rb +394 -0
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +27 -3
- data/supressions/ruby.supp +71 -0
- data/test/helper.rb +6 -0
- data/test/test_async_op.rb +119 -0
- data/test/test_ssl.rb +155 -0
- data/test/test_um.rb +464 -47
- data/uringmachine.gemspec +3 -2
- data/vendor/liburing/.gitignore +5 -0
- data/vendor/liburing/CHANGELOG +1 -0
- data/vendor/liburing/configure +32 -0
- data/vendor/liburing/examples/Makefile +1 -0
- data/vendor/liburing/examples/reg-wait.c +159 -0
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/include/liburing/io_uring.h +48 -2
- data/vendor/liburing/src/include/liburing.h +28 -2
- data/vendor/liburing/src/int_flags.h +10 -3
- data/vendor/liburing/src/liburing-ffi.map +13 -2
- data/vendor/liburing/src/liburing.map +9 -0
- data/vendor/liburing/src/queue.c +25 -16
- data/vendor/liburing/src/register.c +73 -4
- data/vendor/liburing/src/setup.c +46 -18
- data/vendor/liburing/src/setup.h +6 -0
- data/vendor/liburing/test/Makefile +7 -0
- data/vendor/liburing/test/cmd-discard.c +427 -0
- data/vendor/liburing/test/fifo-nonblock-read.c +69 -0
- data/vendor/liburing/test/file-exit-unreg.c +48 -0
- data/vendor/liburing/test/io_uring_passthrough.c +2 -0
- data/vendor/liburing/test/io_uring_register.c +13 -2
- data/vendor/liburing/test/napi-test.c +1 -1
- data/vendor/liburing/test/no-mmap-inval.c +1 -1
- data/vendor/liburing/test/read-mshot-empty.c +2 -0
- data/vendor/liburing/test/read-mshot-stdin.c +121 -0
- data/vendor/liburing/test/read-mshot.c +6 -0
- data/vendor/liburing/test/recvsend_bundle.c +2 -2
- data/vendor/liburing/test/reg-fd-only.c +1 -1
- data/vendor/liburing/test/reg-wait.c +251 -0
- data/vendor/liburing/test/regbuf-clone.c +458 -0
- data/vendor/liburing/test/resize-rings.c +643 -0
- data/vendor/liburing/test/rsrc_tags.c +1 -1
- data/vendor/liburing/test/sqpoll-sleep.c +39 -8
- data/vendor/liburing/test/sqwait.c +136 -0
- data/vendor/liburing/test/sync-cancel.c +8 -1
- data/vendor/liburing/test/timeout.c +13 -8
- metadata +52 -8
- data/examples/http_server_multishot.rb +0 -57
- data/examples/http_server_simpler.rb +0 -34
@@ -0,0 +1,48 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: test that a defer task_work file with tags unregistration
|
4
|
+
* doesn't trigger a lockdep violation
|
5
|
+
*
|
6
|
+
*/
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <inttypes.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <unistd.h>
|
11
|
+
|
12
|
+
#include "liburing.h"
|
13
|
+
#include "helpers.h"
|
14
|
+
|
15
|
+
int main(int argc, char *argv[])
|
16
|
+
{
|
17
|
+
__u64 tags[2] = { 1, 2 };
|
18
|
+
struct io_uring ring;
|
19
|
+
int fds[2], ret;
|
20
|
+
|
21
|
+
if (argc > 1)
|
22
|
+
return T_EXIT_SKIP;
|
23
|
+
|
24
|
+
if (pipe(fds) < 0) {
|
25
|
+
perror("pipe");
|
26
|
+
return 1;
|
27
|
+
}
|
28
|
+
|
29
|
+
ret = io_uring_queue_init(4, &ring, IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_DEFER_TASKRUN);
|
30
|
+
if (ret == -EINVAL) {
|
31
|
+
return T_EXIT_SKIP;
|
32
|
+
} else if (ret < 0) {
|
33
|
+
fprintf(stderr, "queue_init: %d\n", ret);
|
34
|
+
return T_EXIT_FAIL;
|
35
|
+
}
|
36
|
+
|
37
|
+
ret = io_uring_register_files_tags(&ring, fds, tags, 2);
|
38
|
+
if (ret == -EINVAL) {
|
39
|
+
return T_EXIT_SKIP;
|
40
|
+
} else if (ret < 0) {
|
41
|
+
fprintf(stderr, "file_register_init: %d\n", ret);
|
42
|
+
return T_EXIT_FAIL;
|
43
|
+
}
|
44
|
+
|
45
|
+
io_uring_queue_exit(&ring);
|
46
|
+
sleep(1);
|
47
|
+
return 0;
|
48
|
+
}
|
@@ -167,6 +167,8 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read,
|
|
167
167
|
}
|
168
168
|
}
|
169
169
|
sqe->opcode = IORING_OP_URING_CMD;
|
170
|
+
if (do_fixed)
|
171
|
+
sqe->uring_cmd_flags |= IORING_URING_CMD_FIXED;
|
170
172
|
sqe->user_data = ((uint64_t)offset << 32) | i;
|
171
173
|
if (sqthread)
|
172
174
|
sqe->flags |= IOSQE_FIXED_FILE;
|
@@ -436,14 +436,14 @@ static int ioring_poll(struct io_uring *ring, int fd, int fixed)
|
|
436
436
|
return ret;
|
437
437
|
}
|
438
438
|
|
439
|
-
static int
|
439
|
+
static int __test_poll_ringfd(int ring_flags)
|
440
440
|
{
|
441
441
|
int status = 0;
|
442
442
|
int ret;
|
443
443
|
int fd;
|
444
444
|
struct io_uring ring;
|
445
445
|
|
446
|
-
ret = io_uring_queue_init(
|
446
|
+
ret = io_uring_queue_init(2, &ring, ring_flags);
|
447
447
|
if (ret) {
|
448
448
|
perror("io_uring_queue_init");
|
449
449
|
return 1;
|
@@ -466,6 +466,17 @@ static int test_poll_ringfd(void)
|
|
466
466
|
return status;
|
467
467
|
}
|
468
468
|
|
469
|
+
static int test_poll_ringfd(void)
|
470
|
+
{
|
471
|
+
int ret;
|
472
|
+
|
473
|
+
ret = __test_poll_ringfd(0);
|
474
|
+
if (ret)
|
475
|
+
return ret;
|
476
|
+
|
477
|
+
return __test_poll_ringfd(IORING_SETUP_SQPOLL);
|
478
|
+
}
|
479
|
+
|
469
480
|
int main(int argc, char **argv)
|
470
481
|
{
|
471
482
|
int fd, ret;
|
@@ -30,7 +30,7 @@ int main(int argc, char *argv[])
|
|
30
30
|
p.cq_off.user_addr = (unsigned long long) (uintptr_t) addr;
|
31
31
|
|
32
32
|
ret = io_uring_queue_init_params(2, &ring, &p);
|
33
|
-
if (ret == -EINVAL) {
|
33
|
+
if (ret == -EINVAL || ret == -ENOENT) {
|
34
34
|
/* kernel doesn't support SETUP_NO_MMAP */
|
35
35
|
free(addr);
|
36
36
|
return T_EXIT_SKIP;
|
@@ -0,0 +1,121 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: test multishot read on stdin. Not that this REQUIRES input
|
4
|
+
* to be received on stdin, and hence if invoked with no
|
5
|
+
* arguments, or without the single argument being 'stdin',
|
6
|
+
* the test will just return SKIPPED. Can't be run from the
|
7
|
+
* standard test harness, as it's interactive.
|
8
|
+
*
|
9
|
+
* To run, do run "test/read-mshot-stdin.t stdin" and then input text on
|
10
|
+
* the console, followed by enter / line feed. If it works as it should,
|
11
|
+
* it'll output the received CQE data. If an error is detected, it'll
|
12
|
+
* abort with an error.
|
13
|
+
*/
|
14
|
+
#include <errno.h>
|
15
|
+
#include <stdio.h>
|
16
|
+
#include <unistd.h>
|
17
|
+
#include <stdlib.h>
|
18
|
+
#include <string.h>
|
19
|
+
#include <fcntl.h>
|
20
|
+
#include <sys/stat.h>
|
21
|
+
|
22
|
+
#include "liburing.h"
|
23
|
+
#include "helpers.h"
|
24
|
+
|
25
|
+
#define BUF_SIZE 32
|
26
|
+
#define NR_BUFS 64
|
27
|
+
#define BUF_BGID 1
|
28
|
+
|
29
|
+
#define BR_MASK (NR_BUFS - 1)
|
30
|
+
|
31
|
+
static int test_stdin(void)
|
32
|
+
{
|
33
|
+
struct io_uring_buf_ring *br;
|
34
|
+
struct io_uring_params p = { };
|
35
|
+
struct io_uring_sqe *sqe;
|
36
|
+
struct io_uring_cqe *cqe;
|
37
|
+
struct io_uring ring;
|
38
|
+
int ret, i, last_bid;
|
39
|
+
char *buf, *ptr;
|
40
|
+
|
41
|
+
p.flags = IORING_SETUP_CQSIZE;
|
42
|
+
p.cq_entries = NR_BUFS;
|
43
|
+
ret = io_uring_queue_init_params(1, &ring, &p);
|
44
|
+
if (ret) {
|
45
|
+
if (ret == -EINVAL)
|
46
|
+
return T_EXIT_SKIP;
|
47
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
48
|
+
return T_EXIT_FAIL;
|
49
|
+
}
|
50
|
+
|
51
|
+
if (posix_memalign((void **) &buf, 4096, NR_BUFS * BUF_SIZE))
|
52
|
+
return T_EXIT_FAIL;
|
53
|
+
|
54
|
+
br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID, 0, &ret);
|
55
|
+
if (!br) {
|
56
|
+
if (ret == -EINVAL)
|
57
|
+
return T_EXIT_SKIP;
|
58
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
59
|
+
return T_EXIT_FAIL;
|
60
|
+
}
|
61
|
+
|
62
|
+
ptr = buf;
|
63
|
+
for (i = 0; i < NR_BUFS; i++) {
|
64
|
+
io_uring_buf_ring_add(br, ptr, BUF_SIZE, i + 1, BR_MASK, i);
|
65
|
+
ptr += BUF_SIZE;
|
66
|
+
}
|
67
|
+
io_uring_buf_ring_advance(br, NR_BUFS);
|
68
|
+
|
69
|
+
sqe = io_uring_get_sqe(&ring);
|
70
|
+
io_uring_prep_read_multishot(sqe, STDIN_FILENO, 0, 0, BUF_BGID);
|
71
|
+
|
72
|
+
ret = io_uring_submit(&ring);
|
73
|
+
if (ret != 1) {
|
74
|
+
fprintf(stderr, "submit: %d\n", ret);
|
75
|
+
return T_EXIT_FAIL;
|
76
|
+
}
|
77
|
+
|
78
|
+
last_bid = -1;
|
79
|
+
do {
|
80
|
+
int bid;
|
81
|
+
|
82
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
83
|
+
if (ret) {
|
84
|
+
fprintf(stderr, "wait cqe failed %d\n", ret);
|
85
|
+
return T_EXIT_FAIL;
|
86
|
+
}
|
87
|
+
if (cqe->res && !(cqe->flags & IORING_CQE_F_BUFFER)) {
|
88
|
+
fprintf(stderr, "BUF flag not set %x\n", cqe->flags);
|
89
|
+
return T_EXIT_FAIL;
|
90
|
+
}
|
91
|
+
bid = cqe->flags >> 16;
|
92
|
+
printf("CQE res %d, bid %d, flags %x\n", cqe->res, bid, cqe->flags);
|
93
|
+
if (cqe->res > 0 && last_bid != -1 && last_bid + 1 != bid) {
|
94
|
+
fprintf(stderr, "Got bid %d, wanted %d\n", bid, last_bid + 1);
|
95
|
+
return T_EXIT_FAIL;
|
96
|
+
}
|
97
|
+
if (!(cqe->flags & IORING_CQE_F_MORE)) {
|
98
|
+
io_uring_cqe_seen(&ring, cqe);
|
99
|
+
break;
|
100
|
+
}
|
101
|
+
|
102
|
+
last_bid = bid;
|
103
|
+
io_uring_cqe_seen(&ring, cqe);
|
104
|
+
}while (1);
|
105
|
+
|
106
|
+
io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
|
107
|
+
io_uring_queue_exit(&ring);
|
108
|
+
free(buf);
|
109
|
+
return T_EXIT_PASS;
|
110
|
+
}
|
111
|
+
|
112
|
+
int main(int argc, char *argv[])
|
113
|
+
{
|
114
|
+
if (argc == 1)
|
115
|
+
return T_EXIT_SKIP;
|
116
|
+
else if (argc > 2)
|
117
|
+
return T_EXIT_SKIP;
|
118
|
+
if (!strcmp(argv[1], "stdin"))
|
119
|
+
return test_stdin();
|
120
|
+
return T_EXIT_SKIP;
|
121
|
+
}
|
@@ -144,6 +144,8 @@ static int test_inc(int use_mshot, int flags)
|
|
144
144
|
}
|
145
145
|
}
|
146
146
|
|
147
|
+
io_uring_free_buf_ring(&ring, br, 32, BUF_BGID);
|
148
|
+
io_uring_queue_exit(&ring);
|
147
149
|
free(ptr);
|
148
150
|
close(fds[0]);
|
149
151
|
close(fds[1]);
|
@@ -254,6 +256,7 @@ static int test_clamp(void)
|
|
254
256
|
io_uring_cqe_seen(&ring, cqe);
|
255
257
|
}
|
256
258
|
|
259
|
+
io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
|
257
260
|
io_uring_queue_exit(&ring);
|
258
261
|
free(ptr);
|
259
262
|
return 0;
|
@@ -408,6 +411,8 @@ static int test(int first_good, int async, int overflow, int incremental)
|
|
408
411
|
io_uring_cqe_seen(&ring, cqe);
|
409
412
|
}
|
410
413
|
|
414
|
+
|
415
|
+
io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
|
411
416
|
io_uring_queue_exit(&ring);
|
412
417
|
if (incremental) {
|
413
418
|
free(ptr[0]);
|
@@ -483,6 +488,7 @@ static int test_invalid(int async)
|
|
483
488
|
}
|
484
489
|
|
485
490
|
io_uring_cqe_seen(&ring, cqe);
|
491
|
+
io_uring_free_buf_ring(&ring, br, 1, BUF_BGID);
|
486
492
|
io_uring_queue_exit(&ring);
|
487
493
|
free(buf);
|
488
494
|
return 0;
|
@@ -291,7 +291,7 @@ static void *recv_fn(void *data)
|
|
291
291
|
goto err;
|
292
292
|
}
|
293
293
|
|
294
|
-
if (posix_memalign(&buf,
|
294
|
+
if (posix_memalign(&buf, sysconf(_SC_PAGESIZE), MSG_SIZE * RECV_BIDS))
|
295
295
|
goto err;
|
296
296
|
|
297
297
|
if (!classic_buffers) {
|
@@ -453,7 +453,7 @@ static int do_send(struct recv_data *rd)
|
|
453
453
|
return 0;
|
454
454
|
}
|
455
455
|
|
456
|
-
if (posix_memalign(&buf,
|
456
|
+
if (posix_memalign(&buf, sysconf(_SC_PAGESIZE), MSG_SIZE * nr_msgs))
|
457
457
|
return 1;
|
458
458
|
|
459
459
|
if (!classic_buffers) {
|
@@ -58,7 +58,7 @@ static int test(int nentries, int ring_flags)
|
|
58
58
|
ret = io_uring_queue_init(nentries, &ring,
|
59
59
|
IORING_SETUP_REGISTERED_FD_ONLY | IORING_SETUP_NO_MMAP |
|
60
60
|
ring_flags);
|
61
|
-
if (ret == -EINVAL) {
|
61
|
+
if (ret == -EINVAL || ret == -ENOENT) {
|
62
62
|
no_mmap = 1;
|
63
63
|
return T_EXIT_SKIP;
|
64
64
|
} else if (ret == -ENOMEM) {
|
@@ -0,0 +1,251 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: Test that registered waits work
|
4
|
+
*/
|
5
|
+
#include <errno.h>
|
6
|
+
#include <stdio.h>
|
7
|
+
#include <unistd.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <string.h>
|
10
|
+
#include <fcntl.h>
|
11
|
+
#include <sys/time.h>
|
12
|
+
|
13
|
+
#include "liburing.h"
|
14
|
+
#include "helpers.h"
|
15
|
+
#include "test.h"
|
16
|
+
|
17
|
+
static struct io_uring_reg_wait *reg;
|
18
|
+
|
19
|
+
static int test_invalid_reg2(void)
|
20
|
+
{
|
21
|
+
struct io_uring ring;
|
22
|
+
void *buf, *ptr;
|
23
|
+
int ret;
|
24
|
+
|
25
|
+
io_uring_queue_init(1, &ring, 0);
|
26
|
+
|
27
|
+
if (posix_memalign(&buf, 4096, 4096))
|
28
|
+
return T_EXIT_FAIL;
|
29
|
+
memset(buf, 0, 4096);
|
30
|
+
ptr = buf + 4096 - 32;
|
31
|
+
|
32
|
+
ret = io_uring_register_wait_reg(&ring, ptr, 1);
|
33
|
+
if (ret != -EINVAL) {
|
34
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
35
|
+
return T_EXIT_FAIL;
|
36
|
+
}
|
37
|
+
|
38
|
+
ptr = buf + (sizeof(struct io_uring_reg_wait) / 2);
|
39
|
+
ret = io_uring_register_wait_reg(&ring, ptr, 1);
|
40
|
+
if (ret != -EINVAL) {
|
41
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
42
|
+
return T_EXIT_FAIL;
|
43
|
+
}
|
44
|
+
|
45
|
+
free(buf);
|
46
|
+
buf = (void *) 0x1000;
|
47
|
+
ret = io_uring_register_wait_reg(&ring, buf, 1);
|
48
|
+
if (ret != -EFAULT) {
|
49
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
50
|
+
return T_EXIT_FAIL;
|
51
|
+
}
|
52
|
+
|
53
|
+
buf = (void *) 0x1240;
|
54
|
+
ret = io_uring_register_wait_reg(&ring, buf, 1);
|
55
|
+
if (ret != -EFAULT) {
|
56
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
57
|
+
return T_EXIT_FAIL;
|
58
|
+
}
|
59
|
+
|
60
|
+
buf = (void *) 0x1241;
|
61
|
+
ret = io_uring_register_wait_reg(&ring, buf, 1);
|
62
|
+
if (ret != -EINVAL) {
|
63
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
64
|
+
return T_EXIT_FAIL;
|
65
|
+
}
|
66
|
+
|
67
|
+
io_uring_queue_exit(&ring);
|
68
|
+
return T_EXIT_PASS;
|
69
|
+
}
|
70
|
+
|
71
|
+
static int test_invalid_reg(void)
|
72
|
+
{
|
73
|
+
struct io_uring_reg_wait *ireg;
|
74
|
+
struct io_uring_cqe *cqe;
|
75
|
+
struct io_uring ring;
|
76
|
+
struct timeval tv;
|
77
|
+
void *buf, *ptr;
|
78
|
+
int ret;
|
79
|
+
|
80
|
+
io_uring_queue_init(1, &ring, 0);
|
81
|
+
|
82
|
+
if (posix_memalign(&buf, 4096, 4096))
|
83
|
+
return T_EXIT_FAIL;
|
84
|
+
memset(buf, 0, 4096);
|
85
|
+
ptr = buf + 512;
|
86
|
+
ireg = ptr;
|
87
|
+
|
88
|
+
ret = io_uring_register_wait_reg(&ring, ireg, 56);
|
89
|
+
if (ret) {
|
90
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
91
|
+
return T_EXIT_FAIL;
|
92
|
+
}
|
93
|
+
|
94
|
+
ireg = ptr;
|
95
|
+
memset(ireg, 0, sizeof(*ireg));
|
96
|
+
ireg->ts.tv_sec = 1;
|
97
|
+
ireg->ts.tv_nsec = 0;
|
98
|
+
ireg->flags = IORING_REG_WAIT_TS;
|
99
|
+
|
100
|
+
gettimeofday(&tv, NULL);
|
101
|
+
ret = io_uring_submit_and_wait_reg(&ring, &cqe, 1, 0);
|
102
|
+
if (ret != -ETIME) {
|
103
|
+
fprintf(stderr, "wait_reg failed: %d\n", ret);
|
104
|
+
return T_EXIT_FAIL;
|
105
|
+
}
|
106
|
+
|
107
|
+
ret = mtime_since_now(&tv);
|
108
|
+
/* allow some slack, should be around 1.1s */
|
109
|
+
if (ret < 1000 || ret > 1200) {
|
110
|
+
fprintf(stderr, "wait too long or short: %d\n", ret);
|
111
|
+
goto err;
|
112
|
+
}
|
113
|
+
|
114
|
+
memset(ireg, 0, sizeof(*ireg));
|
115
|
+
ireg->ts.tv_sec = 1;
|
116
|
+
ireg->ts.tv_nsec = 0;
|
117
|
+
ireg->flags = IORING_REG_WAIT_TS;
|
118
|
+
|
119
|
+
gettimeofday(&tv, NULL);
|
120
|
+
ret = io_uring_submit_and_wait_reg(&ring, &cqe, 1, 56);
|
121
|
+
if (ret != -EFAULT) {
|
122
|
+
fprintf(stderr, "out-of-range reg_wait failed: %d\n", ret);
|
123
|
+
return T_EXIT_FAIL;
|
124
|
+
}
|
125
|
+
|
126
|
+
free(buf);
|
127
|
+
io_uring_queue_exit(&ring);
|
128
|
+
return T_EXIT_PASS;
|
129
|
+
err:
|
130
|
+
io_uring_queue_exit(&ring);
|
131
|
+
return T_EXIT_FAIL;
|
132
|
+
}
|
133
|
+
|
134
|
+
static int test_invalid_sig(struct io_uring *ring)
|
135
|
+
{
|
136
|
+
struct io_uring_cqe *cqe;
|
137
|
+
sigset_t sig;
|
138
|
+
int ret;
|
139
|
+
|
140
|
+
memset(reg, 0, sizeof(*reg));
|
141
|
+
reg->ts.tv_sec = 1;
|
142
|
+
reg->ts.tv_nsec = 0;
|
143
|
+
reg->sigmask = (unsigned long) &sig;
|
144
|
+
reg->sigmask_sz = 1;
|
145
|
+
|
146
|
+
ret = io_uring_submit_and_wait_reg(ring, &cqe, 1, 0);
|
147
|
+
if (ret != -EINVAL) {
|
148
|
+
fprintf(stderr, "sigmask_sz failed: %d\n", ret);
|
149
|
+
return T_EXIT_FAIL;
|
150
|
+
}
|
151
|
+
|
152
|
+
memset(reg, 0, sizeof(*reg));
|
153
|
+
reg->ts.tv_sec = 1;
|
154
|
+
reg->ts.tv_nsec = 0;
|
155
|
+
reg->sigmask = 100;
|
156
|
+
reg->sigmask_sz = 8;
|
157
|
+
|
158
|
+
ret = io_uring_submit_and_wait_reg(ring, &cqe, 1, 0);
|
159
|
+
if (ret != -EFAULT) {
|
160
|
+
fprintf(stderr, "sigmask invalid failed: %d\n", ret);
|
161
|
+
return T_EXIT_FAIL;
|
162
|
+
}
|
163
|
+
|
164
|
+
return T_EXIT_PASS;
|
165
|
+
}
|
166
|
+
|
167
|
+
static int test_basic(struct io_uring *ring)
|
168
|
+
{
|
169
|
+
struct io_uring_cqe *cqe;
|
170
|
+
struct timeval tv;
|
171
|
+
int ret;
|
172
|
+
|
173
|
+
memset(reg, 0, sizeof(*reg));
|
174
|
+
reg->ts.tv_sec = 1;
|
175
|
+
reg->ts.tv_nsec = 100000000ULL;
|
176
|
+
reg->flags = IORING_REG_WAIT_TS;
|
177
|
+
|
178
|
+
gettimeofday(&tv, NULL);
|
179
|
+
ret = io_uring_submit_and_wait_reg(ring, &cqe, 2, 0);
|
180
|
+
if (ret != -ETIME) {
|
181
|
+
fprintf(stderr, "submit_and_wait_reg: %d\n", ret);
|
182
|
+
goto err;
|
183
|
+
}
|
184
|
+
ret = mtime_since_now(&tv);
|
185
|
+
/* allow some slack, should be around 1.1s */
|
186
|
+
if (ret < 1000 || ret > 1200) {
|
187
|
+
fprintf(stderr, "wait too long or short: %d\n", ret);
|
188
|
+
goto err;
|
189
|
+
}
|
190
|
+
return T_EXIT_PASS;
|
191
|
+
err:
|
192
|
+
return T_EXIT_FAIL;
|
193
|
+
}
|
194
|
+
|
195
|
+
static int test_ring(void)
|
196
|
+
{
|
197
|
+
struct io_uring ring;
|
198
|
+
struct io_uring_params p = { };
|
199
|
+
int ret;
|
200
|
+
|
201
|
+
p.flags = 0;
|
202
|
+
ret = io_uring_queue_init_params(8, &ring, &p);
|
203
|
+
if (ret) {
|
204
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
205
|
+
return 1;
|
206
|
+
}
|
207
|
+
|
208
|
+
reg = io_uring_setup_reg_wait(&ring, 64, &ret);
|
209
|
+
if (!reg) {
|
210
|
+
if (ret == -EINVAL)
|
211
|
+
return T_EXIT_SKIP;
|
212
|
+
fprintf(stderr, "setup_reg_wait: %d\n", ret);
|
213
|
+
return T_EXIT_FAIL;
|
214
|
+
}
|
215
|
+
|
216
|
+
ret = test_basic(&ring);
|
217
|
+
if (ret == T_EXIT_FAIL) {
|
218
|
+
fprintf(stderr, "test failed\n");
|
219
|
+
goto err;
|
220
|
+
}
|
221
|
+
|
222
|
+
ret = test_invalid_sig(&ring);
|
223
|
+
if (ret == T_EXIT_FAIL) {
|
224
|
+
fprintf(stderr, "test_invalid sig failed\n");
|
225
|
+
goto err;
|
226
|
+
}
|
227
|
+
|
228
|
+
ret = test_invalid_reg();
|
229
|
+
if (ret == T_EXIT_FAIL) {
|
230
|
+
fprintf(stderr, "test_invalid_reg failed\n");
|
231
|
+
goto err;
|
232
|
+
}
|
233
|
+
|
234
|
+
ret = test_invalid_reg2();
|
235
|
+
if (ret == T_EXIT_FAIL) {
|
236
|
+
fprintf(stderr, "test_invalid_reg2 failed\n");
|
237
|
+
goto err;
|
238
|
+
}
|
239
|
+
|
240
|
+
err:
|
241
|
+
io_uring_queue_exit(&ring);
|
242
|
+
return ret;
|
243
|
+
}
|
244
|
+
|
245
|
+
int main(int argc, char *argv[])
|
246
|
+
{
|
247
|
+
if (argc > 1)
|
248
|
+
return 0;
|
249
|
+
|
250
|
+
return test_ring();
|
251
|
+
}
|