polyphony 0.93 → 0.95

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 (312) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +2 -2
  3. data/.gitignore +3 -3
  4. data/CHANGELOG.md +14 -0
  5. data/docs/api-reference/fiber.md +2 -2
  6. data/docs/api-reference/object.md +3 -3
  7. data/docs/main-concepts/exception-handling.md +2 -2
  8. data/examples/pipes/echo_server.rb +1 -1
  9. data/examples/pipes/http_server.rb +33 -0
  10. data/ext/polyphony/backend_common.c +53 -8
  11. data/ext/polyphony/backend_common.h +21 -13
  12. data/ext/polyphony/backend_io_uring.c +85 -147
  13. data/ext/polyphony/backend_libev.c +58 -89
  14. data/ext/polyphony/event.c +1 -1
  15. data/ext/polyphony/extconf.rb +7 -5
  16. data/ext/polyphony/fiber.c +5 -13
  17. data/ext/polyphony/io_extensions.c +68 -68
  18. data/ext/polyphony/pipe.c +1 -1
  19. data/ext/polyphony/polyphony.c +23 -23
  20. data/ext/polyphony/polyphony.h +0 -9
  21. data/ext/polyphony/polyphony_ext.c +1 -1
  22. data/ext/polyphony/queue.c +1 -1
  23. data/ext/polyphony/ring_buffer.c +1 -0
  24. data/ext/polyphony/socket_extensions.c +1 -1
  25. data/ext/polyphony/thread.c +1 -1
  26. data/lib/polyphony/extensions/enumerator.rb +16 -0
  27. data/lib/polyphony/extensions/socket.rb +2 -0
  28. data/lib/polyphony/extensions.rb +1 -0
  29. data/lib/polyphony/version.rb +1 -1
  30. data/polyphony.gemspec +2 -2
  31. data/test/test_backend.rb +5 -1
  32. data/test/test_enumerator.rb +46 -0
  33. data/test/test_global_api.rb +1 -1
  34. data/test/test_io.rb +241 -216
  35. data/test/test_socket.rb +1 -1
  36. data/test/test_thread_pool.rb +3 -3
  37. data/vendor/liburing/.github/workflows/build.yml +51 -5
  38. data/vendor/liburing/.github/workflows/shellcheck.yml +1 -1
  39. data/vendor/liburing/.gitignore +6 -123
  40. data/vendor/liburing/CHANGELOG +35 -0
  41. data/vendor/liburing/CITATION.cff +11 -0
  42. data/vendor/liburing/LICENSE +16 -3
  43. data/vendor/liburing/Makefile +3 -1
  44. data/vendor/liburing/Makefile.common +1 -0
  45. data/vendor/liburing/README +14 -2
  46. data/vendor/liburing/SECURITY.md +6 -0
  47. data/vendor/liburing/configure +16 -15
  48. data/vendor/liburing/examples/Makefile +4 -1
  49. data/vendor/liburing/examples/io_uring-udp.c +395 -0
  50. data/vendor/liburing/examples/poll-bench.c +101 -0
  51. data/vendor/liburing/examples/send-zerocopy.c +339 -0
  52. data/vendor/liburing/liburing.spec +1 -1
  53. data/vendor/liburing/man/io_uring.7 +38 -11
  54. data/vendor/liburing/man/io_uring_buf_ring_add.3 +53 -0
  55. data/vendor/liburing/man/io_uring_buf_ring_advance.3 +31 -0
  56. data/vendor/liburing/man/io_uring_buf_ring_cq_advance.3 +41 -0
  57. data/vendor/liburing/man/io_uring_buf_ring_init.3 +30 -0
  58. data/vendor/liburing/man/io_uring_buf_ring_mask.3 +27 -0
  59. data/vendor/liburing/man/io_uring_cq_advance.3 +29 -15
  60. data/vendor/liburing/man/io_uring_cq_has_overflow.3 +25 -0
  61. data/vendor/liburing/man/io_uring_cq_ready.3 +9 -8
  62. data/vendor/liburing/man/io_uring_cqe_get_data.3 +32 -13
  63. data/vendor/liburing/man/io_uring_cqe_get_data64.3 +1 -0
  64. data/vendor/liburing/man/io_uring_cqe_seen.3 +22 -12
  65. data/vendor/liburing/man/io_uring_enter.2 +249 -32
  66. data/vendor/liburing/man/io_uring_enter2.2 +1 -0
  67. data/vendor/liburing/man/io_uring_free_probe.3 +11 -8
  68. data/vendor/liburing/man/io_uring_get_events.3 +33 -0
  69. data/vendor/liburing/man/io_uring_get_probe.3 +9 -8
  70. data/vendor/liburing/man/io_uring_get_sqe.3 +29 -10
  71. data/vendor/liburing/man/io_uring_opcode_supported.3 +11 -10
  72. data/vendor/liburing/man/io_uring_peek_cqe.3 +38 -0
  73. data/vendor/liburing/man/io_uring_prep_accept.3 +197 -0
  74. data/vendor/liburing/man/io_uring_prep_accept_direct.3 +1 -0
  75. data/vendor/liburing/man/io_uring_prep_cancel.3 +118 -0
  76. data/vendor/liburing/man/io_uring_prep_cancel64.3 +1 -0
  77. data/vendor/liburing/man/io_uring_prep_close.3 +59 -0
  78. data/vendor/liburing/man/io_uring_prep_close_direct.3 +1 -0
  79. data/vendor/liburing/man/io_uring_prep_connect.3 +66 -0
  80. data/vendor/liburing/man/io_uring_prep_fadvise.3 +59 -0
  81. data/vendor/liburing/man/io_uring_prep_fallocate.3 +59 -0
  82. data/vendor/liburing/man/io_uring_prep_files_update.3 +92 -0
  83. data/vendor/liburing/man/io_uring_prep_fsync.3 +70 -0
  84. data/vendor/liburing/man/io_uring_prep_link.3 +1 -0
  85. data/vendor/liburing/man/io_uring_prep_linkat.3 +91 -0
  86. data/vendor/liburing/man/io_uring_prep_madvise.3 +56 -0
  87. data/vendor/liburing/man/io_uring_prep_mkdir.3 +1 -0
  88. data/vendor/liburing/man/io_uring_prep_mkdirat.3 +83 -0
  89. data/vendor/liburing/man/io_uring_prep_msg_ring.3 +39 -25
  90. data/vendor/liburing/man/io_uring_prep_multishot_accept.3 +1 -0
  91. data/vendor/liburing/man/io_uring_prep_multishot_accept_direct.3 +1 -0
  92. data/vendor/liburing/man/io_uring_prep_nop.3 +28 -0
  93. data/vendor/liburing/man/io_uring_prep_openat.3 +117 -0
  94. data/vendor/liburing/man/io_uring_prep_openat2.3 +117 -0
  95. data/vendor/liburing/man/io_uring_prep_openat2_direct.3 +1 -0
  96. data/vendor/liburing/man/io_uring_prep_openat_direct.3 +1 -0
  97. data/vendor/liburing/man/io_uring_prep_poll_add.3 +72 -0
  98. data/vendor/liburing/man/io_uring_prep_poll_multishot.3 +1 -0
  99. data/vendor/liburing/man/io_uring_prep_poll_remove.3 +55 -0
  100. data/vendor/liburing/man/io_uring_prep_poll_update.3 +89 -0
  101. data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +131 -0
  102. data/vendor/liburing/man/io_uring_prep_read.3 +33 -14
  103. data/vendor/liburing/man/io_uring_prep_read_fixed.3 +39 -21
  104. data/vendor/liburing/man/io_uring_prep_readv.3 +49 -15
  105. data/vendor/liburing/man/io_uring_prep_readv2.3 +49 -17
  106. data/vendor/liburing/man/io_uring_prep_recv.3 +105 -0
  107. data/vendor/liburing/man/io_uring_prep_recv_multishot.3 +1 -0
  108. data/vendor/liburing/man/io_uring_prep_recvmsg.3 +124 -0
  109. data/vendor/liburing/man/io_uring_prep_recvmsg_multishot.3 +1 -0
  110. data/vendor/liburing/man/io_uring_prep_remove_buffers.3 +52 -0
  111. data/vendor/liburing/man/io_uring_prep_rename.3 +1 -0
  112. data/vendor/liburing/man/io_uring_prep_renameat.3 +96 -0
  113. data/vendor/liburing/man/io_uring_prep_send.3 +57 -0
  114. data/vendor/liburing/man/io_uring_prep_send_zc.3 +64 -0
  115. data/vendor/liburing/man/io_uring_prep_sendmsg.3 +69 -0
  116. data/vendor/liburing/man/io_uring_prep_shutdown.3 +53 -0
  117. data/vendor/liburing/man/io_uring_prep_socket.3 +118 -0
  118. data/vendor/liburing/man/io_uring_prep_socket_direct.3 +1 -0
  119. data/vendor/liburing/man/io_uring_prep_socket_direct_alloc.3 +1 -0
  120. data/vendor/liburing/man/io_uring_prep_splice.3 +80 -0
  121. data/vendor/liburing/man/io_uring_prep_statx.3 +74 -0
  122. data/vendor/liburing/man/io_uring_prep_symlink.3 +1 -0
  123. data/vendor/liburing/man/io_uring_prep_symlinkat.3 +85 -0
  124. data/vendor/liburing/man/io_uring_prep_sync_file_range.3 +59 -0
  125. data/vendor/liburing/man/io_uring_prep_tee.3 +74 -0
  126. data/vendor/liburing/man/io_uring_prep_timeout.3 +95 -0
  127. data/vendor/liburing/man/io_uring_prep_timeout_remove.3 +1 -0
  128. data/vendor/liburing/man/io_uring_prep_timeout_update.3 +98 -0
  129. data/vendor/liburing/man/io_uring_prep_unlink.3 +1 -0
  130. data/vendor/liburing/man/io_uring_prep_unlinkat.3 +82 -0
  131. data/vendor/liburing/man/io_uring_prep_write.3 +32 -15
  132. data/vendor/liburing/man/io_uring_prep_write_fixed.3 +39 -21
  133. data/vendor/liburing/man/io_uring_prep_writev.3 +50 -16
  134. data/vendor/liburing/man/io_uring_prep_writev2.3 +50 -17
  135. data/vendor/liburing/man/io_uring_queue_exit.3 +3 -4
  136. data/vendor/liburing/man/io_uring_queue_init.3 +58 -13
  137. data/vendor/liburing/man/io_uring_queue_init_params.3 +1 -0
  138. data/vendor/liburing/man/io_uring_recvmsg_cmsg_firsthdr.3 +1 -0
  139. data/vendor/liburing/man/io_uring_recvmsg_cmsg_nexthdr.3 +1 -0
  140. data/vendor/liburing/man/io_uring_recvmsg_name.3 +1 -0
  141. data/vendor/liburing/man/io_uring_recvmsg_out.3 +78 -0
  142. data/vendor/liburing/man/io_uring_recvmsg_payload.3 +1 -0
  143. data/vendor/liburing/man/io_uring_recvmsg_payload_length.3 +1 -0
  144. data/vendor/liburing/man/io_uring_recvmsg_validate.3 +1 -0
  145. data/vendor/liburing/man/io_uring_register.2 +153 -13
  146. data/vendor/liburing/man/io_uring_register_buf_ring.3 +140 -0
  147. data/vendor/liburing/man/io_uring_register_buffers.3 +32 -12
  148. data/vendor/liburing/man/io_uring_register_eventfd.3 +51 -0
  149. data/vendor/liburing/man/io_uring_register_eventfd_async.3 +1 -0
  150. data/vendor/liburing/man/io_uring_register_file_alloc_range.3 +52 -0
  151. data/vendor/liburing/man/io_uring_register_files.3 +33 -11
  152. data/vendor/liburing/man/io_uring_register_files_sparse.3 +1 -0
  153. data/vendor/liburing/man/io_uring_register_iowq_aff.3 +61 -0
  154. data/vendor/liburing/man/io_uring_register_iowq_max_workers.3 +71 -0
  155. data/vendor/liburing/man/io_uring_register_ring_fd.3 +49 -0
  156. data/vendor/liburing/man/io_uring_register_sync_cancel.3 +71 -0
  157. data/vendor/liburing/man/io_uring_setup.2 +119 -13
  158. data/vendor/liburing/man/io_uring_sq_ready.3 +14 -8
  159. data/vendor/liburing/man/io_uring_sq_space_left.3 +9 -9
  160. data/vendor/liburing/man/io_uring_sqe_set_data.3 +29 -11
  161. data/vendor/liburing/man/io_uring_sqe_set_data64.3 +1 -0
  162. data/vendor/liburing/man/io_uring_sqe_set_flags.3 +38 -11
  163. data/vendor/liburing/man/io_uring_sqring_wait.3 +13 -9
  164. data/vendor/liburing/man/io_uring_submit.3 +29 -12
  165. data/vendor/liburing/man/io_uring_submit_and_get_events.3 +31 -0
  166. data/vendor/liburing/man/io_uring_submit_and_wait.3 +16 -12
  167. data/vendor/liburing/man/io_uring_submit_and_wait_timeout.3 +30 -23
  168. data/vendor/liburing/man/io_uring_unregister_buf_ring.3 +30 -0
  169. data/vendor/liburing/man/io_uring_unregister_buffers.3 +11 -10
  170. data/vendor/liburing/man/io_uring_unregister_eventfd.3 +1 -0
  171. data/vendor/liburing/man/io_uring_unregister_files.3 +11 -10
  172. data/vendor/liburing/man/io_uring_unregister_iowq_aff.3 +1 -0
  173. data/vendor/liburing/man/io_uring_unregister_ring_fd.3 +32 -0
  174. data/vendor/liburing/man/io_uring_wait_cqe.3 +19 -12
  175. data/vendor/liburing/man/io_uring_wait_cqe_nr.3 +21 -14
  176. data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +27 -13
  177. data/vendor/liburing/man/io_uring_wait_cqes.3 +24 -14
  178. data/vendor/liburing/src/Makefile +8 -7
  179. data/vendor/liburing/src/arch/aarch64/lib.h +48 -0
  180. data/vendor/liburing/src/arch/aarch64/syscall.h +0 -4
  181. data/vendor/liburing/src/arch/generic/lib.h +0 -4
  182. data/vendor/liburing/src/arch/generic/syscall.h +29 -16
  183. data/vendor/liburing/src/arch/syscall-defs.h +41 -14
  184. data/vendor/liburing/src/arch/x86/lib.h +0 -21
  185. data/vendor/liburing/src/arch/x86/syscall.h +146 -10
  186. data/vendor/liburing/src/include/liburing/io_uring.h +245 -5
  187. data/vendor/liburing/src/include/liburing.h +468 -35
  188. data/vendor/liburing/src/int_flags.h +1 -0
  189. data/vendor/liburing/src/lib.h +20 -16
  190. data/vendor/liburing/src/liburing.map +16 -0
  191. data/vendor/liburing/src/nolibc.c +1 -1
  192. data/vendor/liburing/src/queue.c +87 -55
  193. data/vendor/liburing/src/register.c +129 -53
  194. data/vendor/liburing/src/setup.c +65 -28
  195. data/vendor/liburing/src/syscall.c +14 -32
  196. data/vendor/liburing/src/syscall.h +12 -64
  197. data/vendor/liburing/test/{232c93d07b74-test.c → 232c93d07b74.c} +8 -9
  198. data/vendor/liburing/test/{35fa71a030ca-test.c → 35fa71a030ca.c} +4 -4
  199. data/vendor/liburing/test/{500f9fbadef8-test.c → 500f9fbadef8.c} +7 -7
  200. data/vendor/liburing/test/{7ad0e4b2f83c-test.c → 7ad0e4b2f83c.c} +8 -7
  201. data/vendor/liburing/test/{8a9973408177-test.c → 8a9973408177.c} +4 -3
  202. data/vendor/liburing/test/{917257daa0fe-test.c → 917257daa0fe.c} +3 -2
  203. data/vendor/liburing/test/Makefile +60 -62
  204. data/vendor/liburing/test/{a0908ae19763-test.c → a0908ae19763.c} +3 -2
  205. data/vendor/liburing/test/{a4c0b3decb33-test.c → a4c0b3decb33.c} +3 -2
  206. data/vendor/liburing/test/accept-link.c +5 -4
  207. data/vendor/liburing/test/accept-reuse.c +17 -16
  208. data/vendor/liburing/test/accept-test.c +14 -10
  209. data/vendor/liburing/test/accept.c +529 -107
  210. data/vendor/liburing/test/across-fork.c +7 -6
  211. data/vendor/liburing/test/{b19062a56726-test.c → b19062a56726.c} +3 -2
  212. data/vendor/liburing/test/{b5837bd5311d-test.c → b5837bd5311d.c} +10 -9
  213. data/vendor/liburing/test/buf-ring.c +420 -0
  214. data/vendor/liburing/test/{ce593a6c480a-test.c → ce593a6c480a.c} +15 -12
  215. data/vendor/liburing/test/connect.c +8 -7
  216. data/vendor/liburing/test/cq-full.c +5 -4
  217. data/vendor/liburing/test/cq-overflow.c +242 -12
  218. data/vendor/liburing/test/cq-peek-batch.c +5 -4
  219. data/vendor/liburing/test/cq-ready.c +5 -4
  220. data/vendor/liburing/test/cq-size.c +5 -4
  221. data/vendor/liburing/test/{d4ae271dfaae-test.c → d4ae271dfaae.c} +2 -2
  222. data/vendor/liburing/test/{d77a67ed5f27-test.c → d77a67ed5f27.c} +6 -6
  223. data/vendor/liburing/test/defer-taskrun.c +336 -0
  224. data/vendor/liburing/test/defer.c +26 -14
  225. data/vendor/liburing/test/double-poll-crash.c +15 -5
  226. data/vendor/liburing/test/drop-submit.c +5 -3
  227. data/vendor/liburing/test/{eeed8b54e0df-test.c → eeed8b54e0df.c} +7 -6
  228. data/vendor/liburing/test/empty-eownerdead.c +4 -4
  229. data/vendor/liburing/test/eventfd-disable.c +48 -20
  230. data/vendor/liburing/test/eventfd-reg.c +10 -9
  231. data/vendor/liburing/test/eventfd-ring.c +13 -12
  232. data/vendor/liburing/test/eventfd.c +13 -12
  233. data/vendor/liburing/test/exit-no-cleanup.c +1 -1
  234. data/vendor/liburing/test/fadvise.c +3 -3
  235. data/vendor/liburing/test/fallocate.c +16 -9
  236. data/vendor/liburing/test/{fc2a85cb02ef-test.c → fc2a85cb02ef.c} +4 -3
  237. data/vendor/liburing/test/fd-pass.c +187 -0
  238. data/vendor/liburing/test/file-register.c +302 -36
  239. data/vendor/liburing/test/file-update.c +62 -4
  240. data/vendor/liburing/test/file-verify.c +6 -2
  241. data/vendor/liburing/test/files-exit-hang-poll.c +11 -25
  242. data/vendor/liburing/test/files-exit-hang-timeout.c +13 -10
  243. data/vendor/liburing/test/fixed-buf-iter.c +115 -0
  244. data/vendor/liburing/test/fixed-link.c +10 -10
  245. data/vendor/liburing/test/fixed-reuse.c +160 -0
  246. data/vendor/liburing/test/fpos.c +6 -3
  247. data/vendor/liburing/test/fsync.c +3 -3
  248. data/vendor/liburing/test/hardlink.c +10 -6
  249. data/vendor/liburing/test/helpers.c +137 -4
  250. data/vendor/liburing/test/helpers.h +27 -0
  251. data/vendor/liburing/test/io-cancel.c +16 -11
  252. data/vendor/liburing/test/io_uring_enter.c +46 -81
  253. data/vendor/liburing/test/io_uring_passthrough.c +451 -0
  254. data/vendor/liburing/test/io_uring_register.c +59 -229
  255. data/vendor/liburing/test/io_uring_setup.c +24 -29
  256. data/vendor/liburing/test/iopoll-leak.c +85 -0
  257. data/vendor/liburing/test/iopoll.c +16 -9
  258. data/vendor/liburing/test/lfs-openat-write.c +3 -1
  259. data/vendor/liburing/test/link-timeout.c +4 -3
  260. data/vendor/liburing/test/link.c +8 -7
  261. data/vendor/liburing/test/madvise.c +2 -2
  262. data/vendor/liburing/test/mkdir.c +9 -5
  263. data/vendor/liburing/test/msg-ring.c +46 -20
  264. data/vendor/liburing/test/multicqes_drain.c +51 -12
  265. data/vendor/liburing/test/nolibc.c +60 -0
  266. data/vendor/liburing/test/nop.c +78 -16
  267. data/vendor/liburing/test/nvme.h +168 -0
  268. data/vendor/liburing/test/open-direct-link.c +188 -0
  269. data/vendor/liburing/test/open-direct-pick.c +180 -0
  270. data/vendor/liburing/test/openat2.c +3 -3
  271. data/vendor/liburing/test/poll-cancel-all.c +472 -0
  272. data/vendor/liburing/test/poll-link.c +9 -18
  273. data/vendor/liburing/test/poll-mshot-overflow.c +162 -0
  274. data/vendor/liburing/test/poll-mshot-update.c +83 -33
  275. data/vendor/liburing/test/pollfree.c +2 -2
  276. data/vendor/liburing/test/read-before-exit.c +112 -0
  277. data/vendor/liburing/test/read-write.c +83 -1
  278. data/vendor/liburing/test/recv-msgall-stream.c +398 -0
  279. data/vendor/liburing/test/recv-msgall.c +265 -0
  280. data/vendor/liburing/test/recv-multishot.c +505 -0
  281. data/vendor/liburing/test/rename.c +2 -5
  282. data/vendor/liburing/test/ring-leak.c +97 -0
  283. data/vendor/liburing/test/ringbuf-read.c +200 -0
  284. data/vendor/liburing/test/rsrc_tags.c +25 -13
  285. data/vendor/liburing/test/runtests-quiet.sh +11 -0
  286. data/vendor/liburing/test/runtests.sh +18 -20
  287. data/vendor/liburing/test/rw_merge_test.c +3 -2
  288. data/vendor/liburing/test/send-zerocopy.c +684 -0
  289. data/vendor/liburing/test/send_recv.c +49 -2
  290. data/vendor/liburing/test/send_recvmsg.c +165 -55
  291. data/vendor/liburing/test/shutdown.c +3 -4
  292. data/vendor/liburing/test/sigfd-deadlock.c +22 -8
  293. data/vendor/liburing/test/single-issuer.c +171 -0
  294. data/vendor/liburing/test/socket-rw-eagain.c +2 -12
  295. data/vendor/liburing/test/socket-rw-offset.c +2 -11
  296. data/vendor/liburing/test/socket-rw.c +2 -11
  297. data/vendor/liburing/test/socket.c +409 -0
  298. data/vendor/liburing/test/sq-poll-dup.c +1 -1
  299. data/vendor/liburing/test/sq-poll-share.c +1 -1
  300. data/vendor/liburing/test/statx.c +2 -2
  301. data/vendor/liburing/test/submit-and-wait.c +108 -0
  302. data/vendor/liburing/test/submit-link-fail.c +5 -3
  303. data/vendor/liburing/test/submit-reuse.c +0 -2
  304. data/vendor/liburing/test/sync-cancel.c +235 -0
  305. data/vendor/liburing/test/test.h +35 -0
  306. data/vendor/liburing/test/timeout-overflow.c +11 -11
  307. data/vendor/liburing/test/timeout.c +7 -7
  308. data/vendor/liburing/test/tty-write-dpoll.c +60 -0
  309. data/vendor/liburing/test/unlink.c +1 -1
  310. data/vendor/liburing/test/xattr.c +425 -0
  311. metadata +148 -26
  312. data/Gemfile.lock +0 -82
