polyphony 0.94 → 0.96

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 (318) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +3 -3
  3. data/.github/workflows/test_io_uring.yml +4 -4
  4. data/.gitignore +3 -3
  5. data/CHANGELOG.md +19 -0
  6. data/docs/api-reference/fiber.md +2 -2
  7. data/docs/api-reference/object.md +3 -3
  8. data/docs/main-concepts/exception-handling.md +2 -2
  9. data/examples/adapters/redis_blpop.rb +4 -3
  10. data/examples/adapters/redis_channels.rb +16 -7
  11. data/examples/core/await.rb +1 -1
  12. data/examples/io/readline.rb +19 -0
  13. data/ext/polyphony/backend_common.c +25 -3
  14. data/ext/polyphony/backend_io_uring.c +18 -16
  15. data/ext/polyphony/backend_libev.c +2 -2
  16. data/ext/polyphony/event.c +1 -1
  17. data/ext/polyphony/extconf.rb +5 -3
  18. data/ext/polyphony/fiber.c +5 -13
  19. data/ext/polyphony/io_extensions.c +1 -1
  20. data/ext/polyphony/pipe.c +1 -1
  21. data/ext/polyphony/polyphony.c +1 -1
  22. data/ext/polyphony/polyphony_ext.c +1 -1
  23. data/ext/polyphony/queue.c +1 -1
  24. data/ext/polyphony/ring_buffer.c +1 -0
  25. data/ext/polyphony/socket_extensions.c +1 -1
  26. data/ext/polyphony/thread.c +1 -1
  27. data/lib/polyphony/adapters/readline.rb +6 -4
  28. data/lib/polyphony/adapters/redis.rb +28 -87
  29. data/lib/polyphony/core/channel.rb +15 -0
  30. data/lib/polyphony/core/sync.rb +4 -0
  31. data/lib/polyphony/debugger.rb +2 -2
  32. data/lib/polyphony/extensions/socket.rb +2 -0
  33. data/lib/polyphony/version.rb +1 -1
  34. data/lib/polyphony.rb +4 -0
  35. data/polyphony.gemspec +10 -10
  36. data/test/helper.rb +0 -5
  37. data/test/test_backend.rb +5 -1
  38. data/test/test_enumerator.rb +46 -0
  39. data/test/test_ext.rb +63 -0
  40. data/test/test_io.rb +241 -216
  41. data/test/test_socket.rb +1 -1
  42. data/test/test_thread_pool.rb +5 -5
  43. data/vendor/liburing/.github/workflows/build.yml +51 -5
  44. data/vendor/liburing/.github/workflows/shellcheck.yml +1 -1
  45. data/vendor/liburing/.gitignore +6 -123
  46. data/vendor/liburing/CHANGELOG +35 -0
  47. data/vendor/liburing/CITATION.cff +11 -0
  48. data/vendor/liburing/LICENSE +16 -3
  49. data/vendor/liburing/Makefile +3 -1
  50. data/vendor/liburing/Makefile.common +1 -0
  51. data/vendor/liburing/README +14 -2
  52. data/vendor/liburing/SECURITY.md +6 -0
  53. data/vendor/liburing/configure +16 -15
  54. data/vendor/liburing/examples/Makefile +4 -1
  55. data/vendor/liburing/examples/io_uring-udp.c +395 -0
  56. data/vendor/liburing/examples/poll-bench.c +101 -0
  57. data/vendor/liburing/examples/send-zerocopy.c +339 -0
  58. data/vendor/liburing/liburing.spec +1 -1
  59. data/vendor/liburing/man/io_uring.7 +38 -11
  60. data/vendor/liburing/man/io_uring_buf_ring_add.3 +53 -0
  61. data/vendor/liburing/man/io_uring_buf_ring_advance.3 +31 -0
  62. data/vendor/liburing/man/io_uring_buf_ring_cq_advance.3 +41 -0
  63. data/vendor/liburing/man/io_uring_buf_ring_init.3 +30 -0
  64. data/vendor/liburing/man/io_uring_buf_ring_mask.3 +27 -0
  65. data/vendor/liburing/man/io_uring_cq_advance.3 +29 -15
  66. data/vendor/liburing/man/io_uring_cq_has_overflow.3 +25 -0
  67. data/vendor/liburing/man/io_uring_cq_ready.3 +9 -8
  68. data/vendor/liburing/man/io_uring_cqe_get_data.3 +32 -13
  69. data/vendor/liburing/man/io_uring_cqe_get_data64.3 +1 -0
  70. data/vendor/liburing/man/io_uring_cqe_seen.3 +22 -12
  71. data/vendor/liburing/man/io_uring_enter.2 +249 -32
  72. data/vendor/liburing/man/io_uring_enter2.2 +1 -0
  73. data/vendor/liburing/man/io_uring_free_probe.3 +11 -8
  74. data/vendor/liburing/man/io_uring_get_events.3 +33 -0
  75. data/vendor/liburing/man/io_uring_get_probe.3 +9 -8
  76. data/vendor/liburing/man/io_uring_get_sqe.3 +29 -10
  77. data/vendor/liburing/man/io_uring_opcode_supported.3 +11 -10
  78. data/vendor/liburing/man/io_uring_peek_cqe.3 +38 -0
  79. data/vendor/liburing/man/io_uring_prep_accept.3 +197 -0
  80. data/vendor/liburing/man/io_uring_prep_accept_direct.3 +1 -0
  81. data/vendor/liburing/man/io_uring_prep_cancel.3 +118 -0
  82. data/vendor/liburing/man/io_uring_prep_cancel64.3 +1 -0
  83. data/vendor/liburing/man/io_uring_prep_close.3 +59 -0
  84. data/vendor/liburing/man/io_uring_prep_close_direct.3 +1 -0
  85. data/vendor/liburing/man/io_uring_prep_connect.3 +66 -0
  86. data/vendor/liburing/man/io_uring_prep_fadvise.3 +59 -0
  87. data/vendor/liburing/man/io_uring_prep_fallocate.3 +59 -0
  88. data/vendor/liburing/man/io_uring_prep_files_update.3 +92 -0
  89. data/vendor/liburing/man/io_uring_prep_fsync.3 +70 -0
  90. data/vendor/liburing/man/io_uring_prep_link.3 +1 -0
  91. data/vendor/liburing/man/io_uring_prep_linkat.3 +91 -0
  92. data/vendor/liburing/man/io_uring_prep_madvise.3 +56 -0
  93. data/vendor/liburing/man/io_uring_prep_mkdir.3 +1 -0
  94. data/vendor/liburing/man/io_uring_prep_mkdirat.3 +83 -0
  95. data/vendor/liburing/man/io_uring_prep_msg_ring.3 +39 -25
  96. data/vendor/liburing/man/io_uring_prep_multishot_accept.3 +1 -0
  97. data/vendor/liburing/man/io_uring_prep_multishot_accept_direct.3 +1 -0
  98. data/vendor/liburing/man/io_uring_prep_nop.3 +28 -0
  99. data/vendor/liburing/man/io_uring_prep_openat.3 +117 -0
  100. data/vendor/liburing/man/io_uring_prep_openat2.3 +117 -0
  101. data/vendor/liburing/man/io_uring_prep_openat2_direct.3 +1 -0
  102. data/vendor/liburing/man/io_uring_prep_openat_direct.3 +1 -0
  103. data/vendor/liburing/man/io_uring_prep_poll_add.3 +72 -0
  104. data/vendor/liburing/man/io_uring_prep_poll_multishot.3 +1 -0
  105. data/vendor/liburing/man/io_uring_prep_poll_remove.3 +55 -0
  106. data/vendor/liburing/man/io_uring_prep_poll_update.3 +89 -0
  107. data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +131 -0
  108. data/vendor/liburing/man/io_uring_prep_read.3 +33 -14
  109. data/vendor/liburing/man/io_uring_prep_read_fixed.3 +39 -21
  110. data/vendor/liburing/man/io_uring_prep_readv.3 +49 -15
  111. data/vendor/liburing/man/io_uring_prep_readv2.3 +49 -17
  112. data/vendor/liburing/man/io_uring_prep_recv.3 +105 -0
  113. data/vendor/liburing/man/io_uring_prep_recv_multishot.3 +1 -0
  114. data/vendor/liburing/man/io_uring_prep_recvmsg.3 +124 -0
  115. data/vendor/liburing/man/io_uring_prep_recvmsg_multishot.3 +1 -0
  116. data/vendor/liburing/man/io_uring_prep_remove_buffers.3 +52 -0
  117. data/vendor/liburing/man/io_uring_prep_rename.3 +1 -0
  118. data/vendor/liburing/man/io_uring_prep_renameat.3 +96 -0
  119. data/vendor/liburing/man/io_uring_prep_send.3 +57 -0
  120. data/vendor/liburing/man/io_uring_prep_send_zc.3 +64 -0
  121. data/vendor/liburing/man/io_uring_prep_sendmsg.3 +69 -0
  122. data/vendor/liburing/man/io_uring_prep_shutdown.3 +53 -0
  123. data/vendor/liburing/man/io_uring_prep_socket.3 +118 -0
  124. data/vendor/liburing/man/io_uring_prep_socket_direct.3 +1 -0
  125. data/vendor/liburing/man/io_uring_prep_socket_direct_alloc.3 +1 -0
  126. data/vendor/liburing/man/io_uring_prep_splice.3 +80 -0
  127. data/vendor/liburing/man/io_uring_prep_statx.3 +74 -0
  128. data/vendor/liburing/man/io_uring_prep_symlink.3 +1 -0
  129. data/vendor/liburing/man/io_uring_prep_symlinkat.3 +85 -0
  130. data/vendor/liburing/man/io_uring_prep_sync_file_range.3 +59 -0
  131. data/vendor/liburing/man/io_uring_prep_tee.3 +74 -0
  132. data/vendor/liburing/man/io_uring_prep_timeout.3 +95 -0
  133. data/vendor/liburing/man/io_uring_prep_timeout_remove.3 +1 -0
  134. data/vendor/liburing/man/io_uring_prep_timeout_update.3 +98 -0
  135. data/vendor/liburing/man/io_uring_prep_unlink.3 +1 -0
  136. data/vendor/liburing/man/io_uring_prep_unlinkat.3 +82 -0
  137. data/vendor/liburing/man/io_uring_prep_write.3 +32 -15
  138. data/vendor/liburing/man/io_uring_prep_write_fixed.3 +39 -21
  139. data/vendor/liburing/man/io_uring_prep_writev.3 +50 -16
  140. data/vendor/liburing/man/io_uring_prep_writev2.3 +50 -17
  141. data/vendor/liburing/man/io_uring_queue_exit.3 +3 -4
  142. data/vendor/liburing/man/io_uring_queue_init.3 +58 -13
  143. data/vendor/liburing/man/io_uring_queue_init_params.3 +1 -0
  144. data/vendor/liburing/man/io_uring_recvmsg_cmsg_firsthdr.3 +1 -0
  145. data/vendor/liburing/man/io_uring_recvmsg_cmsg_nexthdr.3 +1 -0
  146. data/vendor/liburing/man/io_uring_recvmsg_name.3 +1 -0
  147. data/vendor/liburing/man/io_uring_recvmsg_out.3 +78 -0
  148. data/vendor/liburing/man/io_uring_recvmsg_payload.3 +1 -0
  149. data/vendor/liburing/man/io_uring_recvmsg_payload_length.3 +1 -0
  150. data/vendor/liburing/man/io_uring_recvmsg_validate.3 +1 -0
  151. data/vendor/liburing/man/io_uring_register.2 +153 -13
  152. data/vendor/liburing/man/io_uring_register_buf_ring.3 +140 -0
  153. data/vendor/liburing/man/io_uring_register_buffers.3 +32 -12
  154. data/vendor/liburing/man/io_uring_register_eventfd.3 +51 -0
  155. data/vendor/liburing/man/io_uring_register_eventfd_async.3 +1 -0
  156. data/vendor/liburing/man/io_uring_register_file_alloc_range.3 +52 -0
  157. data/vendor/liburing/man/io_uring_register_files.3 +33 -11
  158. data/vendor/liburing/man/io_uring_register_files_sparse.3 +1 -0
  159. data/vendor/liburing/man/io_uring_register_iowq_aff.3 +61 -0
  160. data/vendor/liburing/man/io_uring_register_iowq_max_workers.3 +71 -0
  161. data/vendor/liburing/man/io_uring_register_ring_fd.3 +49 -0
  162. data/vendor/liburing/man/io_uring_register_sync_cancel.3 +71 -0
  163. data/vendor/liburing/man/io_uring_setup.2 +119 -13
  164. data/vendor/liburing/man/io_uring_sq_ready.3 +14 -8
  165. data/vendor/liburing/man/io_uring_sq_space_left.3 +9 -9
  166. data/vendor/liburing/man/io_uring_sqe_set_data.3 +29 -11
  167. data/vendor/liburing/man/io_uring_sqe_set_data64.3 +1 -0
  168. data/vendor/liburing/man/io_uring_sqe_set_flags.3 +38 -11
  169. data/vendor/liburing/man/io_uring_sqring_wait.3 +13 -9
  170. data/vendor/liburing/man/io_uring_submit.3 +29 -12
  171. data/vendor/liburing/man/io_uring_submit_and_get_events.3 +31 -0
  172. data/vendor/liburing/man/io_uring_submit_and_wait.3 +16 -12
  173. data/vendor/liburing/man/io_uring_submit_and_wait_timeout.3 +30 -23
  174. data/vendor/liburing/man/io_uring_unregister_buf_ring.3 +30 -0
  175. data/vendor/liburing/man/io_uring_unregister_buffers.3 +11 -10
  176. data/vendor/liburing/man/io_uring_unregister_eventfd.3 +1 -0
  177. data/vendor/liburing/man/io_uring_unregister_files.3 +11 -10
  178. data/vendor/liburing/man/io_uring_unregister_iowq_aff.3 +1 -0
  179. data/vendor/liburing/man/io_uring_unregister_ring_fd.3 +32 -0
  180. data/vendor/liburing/man/io_uring_wait_cqe.3 +19 -12
  181. data/vendor/liburing/man/io_uring_wait_cqe_nr.3 +21 -14
  182. data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +27 -13
  183. data/vendor/liburing/man/io_uring_wait_cqes.3 +24 -14
  184. data/vendor/liburing/src/Makefile +8 -7
  185. data/vendor/liburing/src/arch/aarch64/lib.h +48 -0
  186. data/vendor/liburing/src/arch/aarch64/syscall.h +0 -4
  187. data/vendor/liburing/src/arch/generic/lib.h +0 -4
  188. data/vendor/liburing/src/arch/generic/syscall.h +29 -16
  189. data/vendor/liburing/src/arch/syscall-defs.h +41 -14
  190. data/vendor/liburing/src/arch/x86/lib.h +0 -21
  191. data/vendor/liburing/src/arch/x86/syscall.h +146 -10
  192. data/vendor/liburing/src/include/liburing/io_uring.h +245 -5
  193. data/vendor/liburing/src/include/liburing.h +468 -35
  194. data/vendor/liburing/src/int_flags.h +1 -0
  195. data/vendor/liburing/src/lib.h +20 -16
  196. data/vendor/liburing/src/liburing.map +16 -0
  197. data/vendor/liburing/src/nolibc.c +1 -1
  198. data/vendor/liburing/src/queue.c +87 -55
  199. data/vendor/liburing/src/register.c +129 -53
  200. data/vendor/liburing/src/setup.c +65 -28
  201. data/vendor/liburing/src/syscall.c +14 -32
  202. data/vendor/liburing/src/syscall.h +12 -64
  203. data/vendor/liburing/test/{232c93d07b74-test.c → 232c93d07b74.c} +8 -9
  204. data/vendor/liburing/test/{35fa71a030ca-test.c → 35fa71a030ca.c} +4 -4
  205. data/vendor/liburing/test/{500f9fbadef8-test.c → 500f9fbadef8.c} +7 -7
  206. data/vendor/liburing/test/{7ad0e4b2f83c-test.c → 7ad0e4b2f83c.c} +8 -7
  207. data/vendor/liburing/test/{8a9973408177-test.c → 8a9973408177.c} +4 -3
  208. data/vendor/liburing/test/{917257daa0fe-test.c → 917257daa0fe.c} +3 -2
  209. data/vendor/liburing/test/Makefile +60 -62
  210. data/vendor/liburing/test/{a0908ae19763-test.c → a0908ae19763.c} +3 -2
  211. data/vendor/liburing/test/{a4c0b3decb33-test.c → a4c0b3decb33.c} +3 -2
  212. data/vendor/liburing/test/accept-link.c +5 -4
  213. data/vendor/liburing/test/accept-reuse.c +17 -16
  214. data/vendor/liburing/test/accept-test.c +14 -10
  215. data/vendor/liburing/test/accept.c +529 -107
  216. data/vendor/liburing/test/across-fork.c +7 -6
  217. data/vendor/liburing/test/{b19062a56726-test.c → b19062a56726.c} +3 -2
  218. data/vendor/liburing/test/{b5837bd5311d-test.c → b5837bd5311d.c} +10 -9
  219. data/vendor/liburing/test/buf-ring.c +420 -0
  220. data/vendor/liburing/test/{ce593a6c480a-test.c → ce593a6c480a.c} +15 -12
  221. data/vendor/liburing/test/connect.c +8 -7
  222. data/vendor/liburing/test/cq-full.c +5 -4
  223. data/vendor/liburing/test/cq-overflow.c +242 -12
  224. data/vendor/liburing/test/cq-peek-batch.c +5 -4
  225. data/vendor/liburing/test/cq-ready.c +5 -4
  226. data/vendor/liburing/test/cq-size.c +5 -4
  227. data/vendor/liburing/test/{d4ae271dfaae-test.c → d4ae271dfaae.c} +2 -2
  228. data/vendor/liburing/test/{d77a67ed5f27-test.c → d77a67ed5f27.c} +6 -6
  229. data/vendor/liburing/test/defer-taskrun.c +336 -0
  230. data/vendor/liburing/test/defer.c +26 -14
  231. data/vendor/liburing/test/double-poll-crash.c +15 -5
  232. data/vendor/liburing/test/drop-submit.c +5 -3
  233. data/vendor/liburing/test/{eeed8b54e0df-test.c → eeed8b54e0df.c} +7 -6
  234. data/vendor/liburing/test/empty-eownerdead.c +4 -4
  235. data/vendor/liburing/test/eventfd-disable.c +48 -20
  236. data/vendor/liburing/test/eventfd-reg.c +10 -9
  237. data/vendor/liburing/test/eventfd-ring.c +13 -12
  238. data/vendor/liburing/test/eventfd.c +13 -12
  239. data/vendor/liburing/test/exit-no-cleanup.c +1 -1
  240. data/vendor/liburing/test/fadvise.c +3 -3
  241. data/vendor/liburing/test/fallocate.c +16 -9
  242. data/vendor/liburing/test/{fc2a85cb02ef-test.c → fc2a85cb02ef.c} +4 -3
  243. data/vendor/liburing/test/fd-pass.c +187 -0
  244. data/vendor/liburing/test/file-register.c +302 -36
  245. data/vendor/liburing/test/file-update.c +62 -4
  246. data/vendor/liburing/test/file-verify.c +6 -2
  247. data/vendor/liburing/test/files-exit-hang-poll.c +11 -25
  248. data/vendor/liburing/test/files-exit-hang-timeout.c +13 -10
  249. data/vendor/liburing/test/fixed-buf-iter.c +115 -0
  250. data/vendor/liburing/test/fixed-link.c +10 -10
  251. data/vendor/liburing/test/fixed-reuse.c +160 -0
  252. data/vendor/liburing/test/fpos.c +6 -3
  253. data/vendor/liburing/test/fsync.c +3 -3
  254. data/vendor/liburing/test/hardlink.c +10 -6
  255. data/vendor/liburing/test/helpers.c +137 -4
  256. data/vendor/liburing/test/helpers.h +27 -0
  257. data/vendor/liburing/test/io-cancel.c +16 -11
  258. data/vendor/liburing/test/io_uring_enter.c +46 -81
  259. data/vendor/liburing/test/io_uring_passthrough.c +451 -0
  260. data/vendor/liburing/test/io_uring_register.c +59 -229
  261. data/vendor/liburing/test/io_uring_setup.c +24 -29
  262. data/vendor/liburing/test/iopoll-leak.c +85 -0
  263. data/vendor/liburing/test/iopoll.c +16 -9
  264. data/vendor/liburing/test/lfs-openat-write.c +3 -1
  265. data/vendor/liburing/test/link-timeout.c +4 -3
  266. data/vendor/liburing/test/link.c +8 -7
  267. data/vendor/liburing/test/madvise.c +2 -2
  268. data/vendor/liburing/test/mkdir.c +9 -5
  269. data/vendor/liburing/test/msg-ring.c +46 -20
  270. data/vendor/liburing/test/multicqes_drain.c +51 -12
  271. data/vendor/liburing/test/nolibc.c +60 -0
  272. data/vendor/liburing/test/nop.c +78 -16
  273. data/vendor/liburing/test/nvme.h +168 -0
  274. data/vendor/liburing/test/open-direct-link.c +188 -0
  275. data/vendor/liburing/test/open-direct-pick.c +180 -0
  276. data/vendor/liburing/test/openat2.c +3 -3
  277. data/vendor/liburing/test/poll-cancel-all.c +472 -0
  278. data/vendor/liburing/test/poll-link.c +9 -18
  279. data/vendor/liburing/test/poll-mshot-overflow.c +162 -0
  280. data/vendor/liburing/test/poll-mshot-update.c +83 -33
  281. data/vendor/liburing/test/pollfree.c +2 -2
  282. data/vendor/liburing/test/read-before-exit.c +112 -0
  283. data/vendor/liburing/test/read-write.c +83 -1
  284. data/vendor/liburing/test/recv-msgall-stream.c +398 -0
  285. data/vendor/liburing/test/recv-msgall.c +265 -0
  286. data/vendor/liburing/test/recv-multishot.c +505 -0
  287. data/vendor/liburing/test/rename.c +2 -5
  288. data/vendor/liburing/test/ring-leak.c +97 -0
  289. data/vendor/liburing/test/ringbuf-read.c +200 -0
  290. data/vendor/liburing/test/rsrc_tags.c +25 -13
  291. data/vendor/liburing/test/runtests-quiet.sh +11 -0
  292. data/vendor/liburing/test/runtests.sh +18 -20
  293. data/vendor/liburing/test/rw_merge_test.c +3 -2
  294. data/vendor/liburing/test/send-zerocopy.c +684 -0
  295. data/vendor/liburing/test/send_recv.c +49 -2
  296. data/vendor/liburing/test/send_recvmsg.c +165 -55
  297. data/vendor/liburing/test/shutdown.c +3 -4
  298. data/vendor/liburing/test/sigfd-deadlock.c +22 -8
  299. data/vendor/liburing/test/single-issuer.c +171 -0
  300. data/vendor/liburing/test/socket-rw-eagain.c +2 -12
  301. data/vendor/liburing/test/socket-rw-offset.c +2 -11
  302. data/vendor/liburing/test/socket-rw.c +2 -11
  303. data/vendor/liburing/test/socket.c +409 -0
  304. data/vendor/liburing/test/sq-poll-dup.c +1 -1
  305. data/vendor/liburing/test/sq-poll-share.c +1 -1
  306. data/vendor/liburing/test/statx.c +2 -2
  307. data/vendor/liburing/test/submit-and-wait.c +108 -0
  308. data/vendor/liburing/test/submit-link-fail.c +5 -3
  309. data/vendor/liburing/test/submit-reuse.c +0 -2
  310. data/vendor/liburing/test/sync-cancel.c +235 -0
  311. data/vendor/liburing/test/test.h +35 -0
  312. data/vendor/liburing/test/timeout-overflow.c +11 -11
  313. data/vendor/liburing/test/timeout.c +7 -7
  314. data/vendor/liburing/test/tty-write-dpoll.c +60 -0
  315. data/vendor/liburing/test/unlink.c +1 -1
  316. data/vendor/liburing/test/xattr.c +425 -0
  317. metadata +160 -52
  318. data/Gemfile.lock +0 -78
