polyphony 0.98 → 0.99.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -1
  3. data/.rubocop.yml +3 -3
  4. data/.yardopts +30 -0
  5. data/CHANGELOG.md +11 -0
  6. data/LICENSE +1 -1
  7. data/README.md +63 -29
  8. data/Rakefile +1 -5
  9. data/TODO.md +0 -4
  10. data/docs/{main-concepts/concurrency.md → concurrency.md} +2 -9
  11. data/docs/{main-concepts/design-principles.md → design-principles.md} +3 -9
  12. data/docs/{main-concepts/exception-handling.md → exception-handling.md} +2 -9
  13. data/docs/{main-concepts/extending.md → extending.md} +2 -9
  14. data/docs/faq.md +3 -16
  15. data/docs/{main-concepts/fiber-scheduling.md → fiber-scheduling.md} +1 -9
  16. data/docs/link_rewriter.rb +16 -0
  17. data/docs/{getting-started/overview.md → overview.md} +1 -30
  18. data/docs/{getting-started/tutorial.md → tutorial.md} +3 -28
  19. data/docs/{_posts/2020-07-26-polyphony-0.44.md → whats-new.md} +3 -1
  20. data/examples/adapters/redis_client.rb +3 -2
  21. data/examples/io/echo_server.rb +1 -1
  22. data/examples/io/echo_server_plain_ruby.rb +26 -0
  23. data/examples/io/https_server_sni_2.rb +14 -8
  24. data/ext/polyphony/backend_io_uring.c +154 -9
  25. data/ext/polyphony/backend_io_uring_context.c +21 -12
  26. data/ext/polyphony/backend_io_uring_context.h +12 -7
  27. data/ext/polyphony/backend_libev.c +1 -1
  28. data/ext/polyphony/extconf.rb +25 -8
  29. data/ext/polyphony/fiber.c +79 -2
  30. data/ext/polyphony/io_extensions.c +53 -0
  31. data/ext/polyphony/libev.h +0 -2
  32. data/ext/polyphony/pipe.c +42 -2
  33. data/ext/polyphony/polyphony.c +345 -31
  34. data/ext/polyphony/polyphony.h +9 -2
  35. data/ext/polyphony/queue.c +181 -0
  36. data/ext/polyphony/ring_buffer.c +0 -1
  37. data/ext/polyphony/runqueue.c +8 -1
  38. data/ext/polyphony/runqueue_ring_buffer.c +13 -0
  39. data/ext/polyphony/runqueue_ring_buffer.h +2 -1
  40. data/ext/polyphony/socket_extensions.c +6 -0
  41. data/ext/polyphony/thread.c +34 -2
  42. data/lib/polyphony/adapters/process.rb +11 -1
  43. data/lib/polyphony/adapters/sequel.rb +1 -1
  44. data/lib/polyphony/core/channel.rb +2 -0
  45. data/lib/polyphony/core/debug.rb +1 -1
  46. data/lib/polyphony/core/global_api.rb +25 -24
  47. data/lib/polyphony/core/resource_pool.rb +7 -6
  48. data/lib/polyphony/core/sync.rb +55 -2
  49. data/lib/polyphony/core/thread_pool.rb +3 -3
  50. data/lib/polyphony/core/timer.rb +8 -8
  51. data/lib/polyphony/extensions/exception.rb +2 -0
  52. data/lib/polyphony/extensions/fiber.rb +15 -13
  53. data/lib/polyphony/extensions/io.rb +161 -16
  54. data/lib/polyphony/extensions/kernel.rb +20 -2
  55. data/lib/polyphony/extensions/openssl.rb +101 -12
  56. data/lib/polyphony/extensions/pipe.rb +103 -7
  57. data/lib/polyphony/extensions/process.rb +13 -1
  58. data/lib/polyphony/extensions/socket.rb +93 -27
  59. data/lib/polyphony/extensions/thread.rb +9 -1
  60. data/lib/polyphony/extensions/timeout.rb +1 -1
  61. data/lib/polyphony/version.rb +2 -1
  62. data/lib/polyphony.rb +27 -7
  63. data/polyphony.gemspec +1 -8
  64. data/test/stress.rb +1 -1
  65. data/test/test_global_api.rb +45 -7
  66. data/test/test_io.rb +6 -7
  67. data/test/test_socket.rb +157 -0
  68. data/test/test_sync.rb +42 -1
  69. data/test/test_timer.rb +5 -5
  70. data/vendor/liburing/.github/workflows/build.yml +7 -16
  71. data/vendor/liburing/.gitignore +5 -0
  72. data/vendor/liburing/CHANGELOG +23 -1
  73. data/vendor/liburing/Makefile +4 -3
  74. data/vendor/liburing/Makefile.common +1 -0
  75. data/vendor/liburing/README +48 -0
  76. data/vendor/liburing/configure +76 -6
  77. data/vendor/liburing/debian/changelog +11 -0
  78. data/vendor/liburing/debian/control +7 -16
  79. data/vendor/liburing/debian/liburing-dev.manpages +3 -6
  80. data/vendor/liburing/debian/liburing2.install +1 -0
  81. data/vendor/liburing/debian/liburing2.symbols +56 -0
  82. data/vendor/liburing/debian/rules +15 -68
  83. data/vendor/liburing/examples/Makefile +4 -0
  84. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  85. data/vendor/liburing/examples/io_uring-udp.c +1 -1
  86. data/vendor/liburing/examples/send-zerocopy.c +315 -56
  87. data/vendor/liburing/examples/ucontext-cp.c +2 -17
  88. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  89. data/vendor/liburing/liburing.pc.in +1 -1
  90. data/vendor/liburing/liburing.spec +1 -1
  91. data/vendor/liburing/make-debs.sh +3 -3
  92. data/vendor/liburing/man/IO_URING_CHECK_VERSION.3 +1 -0
  93. data/vendor/liburing/man/IO_URING_VERSION_MAJOR.3 +1 -0
  94. data/vendor/liburing/man/IO_URING_VERSION_MINOR.3 +1 -0
  95. data/vendor/liburing/man/io_uring_buf_ring_add.3 +6 -6
  96. data/vendor/liburing/man/io_uring_check_version.3 +72 -0
  97. data/vendor/liburing/man/io_uring_close_ring_fd.3 +43 -0
  98. data/vendor/liburing/man/io_uring_major_version.3 +1 -0
  99. data/vendor/liburing/man/io_uring_minor_version.3 +1 -0
  100. data/vendor/liburing/man/io_uring_prep_accept.3 +1 -1
  101. data/vendor/liburing/man/io_uring_prep_fgetxattr.3 +1 -0
  102. data/vendor/liburing/man/io_uring_prep_fsetxattr.3 +1 -0
  103. data/vendor/liburing/man/io_uring_prep_getxattr.3 +61 -0
  104. data/vendor/liburing/man/io_uring_prep_link_timeout.3 +94 -0
  105. data/vendor/liburing/man/io_uring_prep_msg_ring.3 +22 -2
  106. data/vendor/liburing/man/io_uring_prep_msg_ring_cqe_flags.3 +1 -0
  107. data/vendor/liburing/man/io_uring_prep_poll_add.3 +1 -1
  108. data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +18 -9
  109. data/vendor/liburing/man/io_uring_prep_readv.3 +3 -3
  110. data/vendor/liburing/man/io_uring_prep_readv2.3 +3 -3
  111. data/vendor/liburing/man/io_uring_prep_recv.3 +5 -5
  112. data/vendor/liburing/man/io_uring_prep_recvmsg.3 +4 -4
  113. data/vendor/liburing/man/io_uring_prep_send.3 +9 -0
  114. data/vendor/liburing/man/io_uring_prep_send_set_addr.3 +38 -0
  115. data/vendor/liburing/man/io_uring_prep_send_zc.3 +39 -7
  116. data/vendor/liburing/man/io_uring_prep_send_zc_fixed.3 +1 -0
  117. data/vendor/liburing/man/io_uring_prep_sendmsg.3 +20 -0
  118. data/vendor/liburing/man/io_uring_prep_sendmsg_zc.3 +1 -0
  119. data/vendor/liburing/man/io_uring_prep_setxattr.3 +64 -0
  120. data/vendor/liburing/man/io_uring_prep_splice.3 +40 -0
  121. data/vendor/liburing/man/io_uring_prep_writev.3 +2 -2
  122. data/vendor/liburing/man/io_uring_prep_writev2.3 +2 -2
  123. data/vendor/liburing/man/io_uring_recvmsg_out.3 +13 -9
  124. data/vendor/liburing/man/io_uring_register.2 +15 -9
  125. data/vendor/liburing/man/io_uring_register_buf_ring.3 +4 -4
  126. data/vendor/liburing/man/io_uring_register_buffers.3 +49 -6
  127. data/vendor/liburing/man/io_uring_register_buffers_sparse.3 +1 -0
  128. data/vendor/liburing/man/io_uring_register_buffers_tags.3 +1 -0
  129. data/vendor/liburing/man/io_uring_register_buffers_update_tag.3 +1 -0
  130. data/vendor/liburing/man/io_uring_register_files.3 +60 -5
  131. data/vendor/liburing/man/io_uring_register_files_tags.3 +1 -0
  132. data/vendor/liburing/man/io_uring_register_files_update.3 +1 -0
  133. data/vendor/liburing/man/io_uring_register_files_update_tag.3 +1 -0
  134. data/vendor/liburing/man/io_uring_setup.2 +31 -2
  135. data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +1 -1
  136. data/vendor/liburing/src/Makefile +25 -3
  137. data/vendor/liburing/src/ffi.c +15 -0
  138. data/vendor/liburing/src/include/liburing/io_uring.h +30 -7
  139. data/vendor/liburing/src/include/liburing.h +190 -148
  140. data/vendor/liburing/src/int_flags.h +1 -0
  141. data/vendor/liburing/src/lib.h +5 -16
  142. data/vendor/liburing/src/liburing-ffi.map +172 -0
  143. data/vendor/liburing/src/liburing.map +11 -0
  144. data/vendor/liburing/src/nolibc.c +9 -2
  145. data/vendor/liburing/src/queue.c +2 -2
  146. data/vendor/liburing/src/register.c +66 -96
  147. data/vendor/liburing/src/setup.c +5 -4
  148. data/vendor/liburing/src/version.c +21 -0
  149. data/vendor/liburing/test/232c93d07b74.c +3 -3
  150. data/vendor/liburing/test/35fa71a030ca.c +3 -3
  151. data/vendor/liburing/test/500f9fbadef8.c +2 -0
  152. data/vendor/liburing/test/917257daa0fe.c +1 -1
  153. data/vendor/liburing/test/Makefile +27 -7
  154. data/vendor/liburing/test/a0908ae19763.c +2 -2
  155. data/vendor/liburing/test/a4c0b3decb33.c +2 -2
  156. data/vendor/liburing/test/accept-link.c +4 -4
  157. data/vendor/liburing/test/accept-reuse.c +5 -7
  158. data/vendor/liburing/test/accept.c +34 -31
  159. data/vendor/liburing/test/b19062a56726.c +1 -1
  160. data/vendor/liburing/test/buf-ring.c +58 -4
  161. data/vendor/liburing/test/ce593a6c480a.c +2 -2
  162. data/vendor/liburing/test/close-opath.c +2 -1
  163. data/vendor/liburing/test/connect.c +8 -0
  164. data/vendor/liburing/test/cq-overflow.c +14 -8
  165. data/vendor/liburing/test/d4ae271dfaae.c +1 -1
  166. data/vendor/liburing/test/defer-taskrun.c +64 -9
  167. data/vendor/liburing/test/defer.c +1 -1
  168. data/vendor/liburing/test/double-poll-crash.c +3 -3
  169. data/vendor/liburing/test/eeed8b54e0df.c +8 -3
  170. data/vendor/liburing/test/eploop.c +74 -0
  171. data/vendor/liburing/test/eventfd-ring.c +1 -1
  172. data/vendor/liburing/test/eventfd.c +1 -1
  173. data/vendor/liburing/test/evloop.c +73 -0
  174. data/vendor/liburing/test/exit-no-cleanup.c +1 -1
  175. data/vendor/liburing/test/fadvise.c +1 -1
  176. data/vendor/liburing/test/fc2a85cb02ef.c +3 -3
  177. data/vendor/liburing/test/fd-pass.c +35 -16
  178. data/vendor/liburing/test/file-register.c +61 -0
  179. data/vendor/liburing/test/file-verify.c +2 -2
  180. data/vendor/liburing/test/files-exit-hang-timeout.c +2 -2
  181. data/vendor/liburing/test/fixed-link.c +1 -1
  182. data/vendor/liburing/test/fsnotify.c +118 -0
  183. data/vendor/liburing/test/hardlink.c +1 -1
  184. data/vendor/liburing/test/helpers.c +54 -2
  185. data/vendor/liburing/test/helpers.h +4 -0
  186. data/vendor/liburing/test/io-cancel.c +3 -1
  187. data/vendor/liburing/test/io_uring_passthrough.c +39 -8
  188. data/vendor/liburing/test/io_uring_setup.c +3 -80
  189. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  190. data/vendor/liburing/test/iopoll.c +90 -4
  191. data/vendor/liburing/test/lfs-openat-write.c +7 -9
  192. data/vendor/liburing/test/lfs-openat.c +6 -8
  193. data/vendor/liburing/test/link_drain.c +31 -5
  194. data/vendor/liburing/test/madvise.c +1 -1
  195. data/vendor/liburing/test/msg-ring-flags.c +192 -0
  196. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  197. data/vendor/liburing/test/msg-ring.c +173 -13
  198. data/vendor/liburing/test/multicqes_drain.c +22 -19
  199. data/vendor/liburing/test/nvme.h +4 -3
  200. data/vendor/liburing/test/pipe-bug.c +95 -0
  201. data/vendor/liburing/test/poll-link.c +3 -3
  202. data/vendor/liburing/test/poll-many.c +41 -19
  203. data/vendor/liburing/test/poll-mshot-overflow.c +105 -2
  204. data/vendor/liburing/test/poll-race-mshot.c +292 -0
  205. data/vendor/liburing/test/poll-race.c +105 -0
  206. data/vendor/liburing/test/poll.c +244 -26
  207. data/vendor/liburing/test/pollfree.c +5 -5
  208. data/vendor/liburing/test/read-before-exit.c +20 -3
  209. data/vendor/liburing/test/read-write.c +2 -0
  210. data/vendor/liburing/test/recv-multishot.c +96 -3
  211. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  212. data/vendor/liburing/test/rename.c +1 -1
  213. data/vendor/liburing/test/ring-leak.c +0 -1
  214. data/vendor/liburing/test/ring-leak2.c +1 -1
  215. data/vendor/liburing/test/ringbuf-read.c +10 -6
  216. data/vendor/liburing/test/send-zerocopy.c +273 -103
  217. data/vendor/liburing/test/send_recv.c +7 -4
  218. data/vendor/liburing/test/sendmsg_fs_cve.c +2 -2
  219. data/vendor/liburing/test/single-issuer.c +7 -9
  220. data/vendor/liburing/test/skip-cqe.c +3 -4
  221. data/vendor/liburing/test/socket.c +0 -1
  222. data/vendor/liburing/test/sq-poll-dup.c +10 -3
  223. data/vendor/liburing/test/sq-poll-kthread.c +1 -1
  224. data/vendor/liburing/test/sq-poll-share.c +3 -2
  225. data/vendor/liburing/test/sqpoll-cancel-hang.c +17 -6
  226. data/vendor/liburing/test/sqpoll-disable-exit.c +4 -4
  227. data/vendor/liburing/test/symlink.c +2 -1
  228. data/vendor/liburing/test/test.h +2 -1
  229. data/vendor/liburing/test/timeout-new.c +11 -7
  230. data/vendor/liburing/test/timeout.c +1 -2
  231. data/vendor/liburing/test/unlink.c +1 -1
  232. data/vendor/liburing/test/version.c +25 -0
  233. data/vendor/liburing/test/wakeup-hang.c +1 -1
  234. data/vendor/liburing/test/xattr.c +8 -4
  235. metadata +57 -44
  236. data/docs/_config.yml +0 -64
  237. data/docs/_includes/head.html +0 -40
  238. data/docs/_includes/title.html +0 -1
  239. data/docs/_sass/custom/custom.scss +0 -10
  240. data/docs/_sass/overrides.scss +0 -0
  241. data/docs/api-reference/exception.md +0 -31
  242. data/docs/api-reference/fiber.md +0 -425
  243. data/docs/api-reference/index.md +0 -9
  244. data/docs/api-reference/io.md +0 -36
  245. data/docs/api-reference/object.md +0 -99
  246. data/docs/api-reference/polyphony-baseexception.md +0 -33
  247. data/docs/api-reference/polyphony-cancel.md +0 -26
  248. data/docs/api-reference/polyphony-moveon.md +0 -24
  249. data/docs/api-reference/polyphony-net.md +0 -20
  250. data/docs/api-reference/polyphony-process.md +0 -28
  251. data/docs/api-reference/polyphony-resourcepool.md +0 -59
  252. data/docs/api-reference/polyphony-restart.md +0 -18
  253. data/docs/api-reference/polyphony-terminate.md +0 -18
  254. data/docs/api-reference/polyphony-threadpool.md +0 -67
  255. data/docs/api-reference/polyphony-throttler.md +0 -77
  256. data/docs/api-reference/polyphony.md +0 -36
  257. data/docs/api-reference/thread.md +0 -88
  258. data/docs/favicon.ico +0 -0
  259. data/docs/getting-started/index.md +0 -10
  260. data/docs/getting-started/installing.md +0 -34
  261. data/vendor/liburing/debian/compat +0 -1
  262. data/vendor/liburing/debian/liburing1-udeb.install +0 -1
  263. data/vendor/liburing/debian/liburing1.install +0 -1
  264. data/vendor/liburing/debian/liburing1.symbols +0 -32
  265. /data/{docs/assets/img → assets}/echo-fibers.svg +0 -0
  266. /data/{docs → assets}/polyphony-logo.png +0 -0
  267. /data/{docs/assets/img → assets}/sleeping-fiber.svg +0 -0
