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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +2 -1
  3. data/CHANGELOG.md +16 -0
  4. data/README.md +44 -1
  5. data/TODO.md +12 -3
  6. data/examples/bm_snooze.rb +89 -0
  7. data/examples/bm_sqlite.rb +89 -0
  8. data/examples/bm_write.rb +56 -0
  9. data/examples/dns_client.rb +12 -0
  10. data/examples/http_server.rb +42 -43
  11. data/examples/pg.rb +85 -0
  12. data/examples/server_client.rb +64 -0
  13. data/examples/snooze.rb +44 -0
  14. data/examples/stream.rb +85 -0
  15. data/examples/write_dev_null.rb +16 -0
  16. data/ext/um/extconf.rb +81 -14
  17. data/ext/um/um.c +468 -414
  18. data/ext/um/um.h +149 -40
  19. data/ext/um/um_async_op.c +40 -0
  20. data/ext/um/um_async_op_class.c +136 -0
  21. data/ext/um/um_buffer.c +49 -0
  22. data/ext/um/um_class.c +176 -44
  23. data/ext/um/um_const.c +174 -9
  24. data/ext/um/um_ext.c +8 -0
  25. data/ext/um/um_mutex_class.c +47 -0
  26. data/ext/um/um_op.c +89 -111
  27. data/ext/um/um_queue_class.c +58 -0
  28. data/ext/um/um_ssl.c +850 -0
  29. data/ext/um/um_ssl.h +22 -0
  30. data/ext/um/um_ssl_class.c +138 -0
  31. data/ext/um/um_sync.c +273 -0
  32. data/ext/um/um_utils.c +1 -1
  33. data/lib/uringmachine/dns_resolver.rb +84 -0
  34. data/lib/uringmachine/ssl/context_builder.rb +96 -0
  35. data/lib/uringmachine/ssl.rb +394 -0
  36. data/lib/uringmachine/version.rb +1 -1
  37. data/lib/uringmachine.rb +27 -3
  38. data/supressions/ruby.supp +71 -0
  39. data/test/helper.rb +6 -0
  40. data/test/test_async_op.rb +119 -0
  41. data/test/test_ssl.rb +155 -0
  42. data/test/test_um.rb +464 -47
  43. data/uringmachine.gemspec +3 -2
  44. data/vendor/liburing/.gitignore +5 -0
  45. data/vendor/liburing/CHANGELOG +1 -0
  46. data/vendor/liburing/configure +32 -0
  47. data/vendor/liburing/examples/Makefile +1 -0
  48. data/vendor/liburing/examples/reg-wait.c +159 -0
  49. data/vendor/liburing/liburing.spec +1 -1
  50. data/vendor/liburing/src/include/liburing/io_uring.h +48 -2
  51. data/vendor/liburing/src/include/liburing.h +28 -2
  52. data/vendor/liburing/src/int_flags.h +10 -3
  53. data/vendor/liburing/src/liburing-ffi.map +13 -2
  54. data/vendor/liburing/src/liburing.map +9 -0
  55. data/vendor/liburing/src/queue.c +25 -16
  56. data/vendor/liburing/src/register.c +73 -4
  57. data/vendor/liburing/src/setup.c +46 -18
  58. data/vendor/liburing/src/setup.h +6 -0
  59. data/vendor/liburing/test/Makefile +7 -0
  60. data/vendor/liburing/test/cmd-discard.c +427 -0
  61. data/vendor/liburing/test/fifo-nonblock-read.c +69 -0
  62. data/vendor/liburing/test/file-exit-unreg.c +48 -0
  63. data/vendor/liburing/test/io_uring_passthrough.c +2 -0
  64. data/vendor/liburing/test/io_uring_register.c +13 -2
  65. data/vendor/liburing/test/napi-test.c +1 -1
  66. data/vendor/liburing/test/no-mmap-inval.c +1 -1
  67. data/vendor/liburing/test/read-mshot-empty.c +2 -0
  68. data/vendor/liburing/test/read-mshot-stdin.c +121 -0
  69. data/vendor/liburing/test/read-mshot.c +6 -0
  70. data/vendor/liburing/test/recvsend_bundle.c +2 -2
  71. data/vendor/liburing/test/reg-fd-only.c +1 -1
  72. data/vendor/liburing/test/reg-wait.c +251 -0
  73. data/vendor/liburing/test/regbuf-clone.c +458 -0
  74. data/vendor/liburing/test/resize-rings.c +643 -0
  75. data/vendor/liburing/test/rsrc_tags.c +1 -1
  76. data/vendor/liburing/test/sqpoll-sleep.c +39 -8
  77. data/vendor/liburing/test/sqwait.c +136 -0
  78. data/vendor/liburing/test/sync-cancel.c +8 -1
  79. data/vendor/liburing/test/timeout.c +13 -8
  80. metadata +52 -8
  81. data/examples/http_server_multishot.rb +0 -57
  82. 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 test_poll_ringfd(void)
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(1, &ring, 0);
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;
@@ -147,7 +147,7 @@ static int receiver(int queue_flags)
147
147
  io_uring_prep_recv(sqe, fd, buffer, BUF_SIZE, 0);
148
148
 
149
149
  ret = io_uring_submit(&ring);
150
- if (ret != 1) {
150
+ if (ret < 0) {
151
151
  fprintf(stderr, "io_uring_submit: %i\n", ret);
152
152
  return 1;
153
153
  }
@@ -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;
@@ -151,6 +151,8 @@ int main(int argc, char *argv[])
151
151
  }
152
152
 
153
153
  pthread_join(thread, &tret);
154
+ io_uring_free_buf_ring(&ring, br, NR_BUFS, BGID);
155
+ io_uring_queue_exit(&ring);
154
156
  free(buf);
155
157
  return T_EXIT_PASS;
156
158
  }
@@ -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, 4096, MSG_SIZE * RECV_BIDS))
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, 4096, MSG_SIZE * nr_msgs))
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
+ }