@@ -0,0 +1,336 @@
1
+ // SPDX-License-Identifier: MIT
2
+ #include <errno.h>
3
+ #include <stdio.h>
4
+ #include <unistd.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <error.h>
8
+ #include <sys/eventfd.h>
9
+ #include <signal.h>
10
+ #include <poll.h>
11
+ #include <assert.h>
12
+ #include <pthread.h>
13
+ #include <sys/types.h>
14
+ #include <sys/wait.h>
15
+
16
+ #include "liburing.h"
17
+ #include "test.h"
18
+ #include "helpers.h"
19
+
20
+ #define EXEC_FILENAME ".defer-taskrun"
21
+ #define EXEC_FILESIZE (1U<<20)
22
+
23
+ static bool can_read_t(int fd, int time)
24
+ {
25
+ int ret;
26
+ struct pollfd p = {
27
+ .fd = fd,
28
+ .events = POLLIN,
29
+ };
30
+
31
+ ret = poll(&p, 1, time);
32
+
33
+ return ret == 1;
34
+ }
35
+
36
+ static bool can_read(int fd)
37
+ {
38
+ return can_read_t(fd, 0);
39
+ }
40
+
41
+ static void eventfd_clear(int fd)
42
+ {
43
+ uint64_t val;
44
+ int ret;
45
+
46
+ assert(can_read(fd));
47
+ ret = read(fd, &val, 8);
48
+ assert(ret == 8);
49
+ }
50
+
51
+ static void eventfd_trigger(int fd)
52
+ {
53
+ uint64_t val = 1;
54
+ int ret;
55
+
56
+ ret = write(fd, &val, sizeof(val));
57
+ assert(ret == sizeof(val));
58
+ }
59
+
60
+ #define CHECK(x) if (!(x)) { \
61
+ fprintf(stderr, "%s:%d %s failed\n", __FILE__, __LINE__, #x); \
62
+ return -1; }
63
+
64
+ static int test_eventfd(void)
65
+ {
66
+ struct io_uring ring;
67
+ int ret;
68
+ int fda, fdb;
69
+ struct io_uring_cqe *cqe;
70
+
71
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
72
+ IORING_SETUP_DEFER_TASKRUN);
73
+ if (ret)
74
+ return ret;
75
+
76
+ fda = eventfd(0, EFD_NONBLOCK);
77
+ fdb = eventfd(0, EFD_NONBLOCK);
78
+
79
+ CHECK(fda >= 0 && fdb >= 0);
80
+
81
+ ret = io_uring_register_eventfd(&ring, fda);
82
+ if (ret)
83
+ return ret;
84
+
85
+ CHECK(!can_read(fda));
86
+ CHECK(!can_read(fdb));
87
+
88
+ io_uring_prep_poll_add(io_uring_get_sqe(&ring), fdb, POLLIN);
89
+ io_uring_submit(&ring);
90
+ CHECK(!can_read(fda)); /* poll should not have completed */
91
+
92
+ io_uring_prep_nop(io_uring_get_sqe(&ring));
93
+ io_uring_submit(&ring);
94
+ CHECK(can_read(fda)); /* nop should have */
95
+
96
+ CHECK(io_uring_peek_cqe(&ring, &cqe) == 0);
97
+ CHECK(cqe->res == 0);
98
+ io_uring_cqe_seen(&ring, cqe);
99
+ eventfd_clear(fda);
100
+
101
+ eventfd_trigger(fdb);
102
+ /* can take time due to rcu_call */
103
+ CHECK(can_read_t(fda, 1000));
104
+
105
+ /* should not have processed the cqe yet */
106
+ CHECK(io_uring_cq_ready(&ring) == 0);
107
+
108
+ io_uring_get_events(&ring);
109
+ CHECK(io_uring_cq_ready(&ring) == 1);
110
+
111
+
112
+ io_uring_queue_exit(&ring);
113
+ return 0;
114
+ }
115
+
116
+ struct thread_data {
117
+ struct io_uring ring;
118
+ int efd;
119
+ char buff[8];
120
+ };
121
+
122
+ void *thread(void *t)
123
+ {
124
+ struct thread_data *td = t;
125
+
126
+ io_uring_enable_rings(&td->ring);
127
+ io_uring_prep_read(io_uring_get_sqe(&td->ring), td->efd, td->buff, sizeof(td->buff), 0);
128
+ io_uring_submit(&td->ring);
129
+
130
+ return NULL;
131
+ }
132
+
133
+ static int test_thread_shutdown(void)
134
+ {
135
+ pthread_t t1;
136
+ int ret;
137
+ struct thread_data td;
138
+ struct io_uring_cqe *cqe;
139
+ uint64_t val = 1;
140
+
141
+ ret = io_uring_queue_init(8, &td.ring, IORING_SETUP_SINGLE_ISSUER |
142
+ IORING_SETUP_DEFER_TASKRUN |
143
+ IORING_SETUP_R_DISABLED);
144
+ if (ret)
145
+ return ret;
146
+
147
+ CHECK(io_uring_get_events(&td.ring) == -EBADFD);
148
+
149
+ td.efd = eventfd(0, 0);
150
+ CHECK(td.efd >= 0);
151
+
152
+ CHECK(pthread_create(&t1, NULL, thread, &td) == 0);
153
+ CHECK(pthread_join(t1, NULL) == 0);
154
+
155
+ CHECK(io_uring_get_events(&td.ring) == -EEXIST);
156
+
157
+ CHECK(write(td.efd, &val, sizeof(val)) == sizeof(val));
158
+ CHECK(io_uring_wait_cqe(&td.ring, &cqe) == -EEXIST);
159
+
160
+ close(td.efd);
161
+ io_uring_queue_exit(&td.ring);
162
+ return 0;
163
+ }
164
+
165
+ static int test_exec(const char *filename)
166
+ {
167
+ int ret;
168
+ int fd;
169
+ struct io_uring ring;
170
+ pid_t fork_pid;
171
+ static char * const new_argv[] = {"1", "2", "3", NULL};
172
+ static char * const new_env[] = {NULL};
173
+ char *buff;
174
+
175
+ fork_pid = fork();
176
+ CHECK(fork_pid >= 0);
177
+ if (fork_pid > 0) {
178
+ int wstatus;
179
+
180
+ CHECK(waitpid(fork_pid, &wstatus, 0) != (pid_t)-1);
181
+ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != T_EXIT_SKIP) {
182
+ fprintf(stderr, "child failed %i\n", WEXITSTATUS(wstatus));
183
+ return -1;
184
+ }
185
+ return 0;
186
+ }
187
+
188
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
189
+ IORING_SETUP_DEFER_TASKRUN);
190
+ if (ret)
191
+ return ret;
192
+
193
+ if (filename) {
194
+ fd = open(filename, O_RDONLY | O_DIRECT);
195
+ } else {
196
+ t_create_file(EXEC_FILENAME, EXEC_FILESIZE);
197
+ fd = open(EXEC_FILENAME, O_RDONLY | O_DIRECT);
198
+ unlink(EXEC_FILENAME);
199
+ }
200
+ buff = (char*)malloc(EXEC_FILESIZE);
201
+ CHECK(posix_memalign((void **)&buff, 4096, EXEC_FILESIZE) == 0);
202
+ CHECK(buff);
203
+
204
+ CHECK(fd >= 0);
205
+ io_uring_prep_read(io_uring_get_sqe(&ring), fd, buff, EXEC_FILESIZE, 0);
206
+ io_uring_submit(&ring);
207
+ ret = execve("/proc/self/exe", new_argv, new_env);
208
+ /* if we get here it failed anyway */
209
+ fprintf(stderr, "execve failed %d\n", ret);
210
+ return -1;
211
+ }
212
+
213
+ static int test_flag(void)
214
+ {
215
+ struct io_uring ring;
216
+ int ret;
217
+ int fd;
218
+ struct io_uring_cqe *cqe;
219
+
220
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
221
+ IORING_SETUP_DEFER_TASKRUN |
222
+ IORING_SETUP_TASKRUN_FLAG);
223
+ CHECK(!ret);
224
+
225
+ fd = eventfd(0, EFD_NONBLOCK);
226
+ CHECK(fd >= 0);
227
+
228
+ io_uring_prep_poll_add(io_uring_get_sqe(&ring), fd, POLLIN);
229
+ io_uring_submit(&ring);
230
+ CHECK(!can_read(fd)); /* poll should not have completed */
231
+
232
+ eventfd_trigger(fd);
233
+ CHECK(can_read(fd));
234
+
235
+ /* should not have processed the poll cqe yet */
236
+ CHECK(io_uring_cq_ready(&ring) == 0);
237
+
238
+ /* flag should be set */
239
+ CHECK(IO_URING_READ_ONCE(*ring.sq.kflags) & IORING_SQ_TASKRUN);
240
+
241
+ /* Specifically peek, knowing we have only no cqe
242
+ * but because the flag is set, liburing should try and get more
243
+ */
244
+ ret = io_uring_peek_cqe(&ring, &cqe);
245
+
246
+ CHECK(ret == 0 && cqe);
247
+ CHECK(!(IO_URING_READ_ONCE(*ring.sq.kflags) & IORING_SQ_TASKRUN));
248
+
249
+ close(fd);
250
+ io_uring_queue_exit(&ring);
251
+ return 0;
252
+ }
253
+
254
+ static int test_ring_shutdown(void)
255
+ {
256
+ struct io_uring ring;
257
+ int ret;
258
+ int fd[2];
259
+ char buff = '\0';
260
+ char send = 'X';
261
+
262
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
263
+ IORING_SETUP_DEFER_TASKRUN |
264
+ IORING_SETUP_TASKRUN_FLAG);
265
+ CHECK(!ret);
266
+
267
+ ret = t_create_socket_pair(fd, true);
268
+ CHECK(!ret);
269
+
270
+ io_uring_prep_recv(io_uring_get_sqe(&ring), fd[0], &buff, 1, 0);
271
+ io_uring_submit(&ring);
272
+
273
+ ret = write(fd[1], &send, 1);
274
+ CHECK(ret == 1);
275
+
276
+ /* should not have processed the poll cqe yet */
277
+ CHECK(io_uring_cq_ready(&ring) == 0);
278
+ io_uring_queue_exit(&ring);
279
+
280
+ /* task work should have been processed by now */
281
+ CHECK(buff = 'X');
282
+
283
+ return 0;
284
+ }
285
+
286
+ int main(int argc, char *argv[])
287
+ {
288
+ int ret;
289
+ const char *filename = NULL;
290
+
291
+ if (argc > 2)
292
+ return T_EXIT_SKIP;
293
+ if (argc == 2) {
294
+ /* This test exposes interesting behaviour with a null-blk
295
+ * device configured like:
296
+ * $ modprobe null-blk completion_nsec=100000000 irqmode=2
297
+ * and then run with $ defer-taskrun.t /dev/nullb0
298
+ */
299
+ filename = argv[1];
300
+ }
301
+
302
+ if (!t_probe_defer_taskrun())
303
+ return T_EXIT_SKIP;
304
+
305
+ ret = test_thread_shutdown();
306
+ if (ret) {
307
+ fprintf(stderr, "test_thread_shutdown failed\n");
308
+ return T_EXIT_FAIL;
309
+ }
310
+
311
+ ret = test_exec(filename);
312
+ if (ret) {
313
+ fprintf(stderr, "test_exec failed\n");
314
+ return T_EXIT_FAIL;
315
+ }
316
+
317
+ ret = test_eventfd();
318
+ if (ret) {
319
+ fprintf(stderr, "eventfd failed\n");
320
+ return T_EXIT_FAIL;
321
+ }
322
+
323
+ ret = test_flag();
324
+ if (ret) {
325
+ fprintf(stderr, "flag failed\n");
326
+ return T_EXIT_FAIL;
327
+ }
328
+
329
+ ret = test_ring_shutdown();
330
+ if (ret) {
331
+ fprintf(stderr, "test_ring_shutdown failed\n");
332
+ return T_EXIT_FAIL;
333
+ }
334
+
335
+ return T_EXIT_PASS;
336
+ }
@@ -12,6 +12,10 @@
12
12
  #include "liburing.h"