@@ -87,6 +87,8 @@ static int __test_io(const char *file, struct io_uring *ring, int write, int sqt
87
87
  }
88
88
  fd = open(file, open_flags);
89
89
  if (fd < 0) {
90
+ if (errno == EINVAL)
91
+ return 0;
90
92
  perror("file open");
91
93
  goto err;
92
94
  }
@@ -201,7 +203,80 @@ err:
201
203
  return 1;
202
204
  }
203
205
 
204
- extern unsigned __io_uring_flush_sq(struct io_uring *ring);
206
+ static void sig_alrm(int sig)
207
+ {
208
+ fprintf(stderr, "Ran out of time for peek test!\n");
209
+ exit(T_EXIT_FAIL);
210
+ }
211
+
212
+ /*
213
+ * if we are polling, io_uring_cqe_peek() always needs to enter the kernel
214
+ */
215
+ static int test_io_uring_cqe_peek(const char *file)
216
+ {
217
+ struct io_uring_cqe *cqe;
218
+ struct io_uring ring;
219
+ struct sigaction act;
220
+ int fd, i, ret = T_EXIT_FAIL;
221
+
222
+ if (no_iopoll)
223
+ return 0;
224
+
225
+ ret = io_uring_queue_init(64, &ring, IORING_SETUP_IOPOLL);
226
+ if (ret) {
227
+ fprintf(stderr, "ring create failed: %d\n", ret);
228
+ return 1;
229
+ }
230
+
231
+ fd = open(file, O_RDONLY | O_DIRECT);
232
+ if (fd < 0) {
233
+ if (errno == EINVAL) {
234
+ io_uring_queue_exit(&ring);
235
+ return T_EXIT_SKIP;
236
+ }
237
+ perror("file open");
238
+ goto err;
239
+ }
240
+
241
+ for (i = 0; i < BUFFERS; i++) {
242
+ struct io_uring_sqe *sqe;
243
+ off_t offset = BS * (rand() % BUFFERS);
244
+
245
+ sqe = io_uring_get_sqe(&ring);
246
+ io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
247
+ sqe->user_data = 1;
248
+ }
249
+
250
+ /*
251
+ * Set alarm for 5 seconds, we should be done way before that
252
+ */
253
+ memset(&act, 0, sizeof(act));
254
+ act.sa_handler = sig_alrm;
255
+ sigaction(SIGALRM, &act, NULL);
256
+ alarm(5);
257
+
258
+ ret = io_uring_submit(&ring);
259
+ if (ret != BUFFERS) {
260
+ fprintf(stderr, "submit=%d\n", ret);
261
+ goto err;
262
+ }
263
+
264
+ ret = T_EXIT_PASS;
265
+ i = 0;
266
+ do {
267
+ ret = io_uring_peek_cqe(&ring, &cqe);
268
+ if (ret)
269
+ continue;
270
+ io_uring_cqe_seen(&ring, cqe);
271
+ i++;
272
+ } while (i < BUFFERS);
273
+
274
+ err:
275
+ if (fd != -1)
276
+ close(fd);
277
+ io_uring_queue_exit(&ring);
278
+ return ret;
279
+ }
205
280
 