@@ -75,6 +75,20 @@ static int arm_poll(struct io_uring *ring, int off)
75
75
  return 0;
76
76
  }
77
77
 
78
+ static int submit_arm_poll(struct io_uring *ring, int off)
79
+ {
80
+ int ret;
81
+
82
+ ret = arm_poll(ring, off);
83
+ if (ret)
84
+ return ret;
85
+
86
+ ret = io_uring_submit(ring);
87
+ if (ret < 0)
88
+ return ret;
89
+ return ret == 1 ? 0 : -1;
90
+ }
91
+
78
92
  static int reap_polls(struct io_uring *ring)
79
93
  {
80
94
  struct io_uring_cqe *cqe;
@@ -106,6 +120,18 @@ static int reap_polls(struct io_uring *ring)
106
120
  off = cqe->user_data;
107
121
  if (off == 0x12345678)
108
122
  goto seen;
123
+ if (!(cqe->flags & IORING_CQE_F_MORE)) {
124
+ /* need to re-arm poll */
125
+ ret = submit_arm_poll(ring, off);
126
+ if (ret)
127
+ break;
128
+ if (cqe->res <= 0) {
129
+ /* retry this one */
130
+ i--;
131
+ goto seen;
132
+ }
133
+ }
134
+
109
135
  ret = read(p[off].fd[0], &c, 1);
110
136
  if (ret != 1) {
111
137
  if (ret == -1 && errno == EAGAIN)
@@ -187,52 +213,23 @@ static int arm_polls(struct io_uring *ring)
187
213
  return 0;
188
214
  }
189
215
 
190
- int main(int argc, char *argv[])
216
+ static int run(int cqe)
191
217
  {
192
218
  struct io_uring ring;
193
219
  struct io_uring_params params = { };
194
- struct rlimit rlim;
195
220
  pthread_t thread;
196
221
  int i, j, ret;
197
222
 
198
- if (argc > 1)
199
- return 0;
200
-
201
- ret = has_poll_update();
202
- if (ret < 0) {
203
- fprintf(stderr, "poll update check failed %i\n", ret);
204
- return -1;
205
- } else if (!ret) {
206
- fprintf(stderr, "no poll update, skip\n");
207
- return 0;
208
- }
209
-
210
- if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
211
- perror("getrlimit");
212
- goto err_noring;
213
- }
214
-
215
- if (rlim.rlim_cur < (2 * NFILES + 5)) {
216
- rlim.rlim_cur = (2 * NFILES + 5);
217
- rlim.rlim_max = rlim.rlim_cur;
218
- if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
219
- if (errno == EPERM)
220
- goto err_nofail;
221
- perror("setrlimit");
222
- goto err_noring;
223
- }
224
- }
225
-
226
223
  for (i = 0; i < NFILES; i++) {
227
224
  if (pipe(p[i].fd) < 0) {
228
225
  perror("pipe");
229
- goto err_noring;
226
+ return 1;
230
227
  }
231
228
  fcntl(p[i].fd[0], F_SETFL, O_NONBLOCK);
232
229
  }