13
13
 
14
14
  #define RING_SIZE 128
15
+ enum {
16
+ OP_NOP,
17
+ OP_REMOVE_BUFFERS
18
+ };
15
19
 
16
20
  struct test_context {
17
21
  struct io_uring *ring;
@@ -27,7 +31,8 @@ static void free_context(struct test_context *ctx)
27
31
  memset(ctx, 0, sizeof(*ctx));
28
32
  }
29
33
 
30
- static int init_context(struct test_context *ctx, struct io_uring *ring, int nr)
34
+ static int init_context(struct test_context *ctx, struct io_uring *ring, int nr,
35
+ int op)
31
36
  {
32
37
  struct io_uring_sqe *sqe;
33
38
  int i;
@@ -45,7 +50,14 @@ static int init_context(struct test_context *ctx, struct io_uring *ring, int nr)
45
50
  sqe = io_uring_get_sqe(ring);
46
51
  if (!sqe)
47
52
  goto err;
48
- io_uring_prep_nop(sqe);
53
+ switch (op) {
54
+ case OP_NOP:
55
+ io_uring_prep_nop(sqe);
56
+ break;
57
+ case OP_REMOVE_BUFFERS:
58
+ io_uring_prep_remove_buffers(sqe, 10, 1);
59
+ break;
60
+ };
49
61
  sqe->user_data = i;
50
62
  ctx->sqes[i] = sqe;
51
63
  }