206
281
  /*
207
282
  * if we are polling io_uring_submit needs to always enter the
@@ -227,6 +302,8 @@ static int test_io_uring_submit_enters(const char *file)
227
302
  open_flags = O_WRONLY | O_DIRECT;
228
303
  fd = open(file, open_flags);
229
304
  if (fd < 0) {
305
+ if (errno == EINVAL)
306
+ return T_EXIT_SKIP;
230
307
  perror("file open");
231
308
  goto err;
232
309
  }
@@ -364,9 +441,18 @@ int main(int argc, char *argv[])
364
441
  }
365
442
 
366
443
  ret = test_io_uring_submit_enters(fname);
367
- if (ret) {
368
- fprintf(stderr, "test_io_uring_submit_enters failed\n");
369
- goto err;
444
+ if (ret == T_EXIT_FAIL) {
445
+ fprintf(stderr, "test_io_uring_submit_enters failed\n");
446
+ goto err;
447
+ }
448
+
449
+ /*
450
+ * Keep this last, it exits on failure
451
+ */
452
+ ret = test_io_uring_cqe_peek(fname);
453
+ if (ret == T_EXIT_FAIL) {
454
+ fprintf(stderr, "test_io_uring_cqe_peek failed\n");
455
+ goto err;
370
456
  }