233
230
 
234
231
  params.flags = IORING_SETUP_CQSIZE;
235
- params.cq_entries = 4096;
232
+ params.cq_entries = cqe;
236
233
  ret = io_uring_queue_init_params(RING_SIZE, &ring, &params);
237
234
  if (ret) {
238
235
  if (ret == -EINVAL) {
@@ -260,10 +257,63 @@ int main(int argc, char *argv[])
260
257
  }
261
258
 
262
259
  io_uring_queue_exit(&ring);
260
+ for (i = 0; i < NFILES; i++) {
261
+ close(p[i].fd[0]);
262
+ close(p[i].fd[1]);
263
+ }
263
264
  return 0;
264
265
  err:
265
266
  io_uring_queue_exit(&ring);
266
- err_noring:
267
+ return 1;
268
+ }
269
+
270
+ int main(int argc, char *argv[])
271
+ {
272
+ struct rlimit rlim;
273
+ int ret;
274
+
275
+ if (argc > 1)
276
+ return 0;
277
+
278
+ ret = has_poll_update();
279
+ if (ret < 0) {
280
+ fprintf(stderr, "poll update check failed %i\n", ret);
281
+ return -1;
282
+ } else if (!ret) {
283
+ fprintf(stderr, "no poll update, skip\n");
284
+ return 0;
285
+ }
286
+
287
+ if (getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
288
+ perror("getrlimit");
289
+ goto err;
290
+ }
291
+
292
+ if (rlim.rlim_cur < (2 * NFILES + 5)) {
293
+ rlim.rlim_cur = (2 * NFILES + 5);
294
+ rlim.rlim_max = rlim.rlim_cur;
295
+ if (setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
296
+ if (errno == EPERM)
297
+ goto err_nofail;
298
+ perror("setrlimit");
299
+ goto err;
300
+ }
301
+ }
302
+
303
+ ret = run(1024);
304
+ if (ret) {
305
+ fprintf(stderr, "run(1024) failed\n");
306
+ goto err;
307
+ }
308
+
309
+ ret = run(8192);
310
+ if (ret) {
311
+ fprintf(stderr, "run(8192) failed\n");
312
+ goto err;
313
+ }
314
+
315
+ return 0;
316
+ err:
267
317
  fprintf(stderr, "poll-many failed\n");
268
318
  return 1;
269
319
  err_nofail:
@@ -406,10 +406,10 @@ int main(int argc, char *argv[])
406
406
  ret = mmap((void *)0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
407
407
  if (ret == MAP_FAILED)
408
408
  return 0;
409
- mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
409
+ ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
410
410
  if (ret == MAP_FAILED)
411
411
  return 0;
412
- mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
412
+ ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
413
413
  if (ret == MAP_FAILED)
414
414
  return 0;
415
415
  loop();
@@ -0,0 +1,112 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test if issuing IO from thread and immediately exiting will
4
+ * proceed correctly.
5
+ *
6
+ * Original test case from: https://github.com/axboe/liburing/issues/582
7
+ */
8
+ #include <unistd.h>
9
+ #include <pthread.h>
10
+ #include <sys/timerfd.h>
11
+ #include <string.h>
12
+ #include <stdio.h>
13
+
14
+ #include "liburing.h"
15
+ #include "helpers.h"
16
+
17
+ struct data {
18
+ struct io_uring *ring;
19
+ int timer_fd1;
20
+ int timer_fd2;
21
+ uint64_t buf1;
22
+ uint64_t buf2;
23
+ };
24
+
25
+ void *submit(void *data)
26
+ {
27
+ struct io_uring_sqe *sqe;
28
+ struct data *d = data;
29
+ int ret;
30
+
31
+ sqe = io_uring_get_sqe(d->ring);
32
+ io_uring_prep_read(sqe, d->timer_fd1, &d->buf1, sizeof(d->buf1), 0);
33
+
34
+ sqe = io_uring_get_sqe(d->ring);
35
+ io_uring_prep_read(sqe, d->timer_fd2, &d->buf2, sizeof(d->buf2), 0);
36
+
37
+ ret = io_uring_submit(d->ring);
38
+ if (ret != 2)
39
+ return (void *) (uintptr_t) 1;
40
+
41
+ /* Exit suddenly. */
42
+ return NULL;
43
+ }
44
+
45
+ static int test(int flags)
46
+ {
47
+ struct io_uring_params params = { .flags = flags, };
48
+ struct io_uring ring;
49
+ struct data d = { .ring = &ring, };
50
+ pthread_t thread;
51
+ void *res;
52
+ int ret;
53
+
54
+ ret = t_create_ring_params(8, &ring, &params);
55
+ if (ret == T_SETUP_SKIP)
56
+ return 0;
57
+ else if (ret != T_SETUP_OK)
58
+ return 1;
59
+
60
+ d.timer_fd1 = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
61
+ if (d.timer_fd1 < 0) {
62
+ perror("timerfd_create");
63
+ return 1;
64
+ }
65
+ d.timer_fd2 = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
66
+ if (d.timer_fd2 < 0) {
67
+ perror("timerfd_create");
68
+ return 1;
69
+ }
70
+
71
+ pthread_create(&thread, NULL, submit, &d);
72
+ pthread_join(thread, &res);
73
+
74
+ /** Wait for completions and do stuff ... **/
75
+
76
+ io_uring_queue_exit(&ring);
77
+
78
+ close(d.timer_fd1);
79
+ close(d.timer_fd2);
80
+ return !!res;
81
+ }
82
+
83
+ int main(int argc, char *argv[])
84
+ {
85
+ int ret, i;
86
+
87
+ for (i = 0; i < 1000; i++) {
88
+ ret = test(0);
89
+ if (ret) {
90
+ fprintf(stderr, "Test failed\n");
91
+ return ret;
92
+ }
93
+ }
94
+
95
+ for (i = 0; i < 1000; i++) {
96
+ ret = test(IORING_SETUP_IOPOLL);
97
+ if (ret) {
98
+ fprintf(stderr, "Test IOPOLL failed\n");
99
+ return ret;
100
+ }
101
+ }
102
+
103
+ for (i = 0; i < 100; i++) {
104
+ ret = test(IORING_SETUP_SQPOLL);
105
+ if (ret) {
106
+ fprintf(stderr, "Test SQPOLL failed\n");
107
+ return ret;
108
+ }
109
+ }
110
+
111
+ return 0;
112
+ }
@@ -462,6 +462,79 @@ static int provide_buffers_iovec(struct io_uring *ring, int bgid)
462
462
  return 0;
463
463
  }
464
464
 
465
+ static int test_buf_select_pipe(void)
466
+ {
467
+ struct io_uring_sqe *sqe;
468
+ struct io_uring_cqe *cqe;
469
+ struct io_uring ring;
470
+ int ret, i;
471
+ int fds[2];
472
+
473
+ if (no_buf_select)
474
+ return 0;
475
+
476
+ ret = io_uring_queue_init(64, &ring, 0);
477
+ if (ret) {
478
+ fprintf(stderr, "ring create failed: %d\n", ret);
479
+ return 1;
480
+ }
481
+
482
+ ret = provide_buffers_iovec(&ring, 0);
483
+ if (ret) {
484
+ fprintf(stderr, "provide buffers failed: %d\n", ret);
485
+ return 1;
486
+ }
487
+
488
+ ret = pipe(fds);
489
+ if (ret) {
490
+ fprintf(stderr, "pipe failed: %d\n", ret);
491
+ return 1;
492
+ }
493
+
494
+ for (i = 0; i < 5; i++) {
495
+ sqe = io_uring_get_sqe(&ring);
496
+ io_uring_prep_read(sqe, fds[0], NULL, 1 /* max read 1 per go */, -1);
497
+ sqe->flags |= IOSQE_BUFFER_SELECT;
498
+ sqe->buf_group = 0;
499
+ }
500
+ io_uring_submit(&ring);
501
+
502
+ ret = write(fds[1], "01234", 5);
503
+ if (ret != 5) {
504
+ fprintf(stderr, "pipe write failed %d\n", ret);
505
+ return 1;
506
+ }
507
+
508
+ for (i = 0; i < 5; i++) {
509
+ const char *buff;
510
+
511
+ if (io_uring_wait_cqe(&ring, &cqe)) {
512
+ fprintf(stderr, "bad wait %d\n", i);
513
+ return 1;
514
+ }
515
+ if (cqe->res != 1) {
516
+ fprintf(stderr, "expected read %d\n", cqe->res);
517
+ return 1;
518
+ }
519
+ if (!(cqe->flags & IORING_CQE_F_BUFFER)) {
520
+ fprintf(stderr, "no buffer %d\n", cqe->res);
521
+ return 1;
522
+ }
523
+ buff = vecs[cqe->flags >> 16].iov_base;
524
+ if (*buff != '0' + i) {
525
+ fprintf(stderr, "%d: expected %c, got %c\n", i, '0' + i, *buff);
526
+ return 1;
527
+ }
528
+ io_uring_cqe_seen(&ring, cqe);
529
+ }
530
+
531
+
532
+ close(fds[0]);
533
+ close(fds[1]);
534
+ io_uring_queue_exit(&ring);
535
+ return 0;
536
+ }
537
+
465
538
  static int test_buf_select(const char *filename, int nonvec)
466
539
  {
467
540
  struct io_uring_probe *p;
@@ -686,6 +759,7 @@ static int test_write_efbig(void)
686
759
  goto err;
687
760
  }
688
761
  io_uring_prep_writev(sqe, fd, &vecs[i], 1, off);
762
+ io_uring_sqe_set_data64(sqe, i);
689
763
  off += BS;
690
764
  }
