uringmachine 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. checksums.yaml +7 -0
  2. data/.github/dependabot.yml +12 -0
  3. data/.github/workflows/test.yml +35 -0
  4. data/.gitignore +59 -0
  5. data/.gitmodules +3 -0
  6. data/CHANGELOG.md +7 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +21 -0
  9. data/README.md +11 -0
  10. data/Rakefile +39 -0
  11. data/TODO.md +0 -0
  12. data/examples/echo_server.rb +52 -0
  13. data/examples/event_loop.rb +69 -0
  14. data/examples/fibers.rb +105 -0
  15. data/examples/http_server.rb +56 -0
  16. data/examples/http_server_multishot.rb +57 -0
  17. data/examples/http_server_simpler.rb +34 -0
  18. data/ext/um/extconf.rb +71 -0
  19. data/ext/um/iou.h +101 -0
  20. data/ext/um/op_ctx.c +138 -0
  21. data/ext/um/ring.c +755 -0
  22. data/ext/um/um.c +267 -0
  23. data/ext/um/um.h +97 -0
  24. data/ext/um/um_class.c +175 -0
  25. data/ext/um/um_ext.c +11 -0
  26. data/ext/um/um_op.c +87 -0
  27. data/ext/um/um_utils.c +23 -0
  28. data/lib/uringmachine/version.rb +3 -0
  29. data/lib/uringmachine.rb +8 -0
  30. data/test/helper.rb +70 -0
  31. data/test/test_iou.rb +876 -0
  32. data/test/test_um.rb +168 -0
  33. data/uringmachine.gemspec +27 -0
  34. data/vendor/liburing/.github/actions/codespell/stopwords +7 -0
  35. data/vendor/liburing/.github/pull_request_template.md +86 -0
  36. data/vendor/liburing/.github/workflows/build.yml +137 -0
  37. data/vendor/liburing/.github/workflows/codespell.yml +25 -0
  38. data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
  39. data/vendor/liburing/.gitignore +41 -0
  40. data/vendor/liburing/CHANGELOG +111 -0
  41. data/vendor/liburing/CITATION.cff +11 -0
  42. data/vendor/liburing/COPYING +502 -0
  43. data/vendor/liburing/COPYING.GPL +339 -0
  44. data/vendor/liburing/LICENSE +20 -0
  45. data/vendor/liburing/Makefile +96 -0
  46. data/vendor/liburing/Makefile.common +7 -0
  47. data/vendor/liburing/Makefile.quiet +11 -0
  48. data/vendor/liburing/README +106 -0
  49. data/vendor/liburing/SECURITY.md +6 -0
  50. data/vendor/liburing/configure +624 -0
  51. data/vendor/liburing/debian/README.Debian +7 -0
  52. data/vendor/liburing/debian/changelog +38 -0
  53. data/vendor/liburing/debian/control +39 -0
  54. data/vendor/liburing/debian/copyright +49 -0
  55. data/vendor/liburing/debian/liburing-dev.install +4 -0
  56. data/vendor/liburing/debian/liburing-dev.manpages +5 -0
  57. data/vendor/liburing/debian/liburing2.install +1 -0
  58. data/vendor/liburing/debian/liburing2.symbols +56 -0
  59. data/vendor/liburing/debian/patches/series +1 -0
  60. data/vendor/liburing/debian/rules +29 -0
  61. data/vendor/liburing/debian/source/format +1 -0
  62. data/vendor/liburing/debian/source/local-options +2 -0
  63. data/vendor/liburing/debian/source/options +1 -0
  64. data/vendor/liburing/debian/watch +3 -0
  65. data/vendor/liburing/examples/Makefile +53 -0
  66. data/vendor/liburing/examples/helpers.c +62 -0
  67. data/vendor/liburing/examples/helpers.h +7 -0
  68. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  69. data/vendor/liburing/examples/io_uring-cp.c +282 -0
  70. data/vendor/liburing/examples/io_uring-test.c +112 -0
  71. data/vendor/liburing/examples/io_uring-udp.c +403 -0
  72. data/vendor/liburing/examples/link-cp.c +193 -0
  73. data/vendor/liburing/examples/napi-busy-poll-client.c +509 -0
  74. data/vendor/liburing/examples/napi-busy-poll-server.c +450 -0
  75. data/vendor/liburing/examples/poll-bench.c +101 -0
  76. data/vendor/liburing/examples/proxy.c +2461 -0
  77. data/vendor/liburing/examples/proxy.h +102 -0
  78. data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
  79. data/vendor/liburing/examples/send-zerocopy.c +658 -0
  80. data/vendor/liburing/examples/ucontext-cp.c +258 -0
  81. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  82. data/vendor/liburing/liburing.pc.in +12 -0
  83. data/vendor/liburing/liburing.spec +66 -0
  84. data/vendor/liburing/make-debs.sh +55 -0
  85. data/vendor/liburing/src/Makefile +129 -0
  86. data/vendor/liburing/src/arch/aarch64/lib.h +47 -0
  87. data/vendor/liburing/src/arch/aarch64/syscall.h +91 -0
  88. data/vendor/liburing/src/arch/generic/lib.h +17 -0
  89. data/vendor/liburing/src/arch/generic/syscall.h +100 -0
  90. data/vendor/liburing/src/arch/riscv64/lib.h +48 -0
  91. data/vendor/liburing/src/arch/riscv64/syscall.h +100 -0
  92. data/vendor/liburing/src/arch/syscall-defs.h +94 -0
  93. data/vendor/liburing/src/arch/x86/lib.h +11 -0
  94. data/vendor/liburing/src/arch/x86/syscall.h +296 -0
  95. data/vendor/liburing/src/ffi.c +15 -0
  96. data/vendor/liburing/src/include/liburing/barrier.h +81 -0
  97. data/vendor/liburing/src/include/liburing/io_uring.h +818 -0
  98. data/vendor/liburing/src/include/liburing.h +1602 -0
  99. data/vendor/liburing/src/int_flags.h +11 -0
  100. data/vendor/liburing/src/lib.h +52 -0
  101. data/vendor/liburing/src/liburing-ffi.map +211 -0
  102. data/vendor/liburing/src/liburing.map +104 -0
  103. data/vendor/liburing/src/nolibc.c +55 -0
  104. data/vendor/liburing/src/queue.c +468 -0
  105. data/vendor/liburing/src/register.c +374 -0
  106. data/vendor/liburing/src/setup.c +689 -0
  107. data/vendor/liburing/src/setup.h +9 -0
  108. data/vendor/liburing/src/syscall.c +29 -0
  109. data/vendor/liburing/src/syscall.h +53 -0
  110. data/vendor/liburing/src/version.c +21 -0
  111. data/vendor/liburing/test/232c93d07b74.c +305 -0
  112. data/vendor/liburing/test/35fa71a030ca.c +329 -0
  113. data/vendor/liburing/test/500f9fbadef8.c +91 -0
  114. data/vendor/liburing/test/7ad0e4b2f83c.c +94 -0
  115. data/vendor/liburing/test/8a9973408177.c +107 -0
  116. data/vendor/liburing/test/917257daa0fe.c +54 -0
  117. data/vendor/liburing/test/Makefile +297 -0
  118. data/vendor/liburing/test/a0908ae19763.c +59 -0
  119. data/vendor/liburing/test/a4c0b3decb33.c +181 -0
  120. data/vendor/liburing/test/accept-link.c +255 -0
  121. data/vendor/liburing/test/accept-non-empty.c +256 -0
  122. data/vendor/liburing/test/accept-reuse.c +163 -0
  123. data/vendor/liburing/test/accept-test.c +83 -0
  124. data/vendor/liburing/test/accept.c +919 -0
  125. data/vendor/liburing/test/across-fork.c +284 -0
  126. data/vendor/liburing/test/b19062a56726.c +54 -0
  127. data/vendor/liburing/test/b5837bd5311d.c +78 -0
  128. data/vendor/liburing/test/bind-listen.c +408 -0
  129. data/vendor/liburing/test/buf-ring-nommap.c +123 -0
  130. data/vendor/liburing/test/buf-ring-put.c +83 -0
  131. data/vendor/liburing/test/buf-ring.c +473 -0
  132. data/vendor/liburing/test/ce593a6c480a.c +139 -0
  133. data/vendor/liburing/test/close-opath.c +123 -0
  134. data/vendor/liburing/test/config +14 -0
  135. data/vendor/liburing/test/connect-rep.c +204 -0
  136. data/vendor/liburing/test/connect.c +442 -0
  137. data/vendor/liburing/test/coredump.c +60 -0
  138. data/vendor/liburing/test/cq-full.c +97 -0
  139. data/vendor/liburing/test/cq-overflow.c +530 -0
  140. data/vendor/liburing/test/cq-peek-batch.c +103 -0
  141. data/vendor/liburing/test/cq-ready.c +95 -0
  142. data/vendor/liburing/test/cq-size.c +65 -0
  143. data/vendor/liburing/test/d4ae271dfaae.c +96 -0
  144. data/vendor/liburing/test/d77a67ed5f27.c +65 -0
  145. data/vendor/liburing/test/defer-taskrun.c +391 -0
  146. data/vendor/liburing/test/defer-tw-timeout.c +173 -0
  147. data/vendor/liburing/test/defer.c +319 -0
  148. data/vendor/liburing/test/double-poll-crash.c +195 -0
  149. data/vendor/liburing/test/drop-submit.c +94 -0
  150. data/vendor/liburing/test/eeed8b54e0df.c +120 -0
  151. data/vendor/liburing/test/empty-eownerdead.c +45 -0
  152. data/vendor/liburing/test/eploop.c +74 -0
  153. data/vendor/liburing/test/eventfd-disable.c +179 -0
  154. data/vendor/liburing/test/eventfd-reg.c +77 -0
  155. data/vendor/liburing/test/eventfd-ring.c +98 -0
  156. data/vendor/liburing/test/eventfd.c +113 -0
  157. data/vendor/liburing/test/evloop.c +73 -0
  158. data/vendor/liburing/test/exec-target.c +6 -0
  159. data/vendor/liburing/test/exit-no-cleanup.c +117 -0
  160. data/vendor/liburing/test/fadvise.c +202 -0
  161. data/vendor/liburing/test/fallocate.c +265 -0
  162. data/vendor/liburing/test/fc2a85cb02ef.c +132 -0
  163. data/vendor/liburing/test/fd-install.c +500 -0
  164. data/vendor/liburing/test/fd-pass.c +237 -0
  165. data/vendor/liburing/test/fdinfo.c +419 -0
  166. data/vendor/liburing/test/file-register.c +1189 -0
  167. data/vendor/liburing/test/file-update.c +231 -0
  168. data/vendor/liburing/test/file-verify.c +654 -0
  169. data/vendor/liburing/test/files-exit-hang-poll.c +114 -0
  170. data/vendor/liburing/test/files-exit-hang-timeout.c +137 -0
  171. data/vendor/liburing/test/fixed-buf-iter.c +115 -0
  172. data/vendor/liburing/test/fixed-buf-merge.c +101 -0
  173. data/vendor/liburing/test/fixed-hugepage.c +411 -0
  174. data/vendor/liburing/test/fixed-link.c +90 -0
  175. data/vendor/liburing/test/fixed-reuse.c +160 -0
  176. data/vendor/liburing/test/fpos.c +255 -0
  177. data/vendor/liburing/test/fsnotify.c +118 -0
  178. data/vendor/liburing/test/fsync.c +224 -0
  179. data/vendor/liburing/test/futex.c +571 -0
  180. data/vendor/liburing/test/hardlink.c +170 -0
  181. data/vendor/liburing/test/helpers.c +318 -0
  182. data/vendor/liburing/test/helpers.h +108 -0
  183. data/vendor/liburing/test/ignore-single-mmap.c +48 -0
  184. data/vendor/liburing/test/init-mem.c +164 -0
  185. data/vendor/liburing/test/io-cancel.c +561 -0
  186. data/vendor/liburing/test/io_uring_enter.c +264 -0
  187. data/vendor/liburing/test/io_uring_passthrough.c +482 -0
  188. data/vendor/liburing/test/io_uring_register.c +503 -0
  189. data/vendor/liburing/test/io_uring_setup.c +110 -0
  190. data/vendor/liburing/test/iopoll-leak.c +85 -0
  191. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  192. data/vendor/liburing/test/iopoll.c +465 -0
  193. data/vendor/liburing/test/lfs-openat-write.c +119 -0
  194. data/vendor/liburing/test/lfs-openat.c +273 -0
  195. data/vendor/liburing/test/link-timeout.c +1108 -0
  196. data/vendor/liburing/test/link.c +497 -0
  197. data/vendor/liburing/test/link_drain.c +255 -0
  198. data/vendor/liburing/test/madvise.c +195 -0
  199. data/vendor/liburing/test/min-timeout-wait.c +354 -0
  200. data/vendor/liburing/test/min-timeout.c +233 -0
  201. data/vendor/liburing/test/mkdir.c +112 -0
  202. data/vendor/liburing/test/msg-ring-fd.c +331 -0
  203. data/vendor/liburing/test/msg-ring-flags.c +212 -0
  204. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  205. data/vendor/liburing/test/msg-ring.c +467 -0
  206. data/vendor/liburing/test/multicqes_drain.c +429 -0
  207. data/vendor/liburing/test/napi-test.c +215 -0
  208. data/vendor/liburing/test/napi-test.sh +48 -0
  209. data/vendor/liburing/test/no-mmap-inval.c +42 -0
  210. data/vendor/liburing/test/nolibc.c +62 -0
  211. data/vendor/liburing/test/nop-all-sizes.c +99 -0
  212. data/vendor/liburing/test/nop.c +177 -0
  213. data/vendor/liburing/test/nvme.h +169 -0
  214. data/vendor/liburing/test/ooo-file-unreg.c +82 -0
  215. data/vendor/liburing/test/open-close.c +261 -0
  216. data/vendor/liburing/test/open-direct-link.c +188 -0
  217. data/vendor/liburing/test/open-direct-pick.c +180 -0
  218. data/vendor/liburing/test/openat2.c +312 -0
  219. data/vendor/liburing/test/personality.c +204 -0
  220. data/vendor/liburing/test/pipe-bug.c +95 -0
  221. data/vendor/liburing/test/pipe-eof.c +83 -0
  222. data/vendor/liburing/test/pipe-reuse.c +105 -0
  223. data/vendor/liburing/test/poll-cancel-all.c +496 -0
  224. data/vendor/liburing/test/poll-cancel-ton.c +135 -0
  225. data/vendor/liburing/test/poll-cancel.c +228 -0
  226. data/vendor/liburing/test/poll-link.c +221 -0
  227. data/vendor/liburing/test/poll-many.c +230 -0
  228. data/vendor/liburing/test/poll-mshot-overflow.c +265 -0
  229. data/vendor/liburing/test/poll-mshot-update.c +323 -0
  230. data/vendor/liburing/test/poll-race-mshot.c +276 -0
  231. data/vendor/liburing/test/poll-race.c +105 -0
  232. data/vendor/liburing/test/poll-ring.c +48 -0
  233. data/vendor/liburing/test/poll-v-poll.c +353 -0
  234. data/vendor/liburing/test/poll.c +327 -0
  235. data/vendor/liburing/test/probe.c +135 -0
  236. data/vendor/liburing/test/read-before-exit.c +129 -0
  237. data/vendor/liburing/test/read-mshot-empty.c +153 -0
  238. data/vendor/liburing/test/read-mshot.c +404 -0
  239. data/vendor/liburing/test/read-write.c +1013 -0
  240. data/vendor/liburing/test/recv-msgall-stream.c +398 -0
  241. data/vendor/liburing/test/recv-msgall.c +263 -0
  242. data/vendor/liburing/test/recv-multishot.c +602 -0
  243. data/vendor/liburing/test/recvsend_bundle.c +691 -0
  244. data/vendor/liburing/test/reg-fd-only.c +131 -0
  245. data/vendor/liburing/test/reg-hint.c +56 -0
  246. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  247. data/vendor/liburing/test/regbuf-merge.c +91 -0
  248. data/vendor/liburing/test/register-restrictions.c +633 -0
  249. data/vendor/liburing/test/rename.c +132 -0
  250. data/vendor/liburing/test/ring-leak.c +283 -0
  251. data/vendor/liburing/test/ring-leak2.c +249 -0
  252. data/vendor/liburing/test/ringbuf-read.c +196 -0
  253. data/vendor/liburing/test/ringbuf-status.c +242 -0
  254. data/vendor/liburing/test/rsrc_tags.c +461 -0
  255. data/vendor/liburing/test/runtests-loop.sh +16 -0
  256. data/vendor/liburing/test/runtests-quiet.sh +11 -0
  257. data/vendor/liburing/test/runtests.sh +168 -0
  258. data/vendor/liburing/test/rw_merge_test.c +98 -0
  259. data/vendor/liburing/test/self.c +91 -0
  260. data/vendor/liburing/test/send-zerocopy.c +971 -0
  261. data/vendor/liburing/test/send_recv.c +412 -0
  262. data/vendor/liburing/test/send_recvmsg.c +444 -0
  263. data/vendor/liburing/test/shared-wq.c +84 -0
  264. data/vendor/liburing/test/short-read.c +75 -0
  265. data/vendor/liburing/test/shutdown.c +165 -0
  266. data/vendor/liburing/test/sigfd-deadlock.c +88 -0
  267. data/vendor/liburing/test/single-issuer.c +169 -0
  268. data/vendor/liburing/test/skip-cqe.c +428 -0
  269. data/vendor/liburing/test/socket-getsetsock-cmd.c +346 -0
  270. data/vendor/liburing/test/socket-io-cmd.c +237 -0
  271. data/vendor/liburing/test/socket-rw-eagain.c +149 -0
  272. data/vendor/liburing/test/socket-rw-offset.c +149 -0
  273. data/vendor/liburing/test/socket-rw.c +137 -0
  274. data/vendor/liburing/test/socket.c +408 -0
  275. data/vendor/liburing/test/splice.c +512 -0
  276. data/vendor/liburing/test/sq-full-cpp.cc +45 -0
  277. data/vendor/liburing/test/sq-full.c +45 -0
  278. data/vendor/liburing/test/sq-poll-dup.c +211 -0
  279. data/vendor/liburing/test/sq-poll-kthread.c +169 -0
  280. data/vendor/liburing/test/sq-poll-share.c +138 -0
  281. data/vendor/liburing/test/sq-space_left.c +159 -0
  282. data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
  283. data/vendor/liburing/test/sqpoll-exec.c +132 -0
  284. data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
  285. data/vendor/liburing/test/sqpoll-sleep.c +69 -0
  286. data/vendor/liburing/test/statx.c +172 -0
  287. data/vendor/liburing/test/stdout.c +232 -0
  288. data/vendor/liburing/test/submit-and-wait.c +108 -0
  289. data/vendor/liburing/test/submit-link-fail.c +156 -0
  290. data/vendor/liburing/test/submit-reuse.c +237 -0
  291. data/vendor/liburing/test/symlink.c +117 -0
  292. data/vendor/liburing/test/sync-cancel.c +235 -0
  293. data/vendor/liburing/test/teardowns.c +58 -0
  294. data/vendor/liburing/test/test.h +36 -0
  295. data/vendor/liburing/test/thread-exit.c +143 -0
  296. data/vendor/liburing/test/timeout-new.c +256 -0
  297. data/vendor/liburing/test/timeout.c +1798 -0
  298. data/vendor/liburing/test/truncate.c +186 -0
  299. data/vendor/liburing/test/tty-write-dpoll.c +60 -0
  300. data/vendor/liburing/test/unlink.c +112 -0
  301. data/vendor/liburing/test/version.c +25 -0
  302. data/vendor/liburing/test/wait-timeout.c +287 -0
  303. data/vendor/liburing/test/waitid.c +373 -0
  304. data/vendor/liburing/test/wakeup-hang.c +162 -0
  305. data/vendor/liburing/test/wq-aff.c +146 -0
  306. data/vendor/liburing/test/xattr.c +442 -0
  307. metadata +412 -0