371
457
 
372
458
  if (fname != argv[1])
@@ -1,9 +1,5 @@
1
1
  /* SPDX-License-Identifier: MIT */
2
2
 
3
- #define _LARGEFILE_SOURCE
4
- #define _FILE_OFFSET_BITS 64
5
-
6
- #include <liburing.h>
7
3
  #include <string.h>
8
4
  #include <stdio.h>
9
5
  #include <stdlib.h>
@@ -14,16 +10,18 @@
14
10
  #include <sys/resource.h>
15
11
  #include <unistd.h>
16
12
 
13
+ #include "liburing.h"
17
14
  #include "helpers.h"
18
15
 
19
16
  static const int RSIZE = 2;
20
- static const int OPEN_FLAGS = O_RDWR | O_CREAT;
17
+ static const int OPEN_FLAGS = O_RDWR | O_CREAT | O_LARGEFILE;
21
18
  static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR;
22
19
 
23
- #define DIE(...) do {\
24
- fprintf(stderr, __VA_ARGS__);\
25
- abort();\
26
- } while(0);
20
+ #define DIE(...) \
21
+ do { \
22
+ fprintf(stderr, __VA_ARGS__); \
23
+ abort(); \
24
+ } while(0)
27
25
 
28
26
  static int do_write(struct io_uring *ring, int fd, off_t offset)
