uringmachine 0.3 → 0.5

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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +2 -1
  3. data/CHANGELOG.md +23 -0
  4. data/README.md +128 -0
  5. data/TODO.md +14 -0
  6. data/examples/bm_snooze.rb +89 -0
  7. data/examples/bm_write.rb +56 -0
  8. data/examples/dns_client.rb +12 -0
  9. data/examples/echo_server.rb +18 -40
  10. data/examples/http_server.rb +42 -43
  11. data/examples/inout.rb +19 -0
  12. data/examples/nc.rb +36 -0
  13. data/examples/server_client.rb +64 -0
  14. data/examples/snooze.rb +44 -0
  15. data/examples/write_dev_null.rb +16 -0
  16. data/ext/um/extconf.rb +24 -23
  17. data/ext/um/um.c +524 -278
  18. data/ext/um/um.h +146 -44
  19. data/ext/um/um_buffer.c +49 -0
  20. data/ext/um/um_class.c +217 -106
  21. data/ext/um/um_const.c +213 -0
  22. data/ext/um/um_ext.c +4 -0
  23. data/ext/um/um_mutex_class.c +47 -0
  24. data/ext/um/um_op.c +86 -114
  25. data/ext/um/um_queue_class.c +58 -0
  26. data/ext/um/um_sync.c +273 -0
  27. data/ext/um/um_utils.c +49 -4
  28. data/lib/uringmachine/dns_resolver.rb +84 -0
  29. data/lib/uringmachine/version.rb +1 -1
  30. data/lib/uringmachine.rb +28 -0
  31. data/supressions/ruby.supp +71 -0
  32. data/test/helper.rb +8 -0
  33. data/test/test_um.rb +685 -46
  34. data/vendor/liburing/.github/workflows/build.yml +29 -1
  35. data/vendor/liburing/.gitignore +6 -0
  36. data/vendor/liburing/CHANGELOG +16 -0
  37. data/vendor/liburing/CONTRIBUTING.md +165 -0
  38. data/vendor/liburing/configure +64 -0
  39. data/vendor/liburing/examples/Makefile +9 -1
  40. data/vendor/liburing/examples/kdigest.c +405 -0
  41. data/vendor/liburing/examples/proxy.c +75 -8
  42. data/vendor/liburing/examples/reg-wait.c +159 -0
  43. data/vendor/liburing/liburing.pc.in +1 -1
  44. data/vendor/liburing/liburing.spec +1 -1
  45. data/vendor/liburing/src/Makefile +16 -2
  46. data/vendor/liburing/src/include/liburing/io_uring.h +77 -0
  47. data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
  48. data/vendor/liburing/src/include/liburing.h +59 -6
  49. data/vendor/liburing/src/int_flags.h +10 -3
  50. data/vendor/liburing/src/liburing-ffi.map +16 -0
  51. data/vendor/liburing/src/liburing.map +10 -0
  52. data/vendor/liburing/src/queue.c +28 -16
  53. data/vendor/liburing/src/register.c +106 -1
  54. data/vendor/liburing/src/sanitize.c +176 -0
  55. data/vendor/liburing/src/setup.c +47 -19
  56. data/vendor/liburing/src/setup.h +6 -0
  57. data/vendor/liburing/test/35fa71a030ca.c +7 -0
  58. data/vendor/liburing/test/500f9fbadef8.c +2 -0
  59. data/vendor/liburing/test/7ad0e4b2f83c.c +0 -25
  60. data/vendor/liburing/test/917257daa0fe.c +7 -0
  61. data/vendor/liburing/test/Makefile +38 -4
  62. data/vendor/liburing/test/a0908ae19763.c +7 -0
  63. data/vendor/liburing/test/a4c0b3decb33.c +7 -0
  64. data/vendor/liburing/test/accept.c +14 -4
  65. data/vendor/liburing/test/b19062a56726.c +7 -0
  66. data/vendor/liburing/test/bind-listen.c +2 -2
  67. data/vendor/liburing/test/buf-ring-nommap.c +10 -3
  68. data/vendor/liburing/test/buf-ring.c +2 -0
  69. data/vendor/liburing/test/cmd-discard.c +427 -0
  70. data/vendor/liburing/test/coredump.c +7 -0
  71. data/vendor/liburing/test/cq-overflow.c +13 -1
  72. data/vendor/liburing/test/d4ae271dfaae.c +11 -3
  73. data/vendor/liburing/test/defer-taskrun.c +2 -2
  74. data/vendor/liburing/test/defer-tw-timeout.c +4 -1
  75. data/vendor/liburing/test/defer.c +2 -2
  76. data/vendor/liburing/test/double-poll-crash.c +1 -1
  77. data/vendor/liburing/test/eeed8b54e0df.c +2 -0
  78. data/vendor/liburing/test/eventfd.c +0 -1
  79. data/vendor/liburing/test/exit-no-cleanup.c +11 -0
  80. data/vendor/liburing/test/fadvise.c +9 -26
  81. data/vendor/liburing/test/fdinfo.c +9 -1
  82. data/vendor/liburing/test/fifo-nonblock-read.c +69 -0
  83. data/vendor/liburing/test/file-exit-unreg.c +48 -0
  84. data/vendor/liburing/test/file-register.c +14 -2
  85. data/vendor/liburing/test/file-update.c +1 -1
  86. data/vendor/liburing/test/file-verify.c +27 -16
  87. data/vendor/liburing/test/files-exit-hang-timeout.c +1 -2
  88. data/vendor/liburing/test/fixed-buf-iter.c +3 -1
  89. data/vendor/liburing/test/fixed-hugepage.c +12 -1
  90. data/vendor/liburing/test/fsnotify.c +1 -0
  91. data/vendor/liburing/test/futex.c +16 -4
  92. data/vendor/liburing/test/helpers.c +47 -0
  93. data/vendor/liburing/test/helpers.h +6 -0
  94. data/vendor/liburing/test/init-mem.c +5 -3
  95. data/vendor/liburing/test/io-cancel.c +0 -24
  96. data/vendor/liburing/test/io_uring_passthrough.c +4 -0
  97. data/vendor/liburing/test/io_uring_register.c +38 -8
  98. data/vendor/liburing/test/iopoll-leak.c +4 -0
  99. data/vendor/liburing/test/iopoll-overflow.c +1 -1
  100. data/vendor/liburing/test/iopoll.c +3 -3
  101. data/vendor/liburing/test/kallsyms.c +203 -0
  102. data/vendor/liburing/test/link-timeout.c +159 -0
  103. data/vendor/liburing/test/linked-defer-close.c +224 -0
  104. data/vendor/liburing/test/madvise.c +12 -25
  105. data/vendor/liburing/test/min-timeout-wait.c +0 -25
  106. data/vendor/liburing/test/min-timeout.c +0 -25
  107. data/vendor/liburing/test/mkdir.c +6 -0
  108. data/vendor/liburing/test/msg-ring.c +8 -2
  109. data/vendor/liburing/test/napi-test.c +16 -3
  110. data/vendor/liburing/test/no-mmap-inval.c +3 -1
  111. data/vendor/liburing/test/nop.c +44 -0
  112. data/vendor/liburing/test/ooo-file-unreg.c +1 -1
  113. data/vendor/liburing/test/open-close.c +40 -0
  114. data/vendor/liburing/test/openat2.c +37 -14
  115. data/vendor/liburing/test/poll-many.c +13 -7
  116. data/vendor/liburing/test/poll-mshot-update.c +17 -10
  117. data/vendor/liburing/test/poll-v-poll.c +6 -3
  118. data/vendor/liburing/test/pollfree.c +148 -0
  119. data/vendor/liburing/test/read-mshot-empty.c +158 -153
  120. data/vendor/liburing/test/read-mshot-stdin.c +121 -0
  121. data/vendor/liburing/test/read-mshot.c +282 -27
  122. data/vendor/liburing/test/read-write.c +78 -13
  123. data/vendor/liburing/test/recv-msgall-stream.c +3 -0
  124. data/vendor/liburing/test/recv-msgall.c +5 -0
  125. data/vendor/liburing/test/recvsend_bundle-inc.c +680 -0
  126. data/vendor/liburing/test/recvsend_bundle.c +94 -31
  127. data/vendor/liburing/test/reg-fd-only.c +15 -5
  128. data/vendor/liburing/test/reg-wait.c +251 -0
  129. data/vendor/liburing/test/regbuf-clone.c +645 -0
  130. data/vendor/liburing/test/regbuf-merge.c +7 -0
  131. data/vendor/liburing/test/register-restrictions.c +86 -85
  132. data/vendor/liburing/test/rename.c +59 -1
  133. data/vendor/liburing/test/resize-rings.c +643 -0
  134. data/vendor/liburing/test/ringbuf-read.c +5 -0
  135. data/vendor/liburing/test/ringbuf-status.c +5 -1
  136. data/vendor/liburing/test/rsrc_tags.c +1 -1
  137. data/vendor/liburing/test/runtests.sh +16 -1
  138. data/vendor/liburing/test/send-zerocopy.c +59 -0
  139. data/vendor/liburing/test/short-read.c +1 -0
  140. data/vendor/liburing/test/socket.c +43 -0
  141. data/vendor/liburing/test/splice.c +3 -1
  142. data/vendor/liburing/test/sq-poll-dup.c +1 -1
  143. data/vendor/liburing/test/sq-poll-share.c +2 -0
  144. data/vendor/liburing/test/sqpoll-disable-exit.c +8 -0
  145. data/vendor/liburing/test/sqpoll-exit-hang.c +1 -25
  146. data/vendor/liburing/test/sqpoll-sleep.c +40 -33
  147. data/vendor/liburing/test/sqwait.c +136 -0
  148. data/vendor/liburing/test/statx.c +89 -0
  149. data/vendor/liburing/test/stdout.c +2 -0
  150. data/vendor/liburing/test/submit-and-wait.c +1 -25
  151. data/vendor/liburing/test/submit-reuse.c +4 -26
  152. data/vendor/liburing/test/symlink.c +12 -1
  153. data/vendor/liburing/test/sync-cancel.c +56 -22
  154. data/vendor/liburing/test/thread-exit.c +5 -0
  155. data/vendor/liburing/test/timeout-new.c +1 -26
  156. data/vendor/liburing/test/timeout.c +25 -34
  157. data/vendor/liburing/test/unlink.c +94 -1
  158. data/vendor/liburing/test/uring_cmd_ublk.c +1252 -0
  159. data/vendor/liburing/test/waitid.c +62 -8
  160. data/vendor/liburing/test/wq-aff.c +35 -0
  161. data/vendor/liburing/test/xfail_prep_link_timeout_out_of_scope.c +46 -0
  162. data/vendor/liburing/test/xfail_register_buffers_out_of_scope.c +51 -0
  163. metadata +37 -6
  164. data/examples/event_loop.rb +0 -69
  165. data/examples/fibers.rb +0 -105
  166. data/examples/http_server_multishot.rb +0 -57
  167. data/examples/http_server_simpler.rb +0 -34