@@ -81,7 +93,7 @@ static int test_cancelled_userdata(struct io_uring *ring)
81
93
  struct test_context ctx;
82
94
  int ret, i, nr = 100;
83
95
 
84
- if (init_context(&ctx, ring, nr))
96
+ if (init_context(&ctx, ring, nr, OP_NOP))
85
97
  return 1;
86
98
 
87
99
  for (i = 0; i < nr; i++)
@@ -115,7 +127,7 @@ static int test_thread_link_cancel(struct io_uring *ring)
115
127
  struct test_context ctx;
116
128
  int ret, i, nr = 100;
117
129
 
118
- if (init_context(&ctx, ring, nr))
130
+ if (init_context(&ctx, ring, nr, OP_REMOVE_BUFFERS))
119
131
  return 1;
120
132
 
121
133
  for (i = 0; i < nr; i++)
@@ -134,12 +146,12 @@ static int test_thread_link_cancel(struct io_uring *ring)
134
146
  bool fail = false;
135
147
 
136
148
  if (i == 0)
137
- fail = (ctx.cqes[i].res != -EINVAL);
149
+ fail = (ctx.cqes[i].res != -ENOENT);
138
150
  else
139
151
  fail = (ctx.cqes[i].res != -ECANCELED);
140
152
 
141
153
  if (fail) {
142
- printf("invalid status\n");
154
+ printf("invalid status %d\n", ctx.cqes[i].res);
143
155
  goto err;
144
156
  }