@@ -0,0 +1,105 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Check split up read is handled correctly
4
+ */
5
+ #include <errno.h>
6
+ #include <stdio.h>
7
+ #include <string.h>
8
+ #include <unistd.h>
9
+ #include <pthread.h>
10
+ #include <string.h>
11
+ #include "liburing.h"
12
+
13
+ #define BUFSIZE 16384
14
+ #define BUFFERS 16
15
+
16
+ int main(int argc, char *argv[])
17
+ {
18
+ char buf[BUFSIZE], wbuf[BUFSIZE];
19
+ struct iovec iov[BUFFERS];
20
+ struct io_uring_params p = { };
21
+ struct io_uring ring;
22
+ struct io_uring_sqe *sqe;
23
+ struct io_uring_cqe *cqe;
24
+ int ret, i, fds[2];
25
+ void *ptr;
26
+
27
+ if (pipe(fds) < 0) {
28
+ perror("pipe");
29
+ return 1;
30
+ }
31
+
32
+ ptr = buf;
33
+ for (i = 0; i < BUFFERS; i++) {
34
+ unsigned bsize = BUFSIZE / BUFFERS;
35
+
36
+ iov[i].iov_base = ptr;
37
+ iov[i].iov_len = bsize;
38
+ ptr += bsize;
39
+ }
40
+
41
+ ret = io_uring_queue_init_params(8, &ring, &p);
42
+ if (ret) {
43
+ fprintf(stderr, "queue_init: %d\n", ret);
44
+ return 1;
45
+ }
46
+ if (!(p.features & IORING_FEAT_SUBMIT_STABLE)) {
47
+ fprintf(stdout, "FEAT_SUBMIT_STABLE not there, skipping\n");
48
+ return 0;
49
+ }
50
+
51
+ ptr = wbuf;
52
+ memset(ptr, 0x11, sizeof(wbuf) / 2);
53
+ ptr += sizeof(wbuf) / 2;
54
+ memset(ptr, 0x22, sizeof(wbuf) / 2);
55
+
56
+ ret = write(fds[1], wbuf, sizeof(wbuf) / 2);
57
+ if (ret != sizeof(wbuf) / 2) {
58
+ fprintf(stderr, "Bad write\n");
59
+ ret = 1;
60
+ goto err;
61
+ }
62
+
63
+ sqe = io_uring_get_sqe(&ring);
64
+ io_uring_prep_readv(sqe, fds[0], iov, BUFFERS, 0);
65
+ ret = io_uring_submit(&ring);
66
+ if (ret != 1) {
67
+ fprintf(stderr, "submit: %d\n", ret);
68
+ return 1;
69
+ }
70
+
71
+ for (i = 0; i < BUFFERS; i++) {
72
+ iov[i].iov_base = NULL;
73
+ iov[i].iov_len = 1000000;
74
+ }
75
+
76
+ ret = write(fds[1], ptr, sizeof(wbuf) / 2);
77
+ if (ret != sizeof(wbuf) / 2) {
78
+ fprintf(stderr, "Bad write\n");
79
+ ret = 1;
80
+ goto err;
81
+ }
82
+
83
+ ret = io_uring_wait_cqe(&ring, &cqe);
84
+ if (ret) {
85
+ fprintf(stderr, "wait: %d\n", ret);
86
+ return 1;
87
+ }
88
+
89
+ if (cqe->res < 0) {
90
+ fprintf(stderr, "Read error: %s\n", strerror(-cqe->res));
91
+ return 1;
92
+ } else if (cqe->res != sizeof(wbuf)) {
93
+ /* ignore short read, not a failure */
94
+ goto err;
95
+ }
96
+ io_uring_cqe_seen(&ring, cqe);
97
+
98
+ ret = memcmp(wbuf, buf, sizeof(wbuf));
99
+ if (ret)
100
+ fprintf(stderr, "Read data mismatch\n");
101
+
102
+ err:
103
+ io_uring_queue_exit(&ring);
104
+ return ret;
105
+ }
@@ -0,0 +1,496 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: Test IORING_ASYNC_CANCEL_{ALL,FD}
4
+ *
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <poll.h>
12
+
13
+ #include "liburing.h"
14
+
15
+ static int no_cancel_flags;
16
+
17
+ static int test1(struct io_uring *ring, int *fd, int fixed)
18
+ {
19
+ struct io_uring_sqe *sqe;
20
+ struct io_uring_cqe *cqe;
21
+ int ret, i, __fd = fd[0];
22
+
23
+ if (fixed)
24
+ __fd = 0;
25
+
26
+ if (fixed) {
27
+ ret = io_uring_register_files(ring, fd, 1);
28
+ if (ret) {
29
+ fprintf(stderr, "failed file register %d\n", ret);
30
+ return 1;
31
+ }
32
+ }
33
+
34
+ for (i = 0; i < 8; i++) {
35
+ sqe = io_uring_get_sqe(ring);
36
+ if (!sqe) {
37
+ fprintf(stderr, "get sqe failed\n");
38
+ return 1;
39
+ }
40
+
41
+ io_uring_prep_poll_add(sqe, __fd, POLLIN);
42
+ sqe->user_data = i + 1;
43
+ if (fixed)
44
+ sqe->flags |= IOSQE_FIXED_FILE;
45
+ }
46
+
47
+ ret = io_uring_submit(ring);
48
+ if (ret < 8) {
49
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
50
+ return 1;
51
+ }
52
+
53
+ sqe = io_uring_get_sqe(ring);
54
+ if (!sqe) {
55
+ fprintf(stderr, "get sqe failed\n");
56
+ return 1;
57
+ }
58
+
59
+ /*
60
+ * Mark CANCEL_ALL to cancel all matching the key, and use
61
+ * CANCEL_FD to cancel requests matching the specified fd.
62
+ * This should cancel all the pending poll requests on the pipe
63
+ * input.
64
+ */
65
+ io_uring_prep_cancel(sqe, 0, IORING_ASYNC_CANCEL_ALL);
66
+ sqe->cancel_flags |= IORING_ASYNC_CANCEL_FD;
67
+ if (fixed)
68
+ sqe->cancel_flags |= IORING_ASYNC_CANCEL_FD_FIXED;
69
+ sqe->fd = __fd;
70
+ sqe->user_data = 100;
71
+
72
+ ret = io_uring_submit(ring);
73
+ if (ret < 1) {
74
+ fprintf(stderr, "child: sqe submit failed: %d\n", ret);
75
+ return 1;
76
+ }
77
+
78
+ for (i = 0; i < 9; i++) {
79
+ if (no_cancel_flags)
80
+ break;
81
+ ret = io_uring_wait_cqe(ring, &cqe);
82
+ if (ret) {
83
+ fprintf(stderr, "wait=%d\n", ret);
84
+ return 1;
85
+ }
86
+ switch (cqe->user_data) {
87
+ case 100:
88
+ if (cqe->res == -EINVAL) {
89
+ no_cancel_flags = 1;
90
+ break;
91
+ }
92
+ if (cqe->res != 8) {
93
+ fprintf(stderr, "canceled %d\n", cqe->res);
94
+ return 1;
95
+ }
96
+ break;
97
+ case 1 ... 8:
98
+ if (cqe->res != -ECANCELED) {
99
+ fprintf(stderr, "poll res %d\n", cqe->res);
100
+ return 1;
101
+ }
102
+ break;
103
+ default:
104
+ fprintf(stderr, "invalid user_data %lu\n",
105
+ (unsigned long) cqe->user_data);
106
+ return 1;
107
+ }
108
+ io_uring_cqe_seen(ring, cqe);
109
+ }
110
+
111
+ if (fixed)
112
+ io_uring_unregister_files(ring);
113
+
114
+ return 0;
115
+ }
116
+
117
+ static int test2(struct io_uring *ring, int *fd)
118
+ {
119
+ struct io_uring_sqe *sqe;
120
+ struct io_uring_cqe *cqe;
121
+ int ret, i, fd2[2];
122
+
123
+ if (pipe(fd2) < 0) {
124
+ perror("pipe");
125
+ return 1;
126
+ }
127
+
128
+ for (i = 0; i < 8; i++) {
129
+ sqe = io_uring_get_sqe(ring);
130
+ if (!sqe) {
131
+ fprintf(stderr, "get sqe failed\n");
132
+ goto err;
133
+ }
134
+
135
+ if (!(i & 1))
136
+ io_uring_prep_poll_add(sqe, fd[0], POLLIN);
137
+ else
138
+ io_uring_prep_poll_add(sqe, fd2[0], POLLIN);
139
+ sqe->user_data = i & 1;
140
+ }
141
+
142
+ ret = io_uring_submit(ring);
143
+ if (ret < 8) {
144
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
145
+ goto err;
146
+ }
147
+
148
+ sqe = io_uring_get_sqe(ring);
149
+ if (!sqe) {
150
+ fprintf(stderr, "get sqe failed\n");
151
+ goto err;
152
+ }
153
+
154
+ /*
155
+ * Mark CANCEL_ALL to cancel all matching the key, and use
156
+ * CANCEL_FD to cancel requests matching the specified fd.
157
+ * This should cancel all the pending poll requests on the pipe
158
+ * input.
159
+ */
160
+ io_uring_prep_cancel(sqe, 0, IORING_ASYNC_CANCEL_ALL);
161
+ sqe->cancel_flags |= IORING_ASYNC_CANCEL_FD;
162
+ sqe->fd = fd[0];
163
+ sqe->user_data = 100;
164
+
165
+ ret = io_uring_submit(ring);
166
+ if (ret < 1) {
167
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
168
+ goto err;
169
+ }
170
+
171
+ for (i = 0; i < 5; i++) {
172
+ ret = io_uring_wait_cqe(ring, &cqe);
173
+ if (ret) {
174
+ fprintf(stderr, "wait=%d\n", ret);
175
+ goto err;
176
+ }
177
+ switch (cqe->user_data) {
178
+ case 100:
179
+ if (cqe->res != 4) {
180
+ fprintf(stderr, "canceled %d\n", cqe->res);
181
+ goto err;
182
+ }
183
+ break;
184
+ case 0:
185
+ if (cqe->res != -ECANCELED) {
186
+ fprintf(stderr, "poll res %d\n", cqe->res);
187
+ goto err;
188
+ }
189
+ break;
190
+ default:
191
+ fprintf(stderr, "invalid user_data %lu\n",
192
+ (unsigned long) cqe->user_data);
193
+ goto err;
194
+ }
195
+ io_uring_cqe_seen(ring, cqe);
196
+ }
197
+
198
+ usleep(1000);
199
+
200
+ /*
201
+ * Should not have any pending CQEs now
202
+ */
203
+ ret = io_uring_peek_cqe(ring, &cqe);
204
+ if (!ret) {
205
+ fprintf(stderr, "Unexpected extra cancel cqe\n");
206
+ goto err;
207
+ }
208
+
209
+ sqe = io_uring_get_sqe(ring);
210
+ if (!sqe) {
211
+ fprintf(stderr, "get sqe failed\n");
212
+ goto err;
213
+ }
214
+
215
+ /*
216
+ * Mark CANCEL_ALL to cancel all matching the key, and use
217
+ * CANCEL_FD to cancel requests matching the specified fd.
218
+ * This should cancel all the pending poll requests on the pipe
219
+ * input.
220
+ */
221
+ io_uring_prep_cancel(sqe, 0, IORING_ASYNC_CANCEL_ALL);
222
+ sqe->cancel_flags |= IORING_ASYNC_CANCEL_FD;
223
+ sqe->fd = fd2[0];
224
+ sqe->user_data = 100;
225
+
226
+ ret = io_uring_submit(ring);
227
+ if (ret < 1) {
228
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
229
+ goto err;
230
+ }
231
+
232
+ for (i = 0; i < 5; i++) {
233
+ ret = io_uring_wait_cqe(ring, &cqe);
234
+ if (ret) {
235
+ fprintf(stderr, "wait=%d\n", ret);
236
+ goto err;
237
+ }
238
+ switch (cqe->user_data) {
239
+ case 100:
240
+ if (cqe->res != 4) {
241
+ fprintf(stderr, "canceled %d\n", cqe->res);
242
+ goto err;
243
+ }
244
+ break;
245
+ case 1:
246
+ if (cqe->res != -ECANCELED) {
247
+ fprintf(stderr, "poll res %d\n", cqe->res);
248
+ goto err;
249
+ }
250
+ break;
251
+ default:
252
+ fprintf(stderr, "invalid user_data %lu\n",
253
+ (unsigned long) cqe->user_data);
254
+ goto err;
255
+ }
256
+ io_uring_cqe_seen(ring, cqe);
257
+ }
258
+
259
+ close(fd2[0]);
260
+ close(fd2[1]);
261
+ return 0;
262
+ err:
263
+ close(fd2[0]);
264
+ close(fd2[1]);
265
+ return 1;
266
+ }
267
+
268
+ static int test3(struct io_uring *ring, int *fd)
269
+ {
270
+ struct io_uring_sqe *sqe;
271
+ struct io_uring_cqe *cqe;
272
+ int ret, i, fd2[2];
273
+
274
+ if (pipe(fd2) < 0) {
275
+ perror("pipe");
276
+ return 1;
277
+ }
278
+
279
+ for (i = 0; i < 8; i++) {
280
+ sqe = io_uring_get_sqe(ring);
281
+ if (!sqe) {
282
+ fprintf(stderr, "get sqe failed\n");
283
+ goto err;
284
+ }
285
+
286
+ if (!(i & 1)) {
287
+ io_uring_prep_poll_add(sqe, fd[0], POLLIN);
288
+ sqe->flags |= IOSQE_ASYNC;
289
+ } else
290
+ io_uring_prep_poll_add(sqe, fd2[0], POLLIN);
291
+ sqe->user_data = i & 1;
292
+ }
293
+
294
+ ret = io_uring_submit(ring);
295
+ if (ret < 8) {
296
+ fprintf(stderr, "child: sqe submit failed: %d\n", ret);
297
+ goto err;
298
+ }
299
+
300
+ usleep(10000);
301
+
302
+ sqe = io_uring_get_sqe(ring);
303
+ if (!sqe) {
304
+ fprintf(stderr, "get sqe failed\n");
305
+ goto err;
306
+ }
307
+
308
+ /*
309
+ * Mark CANCEL_ALL to cancel all matching the key, and use
310
+ * CANCEL_FD to cancel requests matching the specified fd.
311
+ * This should cancel all the pending poll requests on the pipe
312
+ * input.
313
+ */
314
+ io_uring_prep_cancel(sqe, 0, IORING_ASYNC_CANCEL_ALL);
315
+ sqe->cancel_flags |= IORING_ASYNC_CANCEL_ANY;
316
+ sqe->fd = 0;
317
+ sqe->user_data = 100;
318
+
319
+ ret = io_uring_submit(ring);
320
+ if (ret < 1) {
321
+ fprintf(stderr, "child: sqe submit failed: %d\n", ret);
322
+ goto err;
323
+ }
324
+
325
+ for (i = 0; i < 9; i++) {
326
+ ret = io_uring_wait_cqe(ring, &cqe);
327
+ if (ret) {
328
+ fprintf(stderr, "wait=%d\n", ret);
329
+ goto err;
330
+ }
331
+ switch (cqe->user_data) {
332
+ case 100:
333
+ if (cqe->res != 8) {
334
+ fprintf(stderr, "canceled %d\n", cqe->res);
335
+ goto err;
336
+ }
337
+ break;
338
+ case 0:
339
+ case 1:
340
+ if (cqe->res != -ECANCELED) {
341
+ fprintf(stderr, "poll res %d\n", cqe->res);
342
+ goto err;
343
+ }
344
+ break;
345
+ default:
346
+ fprintf(stderr, "invalid user_data %lu\n",
347
+ (unsigned long) cqe->user_data);
348
+ goto err;
349
+ }
350
+ io_uring_cqe_seen(ring, cqe);
351
+ }
352
+
353
+ close(fd2[0]);
354
+ close(fd2[1]);
355
+ return 0;
356
+ err:
357
+ close(fd2[0]);
358
+ close(fd2[1]);
359
+ return 1;
360
+ }
361
+
362
+ static int test4(struct io_uring *ring, int *fd)
363
+ {
364
+ struct io_uring_sqe *sqe;
365
+ struct io_uring_cqe *cqe;
366
+ char buffer[32];
367
+ int ret, i;
368
+
369
+ for (i = 0; i < 8; i++) {
370
+ sqe = io_uring_get_sqe(ring);
371
+ if (!sqe) {
372
+ fprintf(stderr, "get sqe failed\n");
373
+ goto err;
374
+ }
375
+
376
+ io_uring_prep_read(sqe, fd[0], &buffer, sizeof(buffer), 0);
377
+ sqe->flags |= IOSQE_ASYNC;
378
+ sqe->user_data = i + 1;
379
+ }
380
+
381
+ ret = io_uring_submit(ring);
382
+ if (ret < 8) {
383
+ fprintf(stderr, "child: sqe submit failed: %d\n", ret);
384
+ goto err;
385
+ }
386
+
387
+ usleep(10000);
388
+
389
+ sqe = io_uring_get_sqe(ring);
390
+ if (!sqe) {
391
+ fprintf(stderr, "get sqe failed\n");
392
+ goto err;
393
+ }
394
+
395
+ /*
396
+ * Mark CANCEL_ALL to cancel all matching the key, and use
397
+ * CANCEL_FD to cancel requests matching the specified fd.
398
+ * This should cancel all the pending poll requests on the pipe
399
+ * input.
400
+ */
401
+ io_uring_prep_cancel(sqe, 0, IORING_ASYNC_CANCEL_ALL);
402
+ sqe->cancel_flags |= IORING_ASYNC_CANCEL_ANY;
403
+ sqe->fd = 0;
404
+ sqe->user_data = 100;
405
+
406
+ ret = io_uring_submit(ring);
407
+ if (ret < 1) {
408
+ fprintf(stderr, "child: sqe submit failed: %d\n", ret);
409
+ goto err;
410
+ }
411
+
412
+ for (i = 0; i < 9; i++) {
413
+ ret = io_uring_wait_cqe(ring, &cqe);
414
+ if (ret) {
415
+ fprintf(stderr, "wait=%d\n", ret);
416
+ goto err;
417
+ }
418
+ switch (cqe->user_data) {
419
+ case 100:
420
+ if (cqe->res != 8) {
421
+ fprintf(stderr, "canceled %d\n", cqe->res);
422
+ goto err;
423
+ }
424
+ break;
425
+ case 1 ... 8:
426
+ if (cqe->res != -ECANCELED) {
427
+ fprintf(stderr, "poll res %d\n", cqe->res);
428
+ goto err;
429
+ }
430
+ break;
431
+ default:
432
+ fprintf(stderr, "invalid user_data %lu\n",
433
+ (unsigned long) cqe->user_data);
434
+ goto err;
435
+ }
436
+ io_uring_cqe_seen(ring, cqe);
437
+ }
438
+
439
+ return 0;
440
+ err:
441
+ return 1;
442
+ }
443
+
444
+ int main(int argc, char *argv[])
445
+ {
446
+ struct io_uring ring;
447
+ int ret, fd[2];
448
+
449
+ if (argc > 1)
450
+ return 0;
451
+
452
+ if (pipe(fd) < 0) {
453
+ perror("pipe");
454
+ return 1;
455
+ }
456
+
457
+ ret = io_uring_queue_init(8, &ring, 0);
458
+ if (ret) {
459
+ fprintf(stderr, "ring setup failed: %d\n", ret);
460
+ return 1;
461
+ }
462
+
463
+ ret = test1(&ring, fd, 0);
464
+ if (ret) {
465
+ fprintf(stderr, "test1 failed\n");
466
+ return ret;
467
+ }
468
+ if (no_cancel_flags)
469
+ return 0;
470
+
471
+ ret = test1(&ring, fd, 1);
472
+ if (ret) {
473
+ fprintf(stderr, "test1 fixed failed\n");
474
+ return ret;
475
+ }
476
+
477
+ ret = test2(&ring, fd);
478
+ if (ret) {
479
+ fprintf(stderr, "test2 failed\n");
480
+ return ret;
481
+ }
482
+
483
+ ret = test3(&ring, fd);
484
+ if (ret) {
485
+ fprintf(stderr, "test3 failed\n");
486
+ return ret;
487
+ }
488
+
489
+ ret = test4(&ring, fd);
490
+ if (ret) {
491
+ fprintf(stderr, "test4 failed\n");
492
+ return ret;
493
+ }
494
+
495
+ return 0;
496
+ }
@@ -0,0 +1,135 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test massive amounts of poll with cancel
4
+ *
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <inttypes.h>
12
+ #include <poll.h>
13
+ #include <sys/wait.h>
14
+ #include <signal.h>
15
+
16
+ #include "liburing.h"
17
+
18
+ #define POLL_COUNT 30000
19
+
20
+ static void *sqe_index[POLL_COUNT];
21
+
22
+ static int reap_events(struct io_uring *ring, unsigned nr_events, int nowait)
23
+ {
24
+ struct io_uring_cqe *cqe;
25
+ int i, ret = 0;
26
+
27
+ for (i = 0; i < nr_events; i++) {
28
+ if (!i && !nowait)
29
+ ret = io_uring_wait_cqe(ring, &cqe);
30
+ else
31
+ ret = io_uring_peek_cqe(ring, &cqe);
32
+ if (ret) {
33
+ if (ret != -EAGAIN)
34
+ fprintf(stderr, "cqe peek failed: %d\n", ret);
35
+ break;
36
+ }
37
+ io_uring_cqe_seen(ring, cqe);
38
+ }
39
+
40
+ return i ? i : ret;
41
+ }
42
+
43
+ static int del_polls(struct io_uring *ring, int fd, int nr)
44
+ {
45
+ int batch, i, ret;
46
+ struct io_uring_sqe *sqe;
47
+
48
+ while (nr) {
49
+ batch = 1024;
50
+ if (batch > nr)
51
+ batch = nr;
52
+
53
+ for (i = 0; i < batch; i++) {
54
+ void *data;
55
+
56
+ sqe = io_uring_get_sqe(ring);
57
+ data = sqe_index[lrand48() % nr];
58
+ io_uring_prep_poll_remove(sqe, (__u64)(uintptr_t)data);
59
+ }
60
+
61
+ ret = io_uring_submit(ring);
62
+ if (ret != batch) {
63
+ fprintf(stderr, "%s: failed submit, %d\n", __FUNCTION__, ret);
64
+ return 1;
65
+ }
66
+ nr -= batch;
67
+ ret = reap_events(ring, 2 * batch, 0);
68
+ }
69
+ return 0;
70
+ }
71
+
72
+ static int add_polls(struct io_uring *ring, int fd, int nr)
73
+ {
74
+ int batch, i, count, ret;
75
+ struct io_uring_sqe *sqe;
76
+
77
+ count = 0;
78
+ while (nr) {
79
+ batch = 1024;
80
+ if (batch > nr)
81
+ batch = nr;
82
+
83
+ for (i = 0; i < batch; i++) {
84
+ sqe = io_uring_get_sqe(ring);
85
+ io_uring_prep_poll_add(sqe, fd, POLLIN);
86
+ sqe_index[count++] = sqe;
87
+ sqe->user_data = (unsigned long) sqe;
88
+ }
89
+
90
+ ret = io_uring_submit(ring);
91
+ if (ret != batch) {
92
+ fprintf(stderr, "%s: failed submit, %d\n", __FUNCTION__, ret);
93
+ return 1;
94
+ }
95
+ nr -= batch;
96
+ reap_events(ring, batch, 1);
97
+ }
98
+ return 0;
99
+ }
100
+
101
+ int main(int argc, char *argv[])
102
+ {
103
+ struct io_uring ring;
104
+ struct io_uring_params p = { };
105
+ int pipe1[2];
106
+ int ret;
107
+
108
+ if (argc > 1)
109
+ return 0;
110
+
111
+ if (pipe(pipe1) != 0) {
112
+ perror("pipe");
113
+ return 1;
114
+ }
115
+
116
+ p.flags = IORING_SETUP_CQSIZE;
117
+ p.cq_entries = 16384;
118
+ ret = io_uring_queue_init_params(1024, &ring, &p);
119
+ if (ret) {
120
+ if (ret == -EINVAL) {
121
+ fprintf(stdout, "No CQSIZE, trying without\n");
122
+ ret = io_uring_queue_init(1024, &ring, 0);
123
+ if (ret) {
124
+ fprintf(stderr, "ring setup failed: %d\n", ret);
125
+ return 1;
126
+ }
127
+ }
128
+ }
129
+
130
+ add_polls(&ring, pipe1[0], 30000);
131
+ del_polls(&ring, pipe1[0], 30000);
132
+
133
+ io_uring_queue_exit(&ring);
134
+ return 0;
135
+ }