@@ -15,25 +15,32 @@
15
15
  #include "liburing.h"
16
16
 
17
17
  static int test_openat2(struct io_uring *ring, const char *path, int dfd,
18
- bool direct, int fixed_index)
18
+ bool direct, int fixed_index, int bad_how)
19
19
  {
20
20
  struct io_uring_cqe *cqe;
21
21
  struct io_uring_sqe *sqe;
22
- struct open_how how;
22
+ struct open_how __how, *how;
23
23
  int ret;
24
24
 
25
+ if (bad_how)
26
+ how = (struct open_how *) (uintptr_t) 0x1234;
27
+ else
28
+ how = &__how;
29
+
25
30
  sqe = io_uring_get_sqe(ring);
26
31
  if (!sqe) {
27
32
  fprintf(stderr, "get sqe failed\n");
28
33
  return -1;
29
34
  }
30
- memset(&how, 0, sizeof(how));
31
- how.flags = O_RDWR;
35
+ if (!bad_how) {
36
+ memset(how, 0, sizeof(*how));
37
+ how->flags = O_RDWR;
38
+ }
32
39
 
33
40
  if (!direct)
34
- io_uring_prep_openat2(sqe, dfd, path, &how);
41
+ io_uring_prep_openat2(sqe, dfd, path, how);
35
42
  else
36
- io_uring_prep_openat2_direct(sqe, dfd, path, &how, fixed_index);
43
+ io_uring_prep_openat2_direct(sqe, dfd, path, how, fixed_index);
37
44
 
38
45
  ret = io_uring_submit(ring);
39
46
  if (ret <= 0) {
@@ -78,7 +85,7 @@ static int test_open_fixed(const char *path, int dfd)
78
85
  return -1;
79
86
  }
80
87
 
81
- ret = test_openat2(&ring, path, dfd, true, 0);
88
+ ret = test_openat2(&ring, path, dfd, true, 0, 0);
82
89
  if (ret == -EINVAL) {
83
90
  printf("fixed open isn't supported\n");
84
91
  return 1;
@@ -135,7 +142,7 @@ static int test_open_fixed_fail(const char *path, int dfd)
135
142
  return -1;
136
143
  }
137
144
 
138
- ret = test_openat2(&ring, path, dfd, true, 0);
145
+ ret = test_openat2(&ring, path, dfd, true, 0, 0);
139
146
  if (ret != -ENXIO) {
140
147
  fprintf(stderr, "install into not existing table, %i\n", ret);
141
148
  return 1;
@@ -149,19 +156,19 @@ static int test_open_fixed_fail(const char *path, int dfd)
149
156
  return -1;
150
157
  }
151
158
 
152
- ret = test_openat2(&ring, path, dfd, true, 1);
159
+ ret = test_openat2(&ring, path, dfd, true, 1, 0);
153
160
  if (ret != -EINVAL) {
154
161
  fprintf(stderr, "install out of bounds, %i\n", ret);
155
162
  return -1;
156
163
  }
157
164
 
158
- ret = test_openat2(&ring, path, dfd, true, (1u << 16));
165
+ ret = test_openat2(&ring, path, dfd, true, (1u << 16), 0);
159
166
  if (ret != -EINVAL) {
160
167
  fprintf(stderr, "install out of bounds or u16 overflow, %i\n", ret);
161
168
  return -1;
162
169
  }
163
170
 
164
- ret = test_openat2(&ring, path, dfd, true, (1u << 16) + 1);
171
+ ret = test_openat2(&ring, path, dfd, true, (1u << 16) + 1, 0);
165
172
  if (ret != -EINVAL) {
166
173
  fprintf(stderr, "install out of bounds or u16 overflow, %i\n", ret);
167
174
  return -1;
@@ -196,7 +203,7 @@ static int test_direct_reinstall(const char *path, int dfd)
196
203
  }
197
204
 
198
205
  /* reinstall into the second slot */
199
- ret = test_openat2(&ring, path, dfd, true, 1);
206
+ ret = test_openat2(&ring, path, dfd, true, 1, 0);
200
207
  if (ret != 0) {
201
208
  fprintf(stderr, "reinstall failed, %i\n", ret);
202
209
  return -1;
@@ -264,18 +271,22 @@ int main(int argc, char *argv[])
264
271
  if (do_unlink)
265
272
  t_create_file(path_rel, 4096);
266
273
 
267
- ret = test_openat2(&ring, path, -1, false, 0);
274
+ ret = test_openat2(&ring, path, -1, false, 0, 0);
268
275
  if (ret < 0) {
269
276
  if (ret == -EINVAL) {
270
277
  fprintf(stdout, "openat2 not supported, skipping\n");
271
278
  goto done;
272
279
  }
280
+ if (ret == -EPERM || ret == -EACCES)
281
+ return T_EXIT_SKIP;
273
282
  fprintf(stderr, "test_openat2 absolute failed: %d\n", ret);
274
283
  goto err;
275
284
  }
276
285
 
277
- ret = test_openat2(&ring, path_rel, AT_FDCWD, false, 0);
286
+ ret = test_openat2(&ring, path_rel, AT_FDCWD, false, 0, 0);
278
287
  if (ret < 0) {
288
+ if (ret == -EPERM || ret == -EACCES)
289
+ return T_EXIT_SKIP;
279
290
  fprintf(stderr, "test_openat2 relative failed: %d\n", ret);
280
291
  goto err;
281
292
  }
@@ -299,6 +310,18 @@ int main(int argc, char *argv[])
299
310
  goto err;
300
311
  }
301
312
 
313
+ ret = test_openat2(&ring, (const char *) (uintptr_t) 0x1234, AT_FDCWD, false, 0, 0);
314
+ if (ret != -EFAULT) {
315
+ fprintf(stderr, "test_openat2 bad address failed: %d\n", ret);
316
+ goto err;
317
+ }
318
+
319
+ ret = test_openat2(&ring, path_rel, AT_FDCWD, false, 0, 1);
320
+ if (ret != -EFAULT) {
321
+ fprintf(stderr, "test_openat2 bad how failed: %d\n", ret);
322
+ goto err;
323
+ }
324
+
302
325
  done:
303
326
  unlink(path);
304
327
  if (do_unlink)
@@ -22,6 +22,8 @@
22
22
 
23
23
  #define RING_SIZE 512
24
24
 
25
+ static int nfiles = NFILES;
26
+
25
27
  struct p {
26
28
  int fd[2];
27
29
  int triggered;
@@ -91,7 +93,7 @@ static int trigger_polls(void)
91
93
  int off;
92
94
 
93
95
  do {
94
- off = rand() % NFILES;
96
+ off = rand() % nfiles;
95
97
  if (!p[off].triggered)
96
98
  break;
97
99
  } while (1);
@@ -109,7 +111,7 @@ static int trigger_polls(void)
109
111
 
110
112
  static int arm_polls(struct io_uring *ring)
111
113
  {
112
- int ret, to_arm = NFILES, i, off;
114
+ int ret, to_arm = nfiles, i, off;
113
115
 
114
116
  off = 0;
115
117
  while (to_arm) {
@@ -161,7 +163,7 @@ int main(int argc, char *argv[])
161
163
  int i, ret;
162
164
 
163
165
  if (argc > 1)
164
- return 0;
166
+ return T_EXIT_SKIP;
165
167
 
166
168
  if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
167
169
  perror("getrlimit");
@@ -169,8 +171,12 @@ int main(int argc, char *argv[])
169
171
  }
170
172
 
171
173
  if (rlim.rlim_cur < (2 * NFILES + 5)) {
172
- rlim.rlim_cur = (2 * NFILES + 5);
173
- rlim.rlim_max = rlim.rlim_cur;
174
+ rlim.rlim_cur = rlim.rlim_max;
175
+ nfiles = (rlim.rlim_cur / 2) - 5;
176
+ if (nfiles > NFILES)
177
+ nfiles = NFILES;
178
+ if (nfiles <= 0)
179
+ goto err_nofail;
174
180
  if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
175
181
  if (errno == EPERM)
176
182
  goto err_nofail;
@@ -179,7 +185,7 @@ int main(int argc, char *argv[])
179
185
  }
180
186
  }
181
187
 
182
- for (i = 0; i < NFILES; i++) {
188
+ for (i = 0; i < nfiles; i++) {
183
189
  if (pipe(p[i].fd) < 0) {
184
190
  perror("pipe");
185
191
  return T_EXIT_FAIL;
@@ -226,5 +232,5 @@ int main(int argc, char *argv[])
226
232
  err_nofail:
227
233
  fprintf(stderr, "poll-many: not enough files available (and not root), "
228
234
  "skipped\n");
229
- return 0;
235
+ return T_EXIT_SKIP;
230
236
  }
@@ -15,11 +15,14 @@
15
15
  #include <pthread.h>
16
16
 
17
17
  #include "liburing.h"
18
+ #include "helpers.h"
18
19
 
19
20
  #define NFILES 5000
20
21
  #define BATCH 500
21
22
  #define NLOOPS 1000
22
23
 
24
+ static int nfiles = NFILES;
25
+
23
26
  #define RING_SIZE 512
24
27
 
25
28
  struct p {
@@ -160,7 +163,7 @@ static int trigger_polls(void)
160
163
  int off;
161
164
 
162
165
  do {
163
- off = rand() % NFILES;
166
+ off = rand() % nfiles;
164
167
  if (!p[off].triggered)
165
168
  break;
166
169
  } while (1);
@@ -184,7 +187,7 @@ static void *trigger_polls_fn(void *data)
184
187
 
185
188
  static int arm_polls(struct io_uring *ring)
186
189
  {
187
- int ret, to_arm = NFILES, i, off;
190
+ int ret, to_arm = nfiles, i, off;
188
191
 
189
192
  off = 0;
190
193
  while (to_arm) {
@@ -220,7 +223,7 @@ static int run(int cqe)
220
223
  pthread_t thread;
221
224
  int i, j, ret;
222
225
 
223
- for (i = 0; i < NFILES; i++) {
226
+ for (i = 0; i < nfiles; i++) {
224
227
  if (pipe(p[i].fd) < 0) {
225
228
  perror("pipe");
226
229
  return 1;
@@ -252,12 +255,12 @@ static int run(int cqe)
252
255
  goto err;
253
256
  pthread_join(thread, NULL);
254
257
 
255
- for (j = 0; j < NFILES; j++)
258
+ for (j = 0; j < nfiles; j++)
256
259
  p[j].triggered = 0;
257
260
  }
258
261
 
259
262
  io_uring_queue_exit(&ring);
260
- for (i = 0; i < NFILES; i++) {
263
+ for (i = 0; i < nfiles; i++) {
261
264
  close(p[i].fd[0]);
262
265
  close(p[i].fd[1]);
263
266
  }
@@ -273,7 +276,7 @@ int main(int argc, char *argv[])
273
276
  int ret;
274
277
 
275
278
  if (argc > 1)
276
- return 0;
279
+ return T_EXIT_SKIP;
277
280
 
278
281
  ret = has_poll_update();
279
282
  if (ret < 0) {
@@ -290,13 +293,17 @@ int main(int argc, char *argv[])
290
293
  }
291
294
 
292
295
  if (rlim.rlim_cur < (2 * NFILES + 5)) {
293
- rlim.rlim_cur = (2 * NFILES + 5);
294
- rlim.rlim_max = rlim.rlim_cur;
296
+ rlim.rlim_cur = rlim.rlim_max;
297
+ nfiles = (rlim.rlim_cur / 2) - 5;
298
+ if (nfiles > NFILES)
299
+ nfiles = NFILES;
300
+ if (nfiles <= 0)
301
+ goto err_nofail;
295
302
  if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
296
303
  if (errno == EPERM)
297
304
  goto err_nofail;
298
305
  perror("setrlimit");
299
- goto err;
306
+ return T_EXIT_FAIL;
300
307
  }
301
308
  }
302
309
 
@@ -319,5 +326,5 @@ err:
319
326
  err_nofail:
320
327
  fprintf(stderr, "poll-many: not enough files available (and not root), "
321
328
  "skipped\n");
322
- return 0;
329
+ return T_EXIT_SKIP;
323
330
  }
@@ -17,6 +17,7 @@
17
17
  #include <sys/epoll.h>
18
18
 
19
19
  #include "liburing.h"
20
+ #include "helpers.h"
20
21
 
21
22
  struct thread_data {
22
23
  struct io_uring *ring;
@@ -174,6 +175,8 @@ static int do_fd_test(struct io_uring *ring, const char *fname, int events)
174
175
 
175
176
  fd = open(fname, O_RDONLY);
176
177
  if (fd < 0) {
178
+ if (errno == EPERM || errno == EACCES)
179
+ return T_EXIT_SKIP;
177
180
  perror("open");
178
181
  return 1;
179
182
  }
@@ -331,19 +334,19 @@ int main(int argc, char *argv[])
331
334
  fname = argv[0];
332
335
 
333
336
  ret = do_fd_test(&ring, fname, POLLIN);
334
- if (ret) {
337
+ if (ret == T_EXIT_FAIL) {
335
338
  fprintf(stderr, "fd test IN failed\n");
336
339
  return ret;
337
340
  }
338
341
 
339
342
  ret = do_fd_test(&ring, fname, POLLOUT);
340
- if (ret) {
343
+ if (ret == T_EXIT_FAIL) {
341
344
  fprintf(stderr, "fd test OUT failed\n");
342
345
  return ret;
343
346
  }
344
347
 
345
348
  ret = do_fd_test(&ring, fname, POLLOUT | POLLIN);
346
- if (ret) {
349
+ if (ret == T_EXIT_FAIL) {
347
350
  fprintf(stderr, "fd test IN|OUT failed\n");
348
351
  return ret;
349
352
  }
@@ -0,0 +1,148 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test pollfree wakeups
4
+ */
5
+ #include <fcntl.h>
6
+ #include <stdio.h>
7
+ #include <string.h>
8
+ #include <sys/stat.h>
9
+ #include <sys/types.h>
10
+ #include <sys/signalfd.h>
11
+ #include <unistd.h>
12
+ #include <stdlib.h>
13
+
14
+ #include "liburing.h"
15
+ #include "helpers.h"
16
+
17
+ static int no_signalfd;
18
+
19
+ static int child(int flags)
20
+ {
21
+ struct io_uring_sqe *sqe;
22
+ struct io_uring ring;
23
+ struct signalfd_siginfo si;
24
+ static unsigned long index;
25
+ sigset_t mask;
26
+ int ret, fd;
27
+
28
+ ret = io_uring_queue_init(4, &ring, flags);
29
+ if (ret) {
30
+ if (ret == -EINVAL)
31
+ return 0;
32
+ fprintf(stderr, "queue init failed %d\n", ret);
33
+ return ret;
34
+ }
35
+
36
+ sigemptyset(&mask);
37
+ sigaddset(&mask, SIGINT);
38
+
39
+ fd = signalfd(-1, &mask, SFD_NONBLOCK);
40
+ if (fd < 0) {
41
+ no_signalfd = 1;
42
+ perror("signalfd");
43
+ return 1;
44
+ }
45
+
46
+ sqe = io_uring_get_sqe(&ring);
47
+ io_uring_prep_read(sqe, fd, &si, sizeof(si), 0);
48
+ sqe->user_data = 1;
49
+ io_uring_submit(&ring);
50
+
51
+ sqe = io_uring_get_sqe(&ring);
52
+ io_uring_prep_read(sqe, fd, &si, sizeof(si), 0);
53
+ sqe->user_data = 2;
54
+ sqe->flags |= IOSQE_ASYNC;
55
+ io_uring_submit(&ring);
56
+
57
+ sqe = io_uring_get_sqe(&ring);
58
+ io_uring_prep_read(sqe, fd, &si, sizeof(si), 0);
59
+ sqe->user_data = 3;
60
+ io_uring_submit(&ring);
61
+
62
+ if (!(++index & 7))
63
+ usleep(100);
64
+
65
+ return 0;
66
+ }
67
+
68
+ static int run_test(int flags)
69
+ {
70
+ pid_t pid;
71
+ int ret;
72
+
73
+ pid = fork();
74
+ if (pid < 0) {
75
+ perror("fork");
76
+ return 1;
77
+ } else if (!pid) {
78
+ ret = child(flags);
79
+ _exit(ret);
80
+ } else {
81
+ int wstatus;
82
+ pid_t childpid;
83
+
84
+ do {
85
+ childpid = waitpid(pid, &wstatus, 0);
86
+ } while (childpid == (pid_t) -1 && (errno == EINTR));
87
+
88
+ if (errno == ECHILD)
89
+ wstatus = 0;
90
+ return wstatus;
91
+ }
92
+ }
93
+
94
+ static int test(int flags)
95
+ {
96
+ struct timeval start;
97
+ int ret;
98
+
99
+ gettimeofday(&start, NULL);
100
+ do {
101
+ ret = run_test(flags);
102
+ if (ret) {
103
+ fprintf(stderr, "test failed with flags %x\n", flags);
104
+ return 1;
105
+ }
106
+ if (no_signalfd)
107
+ break;
108
+ } while (mtime_since_now(&start) < 2500);
109
+
110
+ return 0;
111
+ }
112
+
113
+ int main(int argc, char *argv[])
114
+ {
115
+ int ret;
116
+
117
+ if (argc > 1)
118
+ return T_EXIT_SKIP;
119
+
120
+ ret = test(0);
121
+ if (ret) {
122
+ fprintf(stderr, "test 0 failed: %d\n", ret);
123
+ return ret;
124
+ }
125
+
126
+ if (no_signalfd)
127
+ return T_EXIT_SKIP;
128
+
129
+ ret = test(IORING_SETUP_SQPOLL);
130
+ if (ret) {
131
+ fprintf(stderr, "test SQPOLL failed: %d\n", ret);
132
+ return ret;
133
+ }
134
+
135
+ ret = test(IORING_SETUP_COOP_TASKRUN);
136
+ if (ret) {
137
+ fprintf(stderr, "test COOP failed: %d\n", ret);
138
+ return ret;
139
+ }
140
+
141
+ ret = test(IORING_SETUP_DEFER_TASKRUN|IORING_SETUP_SINGLE_ISSUER);
142
+ if (ret) {
143
+ fprintf(stderr, "test DEFER failed: %d\n", ret);
144
+ return ret;
145
+ }
146
+
147
+ return T_EXIT_PASS;
148
+ }