29
27
  {
@@ -1,8 +1,5 @@
1
1
  /* SPDX-License-Identifier: MIT */
2
2
 
3
- #define _LARGEFILE_SOURCE
4
- #define _FILE_OFFSET_BITS 64
5
-
6
3
  #include <string.h>
7
4
  #include <stdio.h>
8
5
  #include <stdlib.h>
@@ -15,13 +12,14 @@
15
12
 
16
13
  #include "liburing.h"
17
14
 
18
- #define DIE(...) do {\
19
- fprintf(stderr, __VA_ARGS__);\
20
- abort();\
21
- } while(0);
15
+ #define DIE(...) \
16
+ do { \
17
+ fprintf(stderr, __VA_ARGS__); \
18
+ abort(); \
19
+ } while(0)
22
20
 
23
21
  static const int RSIZE = 2;
24
- static const int OPEN_FLAGS = O_RDWR | O_CREAT;
22
+ static const int OPEN_FLAGS = O_RDWR | O_CREAT | O_LARGEFILE;
25
23
  static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR;
26
24
 
27
25
  static int open_io_uring(struct io_uring *ring, int dfd, const char *fn)
@@ -96,7 +96,7 @@ err:
96
96
  return 1;
97
97
  }
98
98
 
99
- int test_link_drain_multi(struct io_uring *ring)
99
+ static int test_link_drain_multi(struct io_uring *ring)
100
100
  {
101
101
  struct io_uring_cqe *cqe;
102
102
  struct io_uring_sqe *sqe[9];
@@ -198,15 +198,17 @@ err:
198
198
 
199
199
  }