145
157
  }
@@ -158,7 +170,7 @@ static int test_drain_with_linked_timeout(struct io_uring *ring)
158
170
  struct test_context ctx;
159
171
  int ret, i;
160
172
 
161
- if (init_context(&ctx, ring, nr * 2))
173
+ if (init_context(&ctx, ring, nr * 2, OP_NOP))
162
174
  return 1;
163
175
 
164
176
  for (i = 0; i < nr; i++) {
@@ -188,7 +200,7 @@ static int run_drained(struct io_uring *ring, int nr)
188
200
  struct test_context ctx;
189
201
  int ret, i;
190
202
 
191
- if (init_context(&ctx, ring, nr))
203
+ if (init_context(&ctx, ring, nr, OP_NOP))
192
204
  return 1;
193
205
 
194
206
  for (i = 0; i < nr; i++)
@@ -248,19 +260,19 @@ int main(int argc, char *argv[])
248
260
  int ret;
249
261
 
250
262
  if (argc > 1)
251
- return 0;
263
+ return T_EXIT_SKIP;
252
264
 
253
265
  memset(&p, 0, sizeof(p));
254
266
  ret = io_uring_queue_init_params(RING_SIZE, &ring, &p);
255
267
  if (ret) {
256
268
  printf("ring setup failed %i\n", ret);
257
- return 1;
269
+ return T_EXIT_FAIL;
258
270
  }
259
271
 
260
272
  ret = io_uring_queue_init(RING_SIZE, &poll_ring, IORING_SETUP_IOPOLL);
261
273
  if (ret) {
262
274
  printf("poll_ring setup failed\n");
263
- return 1;
275
+ return T_EXIT_FAIL;
264
276
  }
265
277
 
266
278
 
@@ -293,9 +305,9 @@ int main(int argc, char *argv[])
293
305
  ret = t_create_ring(RING_SIZE, &sqthread_ring,
294
306
  IORING_SETUP_SQPOLL | IORING_SETUP_IOPOLL);
295
307
  if (ret == T_SETUP_SKIP)
296
- return 0;
308
+ return T_EXIT_SKIP;
297
309
  else if (ret < 0)
298
- return 1;
310
+ return T_EXIT_FAIL;
299
311
 
300
312
  ret = test_thread_link_cancel(&sqthread_ring);
301
313
  if (ret) {
@@ -303,5 +315,5 @@ int main(int argc, char *argv[])
303
315
  return ret;
304
316
  }
305
317
 
306
- return 0;
318
+ return T_EXIT_PASS;
307
319
  }