691
765
 
@@ -701,7 +775,7 @@ static int test_write_efbig(void)
701
775
  fprintf(stderr, "wait_cqe=%d\n", ret);
702
776
  goto err;
703
777
  }
704
- if (i < 16) {
778
+ if (cqe->user_data < 16) {
705
779
  if (cqe->res != BS) {
706
780
  fprintf(stderr, "bad write: %d\n", cqe->res);
707
781
  goto err;
@@ -746,6 +820,8 @@ int main(int argc, char *argv[])
746
820
  t_create_file(fname, FILE_SIZE);
747
821
  }
748
822
 
823
+ signal(SIGXFSZ, SIG_IGN);
824
+
749
825
  vecs = t_create_buffers(BUFFERS, BS);
750
826
 
751
827
  /* if we don't have nonvec read, skip testing that */
@@ -791,6 +867,12 @@ int main(int argc, char *argv[])
791
867
  goto err;
792
868
  }
793
869
 
870
+ ret = test_buf_select_pipe();
871
+ if (ret) {
872
+ fprintf(stderr, "test_buf_select_pipe failed\n");
873
+ goto err;
874
+ }
875
+
794
876
  ret = test_eventfd_read();
795
877
  if (ret) {
796
878
  fprintf(stderr, "test_eventfd_read failed\n");