200
200
 
201
- int main(int argc, char *argv[])
201
+ static int test_drain(bool defer)
202
202
  {
203
203
  struct io_uring ring;
204
204
  int i, ret;
205
+ unsigned int flags = 0;
205
206
 
206
- if (argc > 1)
207
- return 0;
207
+ if (defer)
208
+ flags = IORING_SETUP_SINGLE_ISSUER |
209
+ IORING_SETUP_DEFER_TASKRUN;
208
210
 
209
- ret = io_uring_queue_init(100, &ring, 0);
211
+ ret = io_uring_queue_init(100, &ring, flags);
210
212
  if (ret) {
211
213
  printf("ring setup failed\n");
212
214
  return 1;
@@ -227,3 +229,27 @@ int main(int argc, char *argv[])
227
229
 
228
230
  return ret;
229
231
  }
232
+
233
+ int main(int argc, char *argv[])
234
+ {
235
+ int ret;
236
+
237
+ if (argc > 1)
238
+ return T_EXIT_SKIP;
239
+
240
+ ret = test_drain(false);
241
+ if (ret) {
242
+ fprintf(stderr, "test_drain(false) failed\n");
243
+ return T_EXIT_FAIL;
244
+ }
245
+
246
+ if (t_probe_defer_taskrun()) {
247
+ ret = test_drain(true);
248
+ if (ret) {
249
+ fprintf(stderr, "test_drain(true) failed\n");
250
+ return T_EXIT_FAIL;
251
+ }
252
+ }
253
+
254
+ return T_EXIT_PASS;
255
+ }
@@ -182,7 +182,7 @@ int main(int argc, char *argv[])
182
182
  }
183
183
 
184
184
  /* too hard to reliably test, just ignore */
185
- if (0 && bad > good)
185
+ if ((0) && bad > good)
186
186
  fprintf(stderr, "Suspicious timings (%u > %u)\n", bad, good);
187
187
  if (fname != argv[1])
188
188
  unlink(fname);