@@ -15,6 +15,7 @@
15
15
  #include <unistd.h>
16
16
 
17
17
  #include "liburing.h"
18
+ #include "helpers.h"
18
19
  #include "../src/syscall.h"
19
20
 
20
21
  #define SIZEOF_IO_URING_SQE 64
@@ -52,10 +53,14 @@ static long syz_io_uring_setup(volatile long a0, volatile long a1,
52
53
  *ring_ptr_out = mmap(vma1, ring_sz, PROT_READ | PROT_WRITE,
53
54
  MAP_SHARED | MAP_POPULATE | MAP_FIXED, fd_io_uring,
54
55
  IORING_OFF_SQ_RING);
56
+ if (*ring_ptr_out == MAP_FAILED)
57
+ exit(0);
55
58
  uint32_t sqes_sz = setup_params->sq_entries * SIZEOF_IO_URING_SQE;
56
59
  *sqes_ptr_out =
57
60
  mmap(vma2, sqes_sz, PROT_READ | PROT_WRITE,
58
61
  MAP_SHARED | MAP_POPULATE | MAP_FIXED, fd_io_uring, IORING_OFF_SQES);
62
+ if (*sqes_ptr_out == MAP_FAILED)
63
+ exit(0);
59
64
  return fd_io_uring;
60
65
  }