@@ -0,0 +1,192 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test ring messaging with flags command
4
+ *
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <fcntl.h>
12
+ #include <pthread.h>
13
+
14
+ #include "liburing.h"
15
+ #include "helpers.h"
16
+
17
+ #define CUSTOM_FLAG 0x42
18
+ #define USER_DATA 0x5aa5
19
+ #define LEN 0x20
20
+ #define ID 0x1
21
+
22
+ struct data {
23
+ pthread_barrier_t barrier;
24
+ int fd;
25
+ };
26
+
27
+ static int recv_msg(struct io_uring *ring)
28
+ {
29
+ struct io_uring_cqe *cqe;
30
+ int ret;
31
+
32
+ ret = io_uring_wait_cqe(ring, &cqe);
33
+ if (ret) {
34
+ fprintf(stderr, "wait cqe %d\n", ret);
35
+ return T_EXIT_FAIL;
36
+ }
37
+ if (cqe->user_data != USER_DATA) {
38
+ fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
39
+ return T_EXIT_FAIL;
40
+ }
41
+ if (cqe->res != LEN) {
42
+ fprintf(stderr, "len %x\n", cqe->res);
43
+ return T_EXIT_FAIL;
44
+ }
45
+ if (cqe->flags != CUSTOM_FLAG) {
46
+ fprintf(stderr, "flags %x\n", cqe->flags);
47
+ return T_EXIT_FAIL;
48
+ }
49
+
50
+ return T_EXIT_PASS;
51
+ }
52
+
53
+ static int send_msg(struct io_uring *ring, int target_fd)
54
+ {
55
+ struct io_uring_cqe *cqe;
56
+ struct io_uring_sqe *sqe;
57
+ int ret;
58
+
59
+ sqe = io_uring_get_sqe(ring);
60
+ if (!sqe) {
61
+ fprintf(stderr, "get sqe failed\n");
62
+ return T_EXIT_FAIL;
63
+ }
64
+
65
+ io_uring_prep_msg_ring_cqe_flags(sqe, target_fd, LEN, USER_DATA,
66
+ 0, CUSTOM_FLAG);
67
+ sqe->user_data = ID;
68
+
69
+ ret = io_uring_submit(ring);
70
+ if (ret <= 0) {
71
+ if (ret == -EINVAL)
72
+ return T_EXIT_SKIP;
73
+
74
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
75
+ return T_EXIT_FAIL;
76
+ }
77
+
78
+ ret = io_uring_wait_cqe(ring, &cqe);
79
+ if (ret < 0) {
80
+ fprintf(stderr, "wait completion %d\n", ret);
81
+ return T_EXIT_FAIL;
82
+ }
83
+ if (cqe->res != 0) {
84
+ if (cqe->res == -EINVAL)
85
+ return T_EXIT_SKIP;
86
+ fprintf(stderr, "cqe res %d\n", cqe->res);
87
+ return T_EXIT_FAIL;
88
+ }
89
+ if (cqe->user_data != ID) {
90
+ fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
91
+ return T_EXIT_FAIL;
92
+ }
93
+
94
+ io_uring_cqe_seen(ring, cqe);
95
+ return T_EXIT_PASS;
96
+ }
97
+
98
+ static void *thread_fn(void *data)
99
+ {
100
+ struct data *d = data;
101
+ struct io_uring ring;
102
+ int ret;
103
+
104
+ ret = io_uring_queue_init(2, &ring, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER);
105
+ if (ret) {
106
+ fprintf(stderr, "ring init failed %d\n", ret);
107
+ pthread_barrier_wait(&d->barrier);
108
+ return NULL;
109
+ }
110
+
111
+ d->fd = ring.ring_fd;
112
+ pthread_barrier_wait(&d->barrier);
113
+
114
+ if (recv_msg(&ring))
115
+ return (void *) 1;
116
+
117
+ return NULL;
118
+ }
119
+
120
+ int main(int argc, char *argv[])
121
+ {
122
+ struct io_uring ring, ring2;
123
+ pthread_t thread;
124
+ struct data d;
125
+ void *ret2;
126
+ int ret, i;
127
+
128
+ if (argc > 1)
129
+ return T_EXIT_SKIP;
130
+
131
+ ret = io_uring_queue_init(2, &ring, 0);
132
+ if (ret) {
133
+ fprintf(stderr, "io_uring_queue_init failed for ring1: %d\n", ret);
134
+ return T_EXIT_FAIL;
135
+ }
136
+
137
+ ret = io_uring_queue_init(2, &ring2, 0);
138
+ if (ret) {
139
+ fprintf(stderr, "io_uring_queue_init failed for ring2: %d\n", ret);
140
+ return T_EXIT_FAIL;
141
+ }
142
+
143
+ ret = send_msg(&ring, ring2.ring_fd);
144
+ if (ret) {
145
+ if (ret != T_EXIT_SKIP)
146
+ fprintf(stderr, "send_msg failed: %d\n", ret);
147
+ return ret;
148
+ }
149
+
150
+ ret = recv_msg(&ring2);
151
+ if (ret) {
152
+ fprintf(stderr, "recv_msg failed: %d\n", ret);
153
+ return ret;
154
+ }
155
+
156
+ for (i = 0; i < 8; i++) {
157
+ ret = send_msg(&ring, ring2.ring_fd);
158
+ if (ret) {
159
+ if (ret != T_EXIT_SKIP)
160
+ fprintf(stderr, "send_msg failed: %d\n", ret);
161
+ return ret;
162
+ }
163
+ }
164
+
165
+ for (i = 0; i < 8; i++) {
166
+ ret = recv_msg(&ring2);
167
+ if (ret) {
168
+ fprintf(stderr, "recv_msg failed: %d\n", ret);
169
+ return ret;
170
+ }
171
+ }
172
+
173
+ pthread_barrier_init(&d.barrier, NULL, 2);
174
+ d.fd = -1;
175
+ pthread_create(&thread, NULL, thread_fn, &d);
176
+ pthread_barrier_wait(&d.barrier);
177
+ if (d.fd == -1)
178
+ return T_EXIT_FAIL;
179
+
180
+ ret = send_msg(&ring, d.fd);
181
+ if (ret) {
182
+ fprintf(stderr, "send msg failed: %d\n", ret);
183
+ return ret;
184
+ }
185
+ pthread_join(thread, &ret2);
186
+ if (ret2) {
187
+ fprintf(stderr, "Remote test failed\n");
188
+ return T_EXIT_FAIL;
189
+ }
190
+
191
+ return T_EXIT_PASS;
192
+ }
@@ -0,0 +1,159 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test ring messaging command
4
+ *
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <fcntl.h>
12
+
13
+ #include "liburing.h"
14
+ #include "helpers.h"
15
+
16
+ static int no_msg;
17
+
18
+ static int test(struct io_uring *ring, unsigned dst_flags)
19
+ {
20
+ struct io_uring_params p = { };
21
+ struct io_uring_cqe *cqe;
22
+ struct io_uring_sqe *sqe;
23
+ struct io_uring dst;
24
+ int ret, i, err_ret = T_EXIT_FAIL;
25
+
26
+ p.flags = dst_flags | IORING_SETUP_CQSIZE;
27
+ p.cq_entries = 4;
28
+ ret = io_uring_queue_init_params(4, &dst, &p);
29
+ if (ret) {
30
+ fprintf(stderr, "Destination ring create failed %d\n", ret);
31
+ return T_EXIT_FAIL;
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
+ goto err;
39
+ }
40
+
41
+ io_uring_prep_msg_ring(sqe, dst.ring_fd, 0x10, 0x1234, 0);
42
+ sqe->user_data = i + 1;
43
+ }
44
+
45
+ ret = io_uring_submit(ring);
46
+ if (ret != 8) {
47
+ /*
48
+ * Likely an old kernel that doesn't support the opcode,
49
+ * just skip the test.
50
+ */
51
+ if (ret == 1) {
52
+ err_ret = T_EXIT_SKIP;
53
+ no_msg = 1;
54
+ goto err;
55
+ }
56
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
57
+ goto err;
58
+ }
59
+
60
+ for (i = 0; i < 8; i++) {
61
+ ret = io_uring_wait_cqe(ring, &cqe);
62
+ if (ret < 0) {
63
+ fprintf(stderr, "wait completion %d\n", ret);
64
+ goto err;
65
+ }
66
+ switch (cqe->user_data) {
67
+ case 1 ... 8:
68
+ if (cqe->res == -EINVAL || cqe->res == -EOPNOTSUPP) {
69
+ no_msg = 1;
70
+ goto out;
71
+ }
72
+ if (cqe->res != 0) {
73
+ fprintf(stderr, "cqe res %d\n", cqe->res);
74
+ goto err;
75
+ }
76
+ break;
77
+ case 0x1234:
78
+ if (cqe->res != 0x10) {
79
+ fprintf(stderr, "invalid len %x\n", cqe->res);
80
+ goto err;
81
+ }
82
+ break;
83
+ default:
84
+ fprintf(stderr, "Invalid user_data\n");
85
+ goto err;
86
+ }
87
+ io_uring_cqe_seen(ring, cqe);
88
+ }
89
+
90
+ for (i = 0; i < 8; i++) {
91
+ ret = io_uring_wait_cqe(&dst, &cqe);
92
+ if (ret < 0) {
93
+ fprintf(stderr, "wait completion %d\n", ret);
94
+ goto err;
95
+ }
96
+ switch (cqe->user_data) {
97
+ case 0x1234:
98
+ if (cqe->res != 0x10) {
99
+ fprintf(stderr, "invalid len %x\n", cqe->res);
100
+ goto err;
101
+ }
102
+ break;
103
+ default:
104
+ fprintf(stderr, "Invalid user_data\n");
105
+ goto err;
106
+ }
107
+ io_uring_cqe_seen(&dst, cqe);
108
+ }
109
+
110
+ out:
111
+ io_uring_queue_exit(&dst);
112
+ return no_msg ? T_EXIT_SKIP : T_EXIT_PASS;
113
+ err:
114
+ io_uring_queue_exit(&dst);
115
+ return err_ret;
116
+ }
117
+
118
+ int main(int argc, char *argv[])
119
+ {
120
+ struct io_uring src;
121
+ int ret;
122
+
123
+ if (argc > 1)
124
+ return T_EXIT_SKIP;
125
+
126
+ ret = io_uring_queue_init(8, &src, 0);
127
+ if (ret) {
128
+ fprintf(stderr, "ring setup failed: %d\n", ret);
129
+ return T_EXIT_FAIL;
130
+ }
131
+
132
+ ret = test(&src, 0);
133
+ if (ret && !no_msg) {
134
+ fprintf(stderr, "test failed\n");
135
+ return ret;
136
+ }
137
+ if (no_msg)
138
+ return T_EXIT_SKIP;
139
+
140
+ ret = test(&src, IORING_SETUP_IOPOLL);
141
+ if (ret) {
142
+ fprintf(stderr, "test IOPOLL failed\n");
143
+ return ret;
144
+ }
145
+
146
+ ret = test(&src, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER);
147
+ if (ret) {
148
+ fprintf(stderr, "test defer failed\n");
149
+ return ret;
150
+ }
151
+
152
+ ret = test(&src, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_IOPOLL);
153
+ if (ret) {
154
+ fprintf(stderr, "test defer IOPOLL failed\n");
155
+ return ret;
156
+ }
157
+
158
+ return T_EXIT_PASS;
159
+ }