61
66
 
@@ -108,15 +113,20 @@ uint64_t r[4] = {0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff};
108
113
 
109
114
  int main(int argc, char *argv[])
110
115
  {
116
+ void *mmap_ret;
111
117
  #if !defined(__i386) && !defined(__x86_64__)
112
- return 0;
118
+ return T_EXIT_SKIP;
113
119
  #endif
114
120
 
115
121
  if (argc > 1)
116
- return 0;
122
+ return T_EXIT_SKIP;
117
123
 
118
- mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
119
- mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
124
+ mmap_ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
125
+ if (mmap_ret == MAP_FAILED)
126
+ return T_EXIT_SKIP;
127
+ mmap_ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
128
+ if (mmap_ret == MAP_FAILED)
129
+ return T_EXIT_SKIP;
120
130
  intptr_t res = 0;
121
131
  *(uint32_t*)0x20000484 = 0;
122
132
  *(uint32_t*)0x20000488 = 0;
@@ -181,5 +191,5 @@ int main(int argc, char *argv[])
181
191
  "\xbd\x43\x7d\x16\x69\x3e\x05",
182
192
  19);
183
193
  ioctl(r[3], 0x5404, 0x20000080ul);
184
- return 0;
194
+ return T_EXIT_PASS;
185
195
  }
@@ -9,6 +9,7 @@
9
9
  #include <stdlib.h>
10
10
 
11
11
  #include "liburing.h"
12
+ #include "helpers.h"
12
13
 
13
14
  static int test(struct io_uring *ring, int expect_drops)
14
15
  {
@@ -35,6 +36,7 @@ static int test(struct io_uring *ring, int expect_drops)
35
36
  }
36
37
 
37
38
  io_uring_prep_read(sqe, 128, buf, sizeof(buf), 0);
39
+ sqe->ioprio = (short) -1;
38
40
  }
39
41
 
40
42
 
@@ -62,7 +64,7 @@ int main(int argc, char *argv[])
62
64
  int ret;
63
65
 
64
66
  if (argc > 1)
65
- return 0;
67
+ return T_EXIT_SKIP;
66
68
 
67
69
  ret = io_uring_queue_init(8, &ring, IORING_SETUP_SUBMIT_ALL);
68
70
  if (ret)
@@ -79,7 +81,7 @@ int main(int argc, char *argv[])
79
81
  ret = io_uring_queue_init(8, &ring, 0);
80
82
  if (ret) {
81
83
  fprintf(stderr, "ring setup failed\n");
82
- return 0;
84
+ return T_EXIT_FAIL;
83
85
  }
84
86
 
85
87
  ret = test(&ring, 1);
@@ -88,5 +90,5 @@ int main(int argc, char *argv[])
88
90
  return ret;
89
91
  }
90
92
 
91
- return 0;
93
+ return T_EXIT_PASS;
92
94
  }
@@ -33,6 +33,7 @@ static int get_file_fd(void)
33
33
  }
34
34
 
35
35
  buf = t_malloc(BLOCK);
36
+ memset(buf, 0, BLOCK);
36
37
  ret = write(fd, buf, BLOCK);
37
38
  if (ret != BLOCK) {
38
39
  if (ret < 0)
@@ -64,7 +65,7 @@ int main(int argc, char *argv[])
64
65
  int ret, fd;
65
66
 
66
67
  if (argc > 1)
67
- return 0;
68
+ return T_EXIT_SKIP;
68
69
 
69
70
  iov.iov_base = t_malloc(4096);
70
71
  iov.iov_len = 4096;
@@ -72,19 +73,19 @@ int main(int argc, char *argv[])
72
73
  ret = io_uring_queue_init(2, &ring, 0);
73
74
  if (ret) {
74
75
  printf("ring setup failed\n");
75
- return 1;
76
+ return T_EXIT_FAIL;
76
77
 
77
78
  }
78
79
 
79
80
  sqe = io_uring_get_sqe(&ring);
80
81
  if (!sqe) {
81
82
  printf("get sqe failed\n");
82
- return 1;
83
+ return T_EXIT_FAIL;
83
84
  }
84
85
 
85
86
  fd = get_file_fd();
86
87
  if (fd < 0)
87
- return 1;
88
+ return T_EXIT_FAIL;
88
89
 
89
90
  io_uring_prep_readv(sqe, fd, &iov, 1, 0);
90
91
  sqe->rw_flags = RWF_NOWAIT;
@@ -107,8 +108,8 @@ int main(int argc, char *argv[])
107
108
  }
108
109
 
109
110
  close(fd);
110
- return 0;
111
+ return T_EXIT_PASS;
111
112
  err:
112
113
  close(fd);
113
- return 1;
114
+ return T_EXIT_FAIL;
114
115
  }
@@ -17,14 +17,14 @@ int main(int argc, char *argv[])
17
17
  int ret;
18
18
 
19
19
  if (argc > 1)
20
- return 0;
20
+ return T_EXIT_SKIP;
21
21
 
22
22
  p.flags = IORING_SETUP_SQPOLL;
23
23
  p.sq_thread_idle = 100;
24
24
 
25
25
  ret = t_create_ring_params(1, &ring, &p);
26
26
  if (ret == T_SETUP_SKIP)
27
- return 0;
27
+ return T_EXIT_SKIP;
28
28
  else if (ret < 0)
29
29
  goto err;
30
30
 
@@ -39,7 +39,7 @@ int main(int argc, char *argv[])
39
39
  goto err;
40
40
  }
41
41
 
42
- return 0;
42
+ return T_EXIT_PASS;
43
43
  err:
44
- return 1;
44
+ return T_EXIT_FAIL;
45
45
  }