polyphony 0.94 → 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 (306) 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/ext/polyphony/backend_common.c +3 -3
  9. data/ext/polyphony/backend_io_uring.c +18 -16
  10. data/ext/polyphony/event.c +1 -1
  11. data/ext/polyphony/extconf.rb +5 -3
  12. data/ext/polyphony/fiber.c +5 -13
  13. data/ext/polyphony/io_extensions.c +1 -1
  14. data/ext/polyphony/pipe.c +1 -1
  15. data/ext/polyphony/polyphony.c +1 -1
  16. data/ext/polyphony/polyphony_ext.c +1 -1
  17. data/ext/polyphony/queue.c +1 -1
  18. data/ext/polyphony/ring_buffer.c +1 -0
  19. data/ext/polyphony/socket_extensions.c +1 -1
  20. data/ext/polyphony/thread.c +1 -1
  21. data/lib/polyphony/extensions/enumerator.rb +16 -0
  22. data/lib/polyphony/extensions/socket.rb +2 -0
  23. data/lib/polyphony/extensions.rb +1 -0
  24. data/lib/polyphony/version.rb +1 -1
  25. data/polyphony.gemspec +2 -2
  26. data/test/test_backend.rb +5 -1
  27. data/test/test_enumerator.rb +46 -0
  28. data/test/test_io.rb +241 -216
  29. data/test/test_socket.rb +1 -1
  30. data/test/test_thread_pool.rb +3 -3
  31. data/vendor/liburing/.github/workflows/build.yml +51 -5
  32. data/vendor/liburing/.github/workflows/shellcheck.yml +1 -1
  33. data/vendor/liburing/.gitignore +6 -123
  34. data/vendor/liburing/CHANGELOG +35 -0
  35. data/vendor/liburing/CITATION.cff +11 -0
  36. data/vendor/liburing/LICENSE +16 -3
  37. data/vendor/liburing/Makefile +3 -1
  38. data/vendor/liburing/Makefile.common +1 -0
  39. data/vendor/liburing/README +14 -2
  40. data/vendor/liburing/SECURITY.md +6 -0
  41. data/vendor/liburing/configure +16 -15
  42. data/vendor/liburing/examples/Makefile +4 -1
  43. data/vendor/liburing/examples/io_uring-udp.c +395 -0
  44. data/vendor/liburing/examples/poll-bench.c +101 -0
  45. data/vendor/liburing/examples/send-zerocopy.c +339 -0
  46. data/vendor/liburing/liburing.spec +1 -1
  47. data/vendor/liburing/man/io_uring.7 +38 -11
  48. data/vendor/liburing/man/io_uring_buf_ring_add.3 +53 -0
  49. data/vendor/liburing/man/io_uring_buf_ring_advance.3 +31 -0
  50. data/vendor/liburing/man/io_uring_buf_ring_cq_advance.3 +41 -0
  51. data/vendor/liburing/man/io_uring_buf_ring_init.3 +30 -0
  52. data/vendor/liburing/man/io_uring_buf_ring_mask.3 +27 -0
  53. data/vendor/liburing/man/io_uring_cq_advance.3 +29 -15
  54. data/vendor/liburing/man/io_uring_cq_has_overflow.3 +25 -0
  55. data/vendor/liburing/man/io_uring_cq_ready.3 +9 -8
  56. data/vendor/liburing/man/io_uring_cqe_get_data.3 +32 -13
  57. data/vendor/liburing/man/io_uring_cqe_get_data64.3 +1 -0
  58. data/vendor/liburing/man/io_uring_cqe_seen.3 +22 -12
  59. data/vendor/liburing/man/io_uring_enter.2 +249 -32
  60. data/vendor/liburing/man/io_uring_enter2.2 +1 -0
  61. data/vendor/liburing/man/io_uring_free_probe.3 +11 -8
  62. data/vendor/liburing/man/io_uring_get_events.3 +33 -0
  63. data/vendor/liburing/man/io_uring_get_probe.3 +9 -8
  64. data/vendor/liburing/man/io_uring_get_sqe.3 +29 -10
  65. data/vendor/liburing/man/io_uring_opcode_supported.3 +11 -10
  66. data/vendor/liburing/man/io_uring_peek_cqe.3 +38 -0
  67. data/vendor/liburing/man/io_uring_prep_accept.3 +197 -0
  68. data/vendor/liburing/man/io_uring_prep_accept_direct.3 +1 -0
  69. data/vendor/liburing/man/io_uring_prep_cancel.3 +118 -0
  70. data/vendor/liburing/man/io_uring_prep_cancel64.3 +1 -0
  71. data/vendor/liburing/man/io_uring_prep_close.3 +59 -0
  72. data/vendor/liburing/man/io_uring_prep_close_direct.3 +1 -0
  73. data/vendor/liburing/man/io_uring_prep_connect.3 +66 -0
  74. data/vendor/liburing/man/io_uring_prep_fadvise.3 +59 -0
  75. data/vendor/liburing/man/io_uring_prep_fallocate.3 +59 -0
  76. data/vendor/liburing/man/io_uring_prep_files_update.3 +92 -0
  77. data/vendor/liburing/man/io_uring_prep_fsync.3 +70 -0
  78. data/vendor/liburing/man/io_uring_prep_link.3 +1 -0
  79. data/vendor/liburing/man/io_uring_prep_linkat.3 +91 -0
  80. data/vendor/liburing/man/io_uring_prep_madvise.3 +56 -0
  81. data/vendor/liburing/man/io_uring_prep_mkdir.3 +1 -0
  82. data/vendor/liburing/man/io_uring_prep_mkdirat.3 +83 -0
  83. data/vendor/liburing/man/io_uring_prep_msg_ring.3 +39 -25
  84. data/vendor/liburing/man/io_uring_prep_multishot_accept.3 +1 -0
  85. data/vendor/liburing/man/io_uring_prep_multishot_accept_direct.3 +1 -0
  86. data/vendor/liburing/man/io_uring_prep_nop.3 +28 -0
  87. data/vendor/liburing/man/io_uring_prep_openat.3 +117 -0
  88. data/vendor/liburing/man/io_uring_prep_openat2.3 +117 -0
  89. data/vendor/liburing/man/io_uring_prep_openat2_direct.3 +1 -0
  90. data/vendor/liburing/man/io_uring_prep_openat_direct.3 +1 -0
  91. data/vendor/liburing/man/io_uring_prep_poll_add.3 +72 -0
  92. data/vendor/liburing/man/io_uring_prep_poll_multishot.3 +1 -0
  93. data/vendor/liburing/man/io_uring_prep_poll_remove.3 +55 -0
  94. data/vendor/liburing/man/io_uring_prep_poll_update.3 +89 -0
  95. data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +131 -0
  96. data/vendor/liburing/man/io_uring_prep_read.3 +33 -14
  97. data/vendor/liburing/man/io_uring_prep_read_fixed.3 +39 -21
  98. data/vendor/liburing/man/io_uring_prep_readv.3 +49 -15
  99. data/vendor/liburing/man/io_uring_prep_readv2.3 +49 -17
  100. data/vendor/liburing/man/io_uring_prep_recv.3 +105 -0
  101. data/vendor/liburing/man/io_uring_prep_recv_multishot.3 +1 -0
  102. data/vendor/liburing/man/io_uring_prep_recvmsg.3 +124 -0
  103. data/vendor/liburing/man/io_uring_prep_recvmsg_multishot.3 +1 -0
  104. data/vendor/liburing/man/io_uring_prep_remove_buffers.3 +52 -0
  105. data/vendor/liburing/man/io_uring_prep_rename.3 +1 -0
  106. data/vendor/liburing/man/io_uring_prep_renameat.3 +96 -0
  107. data/vendor/liburing/man/io_uring_prep_send.3 +57 -0
  108. data/vendor/liburing/man/io_uring_prep_send_zc.3 +64 -0
  109. data/vendor/liburing/man/io_uring_prep_sendmsg.3 +69 -0
  110. data/vendor/liburing/man/io_uring_prep_shutdown.3 +53 -0
  111. data/vendor/liburing/man/io_uring_prep_socket.3 +118 -0
  112. data/vendor/liburing/man/io_uring_prep_socket_direct.3 +1 -0
  113. data/vendor/liburing/man/io_uring_prep_socket_direct_alloc.3 +1 -0
  114. data/vendor/liburing/man/io_uring_prep_splice.3 +80 -0
  115. data/vendor/liburing/man/io_uring_prep_statx.3 +74 -0
  116. data/vendor/liburing/man/io_uring_prep_symlink.3 +1 -0
  117. data/vendor/liburing/man/io_uring_prep_symlinkat.3 +85 -0
  118. data/vendor/liburing/man/io_uring_prep_sync_file_range.3 +59 -0
  119. data/vendor/liburing/man/io_uring_prep_tee.3 +74 -0
  120. data/vendor/liburing/man/io_uring_prep_timeout.3 +95 -0
  121. data/vendor/liburing/man/io_uring_prep_timeout_remove.3 +1 -0
  122. data/vendor/liburing/man/io_uring_prep_timeout_update.3 +98 -0
  123. data/vendor/liburing/man/io_uring_prep_unlink.3 +1 -0
  124. data/vendor/liburing/man/io_uring_prep_unlinkat.3 +82 -0
  125. data/vendor/liburing/man/io_uring_prep_write.3 +32 -15
  126. data/vendor/liburing/man/io_uring_prep_write_fixed.3 +39 -21
  127. data/vendor/liburing/man/io_uring_prep_writev.3 +50 -16
  128. data/vendor/liburing/man/io_uring_prep_writev2.3 +50 -17
  129. data/vendor/liburing/man/io_uring_queue_exit.3 +3 -4
  130. data/vendor/liburing/man/io_uring_queue_init.3 +58 -13
  131. data/vendor/liburing/man/io_uring_queue_init_params.3 +1 -0
  132. data/vendor/liburing/man/io_uring_recvmsg_cmsg_firsthdr.3 +1 -0
  133. data/vendor/liburing/man/io_uring_recvmsg_cmsg_nexthdr.3 +1 -0
  134. data/vendor/liburing/man/io_uring_recvmsg_name.3 +1 -0
  135. data/vendor/liburing/man/io_uring_recvmsg_out.3 +78 -0
  136. data/vendor/liburing/man/io_uring_recvmsg_payload.3 +1 -0
  137. data/vendor/liburing/man/io_uring_recvmsg_payload_length.3 +1 -0
  138. data/vendor/liburing/man/io_uring_recvmsg_validate.3 +1 -0
  139. data/vendor/liburing/man/io_uring_register.2 +153 -13
  140. data/vendor/liburing/man/io_uring_register_buf_ring.3 +140 -0
  141. data/vendor/liburing/man/io_uring_register_buffers.3 +32 -12
  142. data/vendor/liburing/man/io_uring_register_eventfd.3 +51 -0
  143. data/vendor/liburing/man/io_uring_register_eventfd_async.3 +1 -0
  144. data/vendor/liburing/man/io_uring_register_file_alloc_range.3 +52 -0
  145. data/vendor/liburing/man/io_uring_register_files.3 +33 -11
  146. data/vendor/liburing/man/io_uring_register_files_sparse.3 +1 -0
  147. data/vendor/liburing/man/io_uring_register_iowq_aff.3 +61 -0
  148. data/vendor/liburing/man/io_uring_register_iowq_max_workers.3 +71 -0
  149. data/vendor/liburing/man/io_uring_register_ring_fd.3 +49 -0
  150. data/vendor/liburing/man/io_uring_register_sync_cancel.3 +71 -0
  151. data/vendor/liburing/man/io_uring_setup.2 +119 -13
  152. data/vendor/liburing/man/io_uring_sq_ready.3 +14 -8
  153. data/vendor/liburing/man/io_uring_sq_space_left.3 +9 -9
  154. data/vendor/liburing/man/io_uring_sqe_set_data.3 +29 -11
  155. data/vendor/liburing/man/io_uring_sqe_set_data64.3 +1 -0
  156. data/vendor/liburing/man/io_uring_sqe_set_flags.3 +38 -11
  157. data/vendor/liburing/man/io_uring_sqring_wait.3 +13 -9
  158. data/vendor/liburing/man/io_uring_submit.3 +29 -12
  159. data/vendor/liburing/man/io_uring_submit_and_get_events.3 +31 -0
  160. data/vendor/liburing/man/io_uring_submit_and_wait.3 +16 -12
  161. data/vendor/liburing/man/io_uring_submit_and_wait_timeout.3 +30 -23
  162. data/vendor/liburing/man/io_uring_unregister_buf_ring.3 +30 -0
  163. data/vendor/liburing/man/io_uring_unregister_buffers.3 +11 -10
  164. data/vendor/liburing/man/io_uring_unregister_eventfd.3 +1 -0
  165. data/vendor/liburing/man/io_uring_unregister_files.3 +11 -10
  166. data/vendor/liburing/man/io_uring_unregister_iowq_aff.3 +1 -0
  167. data/vendor/liburing/man/io_uring_unregister_ring_fd.3 +32 -0
  168. data/vendor/liburing/man/io_uring_wait_cqe.3 +19 -12
  169. data/vendor/liburing/man/io_uring_wait_cqe_nr.3 +21 -14
  170. data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +27 -13
  171. data/vendor/liburing/man/io_uring_wait_cqes.3 +24 -14
  172. data/vendor/liburing/src/Makefile +8 -7
  173. data/vendor/liburing/src/arch/aarch64/lib.h +48 -0
  174. data/vendor/liburing/src/arch/aarch64/syscall.h +0 -4
  175. data/vendor/liburing/src/arch/generic/lib.h +0 -4
  176. data/vendor/liburing/src/arch/generic/syscall.h +29 -16
  177. data/vendor/liburing/src/arch/syscall-defs.h +41 -14
  178. data/vendor/liburing/src/arch/x86/lib.h +0 -21
  179. data/vendor/liburing/src/arch/x86/syscall.h +146 -10
  180. data/vendor/liburing/src/include/liburing/io_uring.h +245 -5
  181. data/vendor/liburing/src/include/liburing.h +468 -35
  182. data/vendor/liburing/src/int_flags.h +1 -0
  183. data/vendor/liburing/src/lib.h +20 -16
  184. data/vendor/liburing/src/liburing.map +16 -0
  185. data/vendor/liburing/src/nolibc.c +1 -1
  186. data/vendor/liburing/src/queue.c +87 -55
  187. data/vendor/liburing/src/register.c +129 -53
  188. data/vendor/liburing/src/setup.c +65 -28
  189. data/vendor/liburing/src/syscall.c +14 -32
  190. data/vendor/liburing/src/syscall.h +12 -64
  191. data/vendor/liburing/test/{232c93d07b74-test.c → 232c93d07b74.c} +8 -9
  192. data/vendor/liburing/test/{35fa71a030ca-test.c → 35fa71a030ca.c} +4 -4
  193. data/vendor/liburing/test/{500f9fbadef8-test.c → 500f9fbadef8.c} +7 -7
  194. data/vendor/liburing/test/{7ad0e4b2f83c-test.c → 7ad0e4b2f83c.c} +8 -7
  195. data/vendor/liburing/test/{8a9973408177-test.c → 8a9973408177.c} +4 -3
  196. data/vendor/liburing/test/{917257daa0fe-test.c → 917257daa0fe.c} +3 -2
  197. data/vendor/liburing/test/Makefile +60 -62
  198. data/vendor/liburing/test/{a0908ae19763-test.c → a0908ae19763.c} +3 -2
  199. data/vendor/liburing/test/{a4c0b3decb33-test.c → a4c0b3decb33.c} +3 -2
  200. data/vendor/liburing/test/accept-link.c +5 -4
  201. data/vendor/liburing/test/accept-reuse.c +17 -16
  202. data/vendor/liburing/test/accept-test.c +14 -10
  203. data/vendor/liburing/test/accept.c +529 -107
  204. data/vendor/liburing/test/across-fork.c +7 -6
  205. data/vendor/liburing/test/{b19062a56726-test.c → b19062a56726.c} +3 -2
  206. data/vendor/liburing/test/{b5837bd5311d-test.c → b5837bd5311d.c} +10 -9
  207. data/vendor/liburing/test/buf-ring.c +420 -0
  208. data/vendor/liburing/test/{ce593a6c480a-test.c → ce593a6c480a.c} +15 -12
  209. data/vendor/liburing/test/connect.c +8 -7
  210. data/vendor/liburing/test/cq-full.c +5 -4
  211. data/vendor/liburing/test/cq-overflow.c +242 -12
  212. data/vendor/liburing/test/cq-peek-batch.c +5 -4
  213. data/vendor/liburing/test/cq-ready.c +5 -4
  214. data/vendor/liburing/test/cq-size.c +5 -4
  215. data/vendor/liburing/test/{d4ae271dfaae-test.c → d4ae271dfaae.c} +2 -2
  216. data/vendor/liburing/test/{d77a67ed5f27-test.c → d77a67ed5f27.c} +6 -6
  217. data/vendor/liburing/test/defer-taskrun.c +336 -0
  218. data/vendor/liburing/test/defer.c +26 -14
  219. data/vendor/liburing/test/double-poll-crash.c +15 -5
  220. data/vendor/liburing/test/drop-submit.c +5 -3
  221. data/vendor/liburing/test/{eeed8b54e0df-test.c → eeed8b54e0df.c} +7 -6
  222. data/vendor/liburing/test/empty-eownerdead.c +4 -4
  223. data/vendor/liburing/test/eventfd-disable.c +48 -20
  224. data/vendor/liburing/test/eventfd-reg.c +10 -9
  225. data/vendor/liburing/test/eventfd-ring.c +13 -12
  226. data/vendor/liburing/test/eventfd.c +13 -12
  227. data/vendor/liburing/test/exit-no-cleanup.c +1 -1
  228. data/vendor/liburing/test/fadvise.c +3 -3
  229. data/vendor/liburing/test/fallocate.c +16 -9
  230. data/vendor/liburing/test/{fc2a85cb02ef-test.c → fc2a85cb02ef.c} +4 -3
  231. data/vendor/liburing/test/fd-pass.c +187 -0
  232. data/vendor/liburing/test/file-register.c +302 -36
  233. data/vendor/liburing/test/file-update.c +62 -4
  234. data/vendor/liburing/test/file-verify.c +6 -2
  235. data/vendor/liburing/test/files-exit-hang-poll.c +11 -25
  236. data/vendor/liburing/test/files-exit-hang-timeout.c +13 -10
  237. data/vendor/liburing/test/fixed-buf-iter.c +115 -0
  238. data/vendor/liburing/test/fixed-link.c +10 -10
  239. data/vendor/liburing/test/fixed-reuse.c +160 -0
  240. data/vendor/liburing/test/fpos.c +6 -3
  241. data/vendor/liburing/test/fsync.c +3 -3
  242. data/vendor/liburing/test/hardlink.c +10 -6
  243. data/vendor/liburing/test/helpers.c +137 -4
  244. data/vendor/liburing/test/helpers.h +27 -0
  245. data/vendor/liburing/test/io-cancel.c +16 -11
  246. data/vendor/liburing/test/io_uring_enter.c +46 -81
  247. data/vendor/liburing/test/io_uring_passthrough.c +451 -0
  248. data/vendor/liburing/test/io_uring_register.c +59 -229
  249. data/vendor/liburing/test/io_uring_setup.c +24 -29
  250. data/vendor/liburing/test/iopoll-leak.c +85 -0
  251. data/vendor/liburing/test/iopoll.c +16 -9
  252. data/vendor/liburing/test/lfs-openat-write.c +3 -1
  253. data/vendor/liburing/test/link-timeout.c +4 -3
  254. data/vendor/liburing/test/link.c +8 -7
  255. data/vendor/liburing/test/madvise.c +2 -2
  256. data/vendor/liburing/test/mkdir.c +9 -5
  257. data/vendor/liburing/test/msg-ring.c +46 -20
  258. data/vendor/liburing/test/multicqes_drain.c +51 -12
  259. data/vendor/liburing/test/nolibc.c +60 -0
  260. data/vendor/liburing/test/nop.c +78 -16
  261. data/vendor/liburing/test/nvme.h +168 -0
  262. data/vendor/liburing/test/open-direct-link.c +188 -0
  263. data/vendor/liburing/test/open-direct-pick.c +180 -0
  264. data/vendor/liburing/test/openat2.c +3 -3
  265. data/vendor/liburing/test/poll-cancel-all.c +472 -0
  266. data/vendor/liburing/test/poll-link.c +9 -18
  267. data/vendor/liburing/test/poll-mshot-overflow.c +162 -0
  268. data/vendor/liburing/test/poll-mshot-update.c +83 -33
  269. data/vendor/liburing/test/pollfree.c +2 -2
  270. data/vendor/liburing/test/read-before-exit.c +112 -0
  271. data/vendor/liburing/test/read-write.c +83 -1
  272. data/vendor/liburing/test/recv-msgall-stream.c +398 -0
  273. data/vendor/liburing/test/recv-msgall.c +265 -0
  274. data/vendor/liburing/test/recv-multishot.c +505 -0
  275. data/vendor/liburing/test/rename.c +2 -5
  276. data/vendor/liburing/test/ring-leak.c +97 -0
  277. data/vendor/liburing/test/ringbuf-read.c +200 -0
  278. data/vendor/liburing/test/rsrc_tags.c +25 -13
  279. data/vendor/liburing/test/runtests-quiet.sh +11 -0
  280. data/vendor/liburing/test/runtests.sh +18 -20
  281. data/vendor/liburing/test/rw_merge_test.c +3 -2
  282. data/vendor/liburing/test/send-zerocopy.c +684 -0
  283. data/vendor/liburing/test/send_recv.c +49 -2
  284. data/vendor/liburing/test/send_recvmsg.c +165 -55
  285. data/vendor/liburing/test/shutdown.c +3 -4
  286. data/vendor/liburing/test/sigfd-deadlock.c +22 -8
  287. data/vendor/liburing/test/single-issuer.c +171 -0
  288. data/vendor/liburing/test/socket-rw-eagain.c +2 -12
  289. data/vendor/liburing/test/socket-rw-offset.c +2 -11
  290. data/vendor/liburing/test/socket-rw.c +2 -11
  291. data/vendor/liburing/test/socket.c +409 -0
  292. data/vendor/liburing/test/sq-poll-dup.c +1 -1
  293. data/vendor/liburing/test/sq-poll-share.c +1 -1
  294. data/vendor/liburing/test/statx.c +2 -2
  295. data/vendor/liburing/test/submit-and-wait.c +108 -0
  296. data/vendor/liburing/test/submit-link-fail.c +5 -3
  297. data/vendor/liburing/test/submit-reuse.c +0 -2
  298. data/vendor/liburing/test/sync-cancel.c +235 -0
  299. data/vendor/liburing/test/test.h +35 -0
  300. data/vendor/liburing/test/timeout-overflow.c +11 -11
  301. data/vendor/liburing/test/timeout.c +7 -7
  302. data/vendor/liburing/test/tty-write-dpoll.c +60 -0
  303. data/vendor/liburing/test/unlink.c +1 -1
  304. data/vendor/liburing/test/xattr.c +425 -0
  305. metadata +143 -22
  306. data/Gemfile.lock +0 -78
@@ -7,6 +7,7 @@
7
7
  #include <stdlib.h>
8
8
  #include <stdint.h>
9
9
  #include <assert.h>
10
+ #include <limits.h>
10
11
 
11
12
  #include <errno.h>
12
13
  #include <fcntl.h>
@@ -22,13 +23,43 @@
22
23
  #include "helpers.h"
23
24
  #include "liburing.h"
24
25
 
26
+ #define MAX_FDS 32
27
+ #define NOP_USER_DATA (1LLU << 50)
28
+ #define INITIAL_USER_DATA 1000
29
+
25
30
  static int no_accept;
31
+ static int no_accept_multi;
26
32
 
27
33
  struct data {
28
34
  char buf[128];
29
35
  struct iovec iov;
30
36
  };
31
37
 
38
+ struct accept_test_args {
39
+ int accept_should_error;
40
+ bool fixed;
41
+ bool nonblock;
42
+ bool queue_accept_before_connect;
43
+ bool multishot;
44
+ int extra_loops;
45
+ bool overflow;
46
+ };
47
+
48
+ static void close_fds(int fds[], int nr)
49
+ {
50
+ int i;
51
+
52
+ for (i = 0; i < nr; i++)
53
+ close(fds[i]);
54
+ }
55
+
56
+ static void close_sock_fds(int s_fd[], int c_fd[], int nr, bool fixed)
57
+ {
58
+ if (!fixed)
59
+ close_fds(s_fd, nr);
60
+ close_fds(c_fd, nr);
61
+ }
62
+
32
63
  static void queue_send(struct io_uring *ring, int fd)
33
64
  {
34
65
  struct io_uring_sqe *sqe;
@@ -59,30 +90,83 @@ static void queue_recv(struct io_uring *ring, int fd, bool fixed)
59
90
  sqe->flags |= IOSQE_FIXED_FILE;
60
91
  }
61
92
 
62
- static int accept_conn(struct io_uring *ring, int fd, bool fixed)
93
+ static void queue_accept_multishot(struct io_uring *ring, int fd,
94
+ int idx, bool fixed)
63
95
  {
64
- struct io_uring_sqe *sqe;
65
- struct io_uring_cqe *cqe;
66
- int ret, fixed_idx = 0;
96
+ struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
97
+ int ret;
67
98
 
68
- sqe = io_uring_get_sqe(ring);
69
- if (!fixed)
70
- io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
99
+ if (fixed)
100
+ io_uring_prep_multishot_accept_direct(sqe, fd,
101
+ NULL, NULL,
102
+ 0);
71
103
  else
72
- io_uring_prep_accept_direct(sqe, fd, NULL, NULL, 0, fixed_idx);
104
+ io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0);
73
105
 
106
+ io_uring_sqe_set_data64(sqe, idx);
74
107
  ret = io_uring_submit(ring);
75
108
  assert(ret != -1);
109
+ }
76
110
 
77
- ret = io_uring_wait_cqe(ring, &cqe);
78
- assert(!ret);
79
- ret = cqe->res;
80
- io_uring_cqe_seen(ring, cqe);
111
+ static void queue_accept_conn(struct io_uring *ring, int fd,
112
+ struct accept_test_args args)
113
+ {
114
+ struct io_uring_sqe *sqe;
115
+ int ret;
116
+ int fixed_idx = args.fixed ? 0 : -1;
117
+ int count = 1 + args.extra_loops;
118
+
119
+ if (args.multishot) {
120
+ queue_accept_multishot(ring, fd, INITIAL_USER_DATA, args.fixed);
121
+ return;
122
+ }
81
123
 
82
- if (fixed) {
124
+ while (count--) {
125
+ sqe = io_uring_get_sqe(ring);
126
+ if (fixed_idx < 0) {
127
+ io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
128
+ } else {
129
+ io_uring_prep_accept_direct(sqe, fd, NULL, NULL,
130
+ 0, fixed_idx);
131
+ }
132
+ ret = io_uring_submit(ring);
133
+ assert(ret != -1);
134
+ }
135
+ }
136
+
137
+ static int accept_conn(struct io_uring *ring, int fixed_idx, int *multishot, int fd)
138
+ {
139
+ struct io_uring_cqe *pcqe;
140
+ struct io_uring_cqe cqe;
141
+ int ret;
142
+
143
+ do {
144
+ ret = io_uring_wait_cqe(ring, &pcqe);
145
+ assert(!ret);
146
+ cqe = *pcqe;
147
+ io_uring_cqe_seen(ring, pcqe);
148
+ } while (cqe.user_data == NOP_USER_DATA);
149
+
150
+ if (*multishot) {
151
+ if (!(cqe.flags & IORING_CQE_F_MORE)) {
152
+ (*multishot)++;
153
+ queue_accept_multishot(ring, fd, *multishot, fixed_idx == 0);
154
+ } else {
155
+ if (cqe.user_data != *multishot) {
156
+ fprintf(stderr, "received multishot after told done!\n");
157
+ return -ECANCELED;
158
+ }
159
+ }
160
+ }
161
+
162
+ ret = cqe.res;
163
+
164
+ if (fixed_idx >= 0) {
83
165
  if (ret > 0) {
84
- close(ret);
85
- return -EINVAL;
166
+ if (!multishot) {
167
+ close(ret);
168
+ return -EINVAL;
169
+ }
86
170
  } else if (!ret) {
87
171
  ret = fixed_idx;
88
172
  }
@@ -90,11 +174,13 @@ static int accept_conn(struct io_uring *ring, int fd, bool fixed)
90
174
  return ret;
91
175
  }
92
176
 
93
- static int start_accept_listen(struct sockaddr_in *addr, int port_off)
177
+ static int start_accept_listen(struct sockaddr_in *addr, int port_off,
178
+ int extra_flags)
94
179
  {
95
180
  int fd, ret;
96
181
 
97
- fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
182
+ fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC | extra_flags,
183
+ IPPROTO_TCP);
98
184
 
99
185
  int32_t val = 1;
100
186
  ret = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
@@ -108,69 +194,148 @@ static int start_accept_listen(struct sockaddr_in *addr, int port_off)
108
194
  addr = &laddr;
109
195
 
110
196
  addr->sin_family = AF_INET;
111
- addr->sin_port = htons(0x1235 + port_off);
112
197
  addr->sin_addr.s_addr = inet_addr("127.0.0.1");
113
-
114
- ret = bind(fd, (struct sockaddr*)addr, sizeof(*addr));
115
- assert(ret != -1);
198
+ assert(!t_bind_ephemeral_port(fd, addr));
116
199
  ret = listen(fd, 128);
117
200
  assert(ret != -1);
118
201
 
119
202
  return fd;
120
203
  }
121
204
 
122
- static int test(struct io_uring *ring, int accept_should_error, bool fixed)
205
+ static int set_client_fd(struct sockaddr_in *addr)
123
206
  {
124
- struct io_uring_cqe *cqe;
125
- struct sockaddr_in addr;
126
- uint32_t head, count = 0;
127
- int ret, p_fd[2], done = 0;
128
-
129
- int32_t val, recv_s0 = start_accept_listen(&addr, 0);
207
+ int32_t val;
208
+ int fd, ret;
130
209
 
131
- p_fd[1] = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
210
+ fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
132
211
 
133
212
  val = 1;
134
- ret = setsockopt(p_fd[1], IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
213
+ ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
135
214
  assert(ret != -1);
136
215
 
137
- int32_t flags = fcntl(p_fd[1], F_GETFL, 0);
216
+ int32_t flags = fcntl(fd, F_GETFL, 0);
138
217
  assert(flags != -1);
139
218
 
140
219
  flags |= O_NONBLOCK;
141
- ret = fcntl(p_fd[1], F_SETFL, flags);
220
+ ret = fcntl(fd, F_SETFL, flags);
142
221
  assert(ret != -1);
143
222
 
144
- ret = connect(p_fd[1], (struct sockaddr*)&addr, sizeof(addr));
223
+ ret = connect(fd, (struct sockaddr *)addr, sizeof(*addr));
145
224
  assert(ret == -1);
146
225
 
147
- flags = fcntl(p_fd[1], F_GETFL, 0);
226
+ flags = fcntl(fd, F_GETFL, 0);
148
227
  assert(flags != -1);
149
228
 
150
229
  flags &= ~O_NONBLOCK;
151
- ret = fcntl(p_fd[1], F_SETFL, flags);
230
+ ret = fcntl(fd, F_SETFL, flags);
152
231
  assert(ret != -1);
153
232
 
154
- p_fd[0] = accept_conn(ring, recv_s0, fixed);
155
- if (p_fd[0] == -EINVAL) {
156
- if (accept_should_error)
233
+ return fd;
234
+ }
235
+
236
+ static void cause_overflow(struct io_uring *ring)
237
+ {
238
+ int i, ret;
239
+
240
+ for (i = 0; i < ring->cq.ring_entries; i++) {
241
+ struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
242
+
243
+ io_uring_prep_nop(sqe);
244
+ io_uring_sqe_set_data64(sqe, NOP_USER_DATA);
245
+ ret = io_uring_submit(ring);
246
+ assert(ret != -1);
247
+ }
248
+
249
+ }
250
+
251
+ static void clear_overflow(struct io_uring *ring)
252
+ {
253
+ struct io_uring_cqe *cqe;
254
+
255
+ while (!io_uring_peek_cqe(ring, &cqe)) {
256
+ if (cqe->user_data != NOP_USER_DATA)
257
+ break;
258
+ io_uring_cqe_seen(ring, cqe);
259
+ }
260
+ }
261
+
262
+ static int test_loop(struct io_uring *ring,
263
+ struct accept_test_args args,
264
+ int recv_s0,
265
+ struct sockaddr_in *addr)
266
+ {
267
+ struct io_uring_cqe *cqe;
268
+ uint32_t head, count = 0;
269
+ int i, ret, s_fd[MAX_FDS], c_fd[MAX_FDS], done = 0;
270
+ bool fixed = args.fixed;
271
+ bool multishot = args.multishot;
272
+ uint32_t multishot_mask = 0;
273
+ int nr_fds = multishot ? MAX_FDS : 1;
274
+ int multishot_idx = multishot ? INITIAL_USER_DATA : 0;
275
+
276
+ if (args.overflow)
277
+ cause_overflow(ring);
278
+
279
+ for (i = 0; i < nr_fds; i++) {
280
+ c_fd[i] = set_client_fd(addr);
281
+ if (args.overflow && i == nr_fds / 2)
282
+ clear_overflow(ring);
283
+ }
284
+
285
+ if (!args.queue_accept_before_connect)
286
+ queue_accept_conn(ring, recv_s0, args);
287
+
288
+ for (i = 0; i < nr_fds; i++) {
289
+ s_fd[i] = accept_conn(ring, fixed ? 0 : -1, &multishot_idx, recv_s0);
290
+ if (s_fd[i] == -EINVAL) {
291
+ if (args.accept_should_error)
292
+ goto out;
293
+ fprintf(stdout,
294
+ "%s %s Accept not supported, skipping\n",
295
+ fixed ? "Fixed" : "",
296
+ multishot ? "Multishot" : "");
297
+ if (multishot)
298
+ no_accept_multi = 1;
299
+ else
300
+ no_accept = 1;
157
301
  goto out;
158
- if (fixed)
159
- fprintf(stdout, "Fixed accept not supported, skipping\n");
160
- else
161
- fprintf(stdout, "Accept not supported, skipping\n");
162
- no_accept = 1;
302
+ } else if (s_fd[i] < 0) {
303
+ if (args.accept_should_error &&
304
+ (s_fd[i] == -EBADF || s_fd[i] == -EINVAL))
305
+ goto out;
306
+ fprintf(stderr, "%s %s Accept[%d] got %d\n",
307
+ fixed ? "Fixed" : "",
308
+ multishot ? "Multishot" : "",
309
+ i, s_fd[i]);
310
+ goto err;
311
+ }
312
+
313
+ if (multishot && fixed) {
314
+ if (s_fd[i] >= MAX_FDS) {
315
+ fprintf(stderr,
316
+ "Fixed Multishot Accept[%d] got outbound index: %d\n",
317
+ i, s_fd[i]);
318
+ goto err;
319
+ }
320
+ /*
321
+ * for fixed multishot accept test, the file slots
322
+ * allocated are [0, 32), this means we finally end up
323
+ * with each bit of a u32 being 1.
324
+ */
325
+ multishot_mask |= (1U << s_fd[i]);
326
+ }
327
+ }
328
+
329
+ if (multishot) {
330
+ if (fixed && (~multishot_mask != 0U)) {
331
+ fprintf(stderr, "Fixed Multishot Accept misses events\n");
332
+ goto err;
333
+ }
163
334
  goto out;
164
- } else if (p_fd[0] < 0) {
165
- if (accept_should_error &&
166
- (p_fd[0] == -EBADF || p_fd[0] == -EINVAL))
167
- goto out;
168
- fprintf(stderr, "Accept got %d\n", p_fd[0]);
169
- goto err;
170
335
  }
171
336
 
172
- queue_send(ring, p_fd[1]);
173
- queue_recv(ring, p_fd[0], fixed);
337
+ queue_send(ring, c_fd[0]);
338
+ queue_recv(ring, s_fd[0], fixed);
174
339
 
175
340
  ret = io_uring_submit_and_wait(ring, 2);
176
341
  assert(ret != -1);
@@ -194,19 +359,32 @@ static int test(struct io_uring *ring, int accept_should_error, bool fixed)
194
359
  }
195
360
 
196
361
  out:
197
- if (!fixed)
198
- close(p_fd[0]);
199
- close(p_fd[1]);
200
- close(recv_s0);
362
+ close_sock_fds(s_fd, c_fd, nr_fds, fixed);
201
363
  return 0;
202
364
  err:
203
- if (!fixed)
204
- close(p_fd[0]);
205
- close(p_fd[1]);
206
- close(recv_s0);
365
+ close_sock_fds(s_fd, c_fd, nr_fds, fixed);
207
366
  return 1;
208
367
  }
209
368
 
369
+ static int test(struct io_uring *ring, struct accept_test_args args)
370
+ {
371
+ struct sockaddr_in addr;
372
+ int ret = 0;
373
+ int loop;
374
+ int32_t recv_s0 = start_accept_listen(&addr, 0,
375
+ args.nonblock ? O_NONBLOCK : 0);
376
+ if (args.queue_accept_before_connect)
377
+ queue_accept_conn(ring, recv_s0, args);
378
+ for (loop = 0; loop < 1 + args.extra_loops; loop++) {
379
+ ret = test_loop(ring, args, recv_s0, &addr);
380
+ if (ret)
381
+ break;
382
+ }
383
+
384
+ close(recv_s0);
385
+ return ret;
386
+ }
387
+
210
388
  static void sig_alrm(int sig)
211
389
  {
212
390
  exit(0);
@@ -222,7 +400,7 @@ static int test_accept_pending_on_exit(void)
222
400
  ret = io_uring_queue_init(32, &m_io_uring, 0);
223
401
  assert(ret >= 0);
224
402
 
225
- fd = start_accept_listen(NULL, 0);
403
+ fd = start_accept_listen(NULL, 0, 0);
226
404
 
227
405
  sqe = io_uring_get_sqe(&m_io_uring);
228
406
  io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
@@ -239,10 +417,17 @@ static int test_accept_pending_on_exit(void)
239
417
  return 0;
240
418
  }
241
419
 
420
+ struct test_accept_many_args {
421
+ unsigned int usecs;
422
+ bool nonblock;
423
+ bool single_sock;
424
+ bool close_fds;
425
+ };
426
+
242
427
  /*
243
428
  * Test issue many accepts and see if we handle cancellation on exit
244
429
  */
245
- static int test_accept_many(unsigned nr, unsigned usecs)
430
+ static int test_accept_many(struct test_accept_many_args args)
246
431
  {
247
432
  struct io_uring m_io_uring;
248
433
  struct io_uring_cqe *cqe;
@@ -250,6 +435,8 @@ static int test_accept_many(unsigned nr, unsigned usecs)
250
435
  unsigned long cur_lim;
251
436
  struct rlimit rlim;
252
437
  int *fds, i, ret;
438
+ unsigned int nr = 128;
439
+ int nr_socks = args.single_sock ? 1 : nr;
253
440
 
254
441
  if (getrlimit(RLIMIT_NPROC, &rlim) < 0) {
255
442
  perror("getrlimit");
@@ -267,31 +454,39 @@ static int test_accept_many(unsigned nr, unsigned usecs)
267
454
  ret = io_uring_queue_init(2 * nr, &m_io_uring, 0);
268
455
  assert(ret >= 0);
269
456
 
270
- fds = t_calloc(nr, sizeof(int));
457
+ fds = t_calloc(nr_socks, sizeof(int));
271
458
 
272
- for (i = 0; i < nr; i++)
273
- fds[i] = start_accept_listen(NULL, i);
459
+ for (i = 0; i < nr_socks; i++)
460
+ fds[i] = start_accept_listen(NULL, i,
461
+ args.nonblock ? O_NONBLOCK : 0);
274
462
 
275
463
  for (i = 0; i < nr; i++) {
464
+ int sock_idx = args.single_sock ? 0 : i;
276
465
  sqe = io_uring_get_sqe(&m_io_uring);
277
- io_uring_prep_accept(sqe, fds[i], NULL, NULL, 0);
466
+ io_uring_prep_accept(sqe, fds[sock_idx], NULL, NULL, 0);
278
467
  sqe->user_data = 1 + i;
279
468
  ret = io_uring_submit(&m_io_uring);
280
469
  assert(ret == 1);
281
470
  }
282
471
 
283
- if (usecs)
284
- usleep(usecs);
472
+ if (args.usecs)
473
+ usleep(args.usecs);
474
+
475
+ if (args.close_fds)
476
+ for (i = 0; i < nr_socks; i++)
477
+ close(fds[i]);
285
478
 
286
479
  for (i = 0; i < nr; i++) {
287
480
  if (io_uring_peek_cqe(&m_io_uring, &cqe))
288
481
  break;
289
482
  if (cqe->res != -ECANCELED) {
290
- fprintf(stderr, "Expected cqe to be cancelled\n");
291
- goto err;
483
+ fprintf(stderr, "Expected cqe to be cancelled %d\n", cqe->res);
484
+ ret = 1;
485
+ goto out;
292
486
  }
293
487
  io_uring_cqe_seen(&m_io_uring, cqe);
294
488
  }
489
+ ret = 0;
295
490
  out:
296
491
  rlim.rlim_cur = cur_lim;
297
492
  if (setrlimit(RLIMIT_NPROC, &rlim) < 0) {
@@ -301,40 +496,46 @@ out:
301
496
 
302
497
  free(fds);
303
498
  io_uring_queue_exit(&m_io_uring);
304
- return 0;
305
- err:
306
- ret = 1;
307
- goto out;
499
+ return ret;
308
500
  }
309
501
 
310
- static int test_accept_cancel(unsigned usecs)
502
+ static int test_accept_cancel(unsigned usecs, unsigned int nr, bool multishot)
311
503
  {
312
504
  struct io_uring m_io_uring;
313
505
  struct io_uring_cqe *cqe;
314
506
  struct io_uring_sqe *sqe;
315
507
  int fd, i, ret;
316
508
 
509
+ if (multishot && no_accept_multi)
510
+ return T_EXIT_SKIP;
511
+
317
512
  ret = io_uring_queue_init(32, &m_io_uring, 0);
318
513
  assert(ret >= 0);
319
514
 
320
- fd = start_accept_listen(NULL, 0);
515
+ fd = start_accept_listen(NULL, 0, 0);
321
516
 
322
- sqe = io_uring_get_sqe(&m_io_uring);
323
- io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
324
- sqe->user_data = 1;
325
- ret = io_uring_submit(&m_io_uring);
326
- assert(ret == 1);
517
+ for (i = 1; i <= nr; i++) {
518
+ sqe = io_uring_get_sqe(&m_io_uring);
519
+ if (!multishot)
520
+ io_uring_prep_accept(sqe, fd, NULL, NULL, 0);
521
+ else
522
+ io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0);
523
+ sqe->user_data = i;
524
+ ret = io_uring_submit(&m_io_uring);
525
+ assert(ret == 1);
526
+ }
327
527
 
328
528
  if (usecs)
329
529
  usleep(usecs);
330
530
 
331
- sqe = io_uring_get_sqe(&m_io_uring);
332
- io_uring_prep_cancel(sqe, 1, 0);
333
- sqe->user_data = 2;
334
- ret = io_uring_submit(&m_io_uring);
335
- assert(ret == 1);
336
-
337
- for (i = 0; i < 2; i++) {
531
+ for (i = 1; i <= nr; i++) {
532
+ sqe = io_uring_get_sqe(&m_io_uring);
533
+ io_uring_prep_cancel64(sqe, i, 0);
534
+ sqe->user_data = nr + i;
535
+ ret = io_uring_submit(&m_io_uring);
536
+ assert(ret == 1);
537
+ }
538
+ for (i = 0; i < nr * 2; i++) {
338
539
  ret = io_uring_wait_cqe(&m_io_uring, &cqe);
339
540
  assert(!ret);
340
541
  /*
@@ -347,12 +548,15 @@ static int test_accept_cancel(unsigned usecs)
347
548
  * should get '-EALREADY' for the cancel request and
348
549
  * '-EINTR' for the accept request.
349
550
  */
350
- if (cqe->user_data == 1) {
551
+ if (cqe->user_data == 0) {
552
+ fprintf(stderr, "unexpected 0 user data\n");
553
+ goto err;
554
+ } else if (cqe->user_data <= nr) {
351
555
  if (cqe->res != -EINTR && cqe->res != -ECANCELED) {
352
556
  fprintf(stderr, "Cancelled accept got %d\n", cqe->res);
353
557
  goto err;
354
558
  }
355
- } else if (cqe->user_data == 2) {
559
+ } else if (cqe->user_data <= nr * 2) {
356
560
  if (cqe->res != -EALREADY && cqe->res != 0) {
357
561
  fprintf(stderr, "Cancel got %d\n", cqe->res);
358
562
  goto err;
@@ -362,20 +566,101 @@ static int test_accept_cancel(unsigned usecs)
362
566
  }
363
567
 
364
568
  io_uring_queue_exit(&m_io_uring);
569
+ close(fd);
570
+ return 0;
571
+ err:
572
+ io_uring_queue_exit(&m_io_uring);
573
+ close(fd);
574
+ return 1;
575
+ }
576
+
577
+ static int test_accept(int count, bool before)
578
+ {
579
+ struct io_uring m_io_uring;
580
+ int ret;
581
+ struct accept_test_args args = {
582
+ .queue_accept_before_connect = before,
583
+ .extra_loops = count - 1
584
+ };
585
+
586
+ ret = io_uring_queue_init(32, &m_io_uring, 0);
587
+ assert(ret >= 0);
588
+ ret = test(&m_io_uring, args);
589
+ io_uring_queue_exit(&m_io_uring);
590
+ return ret;
591
+ }
592
+
593
+ static int test_multishot_accept(int count, bool before, bool overflow)
594
+ {
595
+ struct io_uring m_io_uring;
596
+ int ret;
597
+ struct accept_test_args args = {
598
+ .queue_accept_before_connect = before,
599
+ .multishot = true,
600
+ .extra_loops = count - 1,
601
+ .overflow = overflow
602
+ };
603
+
604
+ if (no_accept_multi)
605
+ return T_EXIT_SKIP;
606
+
607
+ ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
608
+ assert(ret >= 0);
609
+ ret = test(&m_io_uring, args);
610
+ io_uring_queue_exit(&m_io_uring);
611
+ return ret;
612
+ }
613
+
614
+ static int test_accept_multishot_wrong_arg()
615
+ {
616
+ struct io_uring m_io_uring;
617
+ struct io_uring_cqe *cqe;
618
+ struct io_uring_sqe *sqe;
619
+ int fd, ret;
620
+
621
+ ret = io_uring_queue_init(4, &m_io_uring, 0);
622
+ assert(ret >= 0);
623
+
624
+ fd = start_accept_listen(NULL, 0, 0);
625
+
626
+ sqe = io_uring_get_sqe(&m_io_uring);
627
+ io_uring_prep_multishot_accept_direct(sqe, fd, NULL, NULL, 0);
628
+ sqe->file_index = 1;
629
+ ret = io_uring_submit(&m_io_uring);
630
+ assert(ret == 1);
631
+
632
+ ret = io_uring_wait_cqe(&m_io_uring, &cqe);
633
+ assert(!ret);
634
+ if (cqe->res != -EINVAL) {
635
+ fprintf(stderr, "file index should be IORING_FILE_INDEX_ALLOC \
636
+ if its accept in multishot direct mode\n");
637
+ goto err;
638
+ }
639
+ io_uring_cqe_seen(&m_io_uring, cqe);
640
+
641
+ io_uring_queue_exit(&m_io_uring);
642
+ close(fd);
365
643
  return 0;
366
644
  err:
367
645
  io_uring_queue_exit(&m_io_uring);
646
+ close(fd);
368
647
  return 1;
369
648
  }
370
649
 
371
- static int test_accept(void)
650
+
651
+ static int test_accept_nonblock(bool queue_before_connect, int count)
372
652
  {
373
653
  struct io_uring m_io_uring;
374
654
  int ret;
655
+ struct accept_test_args args = {
656
+ .nonblock = true,
657
+ .queue_accept_before_connect = queue_before_connect,
658
+ .extra_loops = count - 1
659
+ };
375
660
 
376
661
  ret = io_uring_queue_init(32, &m_io_uring, 0);
377
662
  assert(ret >= 0);
378
- ret = test(&m_io_uring, 0, false);
663
+ ret = test(&m_io_uring, args);
379
664
  io_uring_queue_exit(&m_io_uring);
380
665
  return ret;
381
666
  }
@@ -384,12 +669,37 @@ static int test_accept_fixed(void)
384
669
  {
385
670
  struct io_uring m_io_uring;
386
671
  int ret, fd = -1;
672
+ struct accept_test_args args = {
673
+ .fixed = true
674
+ };
387
675
 
388
676
  ret = io_uring_queue_init(32, &m_io_uring, 0);
389
677
  assert(ret >= 0);
390
678
  ret = io_uring_register_files(&m_io_uring, &fd, 1);
391
679
  assert(ret == 0);
392
- ret = test(&m_io_uring, 0, true);
680
+ ret = test(&m_io_uring, args);
681
+ io_uring_queue_exit(&m_io_uring);
682
+ return ret;
683
+ }
684
+
685
+ static int test_multishot_fixed_accept(void)
686
+ {
687
+ struct io_uring m_io_uring;
688
+ int ret, fd[MAX_FDS];
689
+ struct accept_test_args args = {
690
+ .fixed = true,
691
+ .multishot = true
692
+ };
693
+
694
+ if (no_accept_multi)
695
+ return T_EXIT_SKIP;
696
+
697
+ memset(fd, -1, sizeof(fd));
698
+ ret = io_uring_queue_init(MAX_FDS + 10, &m_io_uring, 0);
699
+ assert(ret >= 0);
700
+ ret = io_uring_register_files(&m_io_uring, fd, MAX_FDS);
701
+ assert(ret == 0);
702
+ ret = test(&m_io_uring, args);
393
703
  io_uring_queue_exit(&m_io_uring);
394
704
  return ret;
395
705
  }
@@ -398,7 +708,8 @@ static int test_accept_sqpoll(void)
398
708
  {
399
709
  struct io_uring m_io_uring;
400
710
  struct io_uring_params p = { };
401
- int ret, should_fail;
711
+ int ret;
712
+ struct accept_test_args args = { };
402
713
 
403
714
  p.flags = IORING_SETUP_SQPOLL;
404
715
  ret = t_create_ring_params(32, &m_io_uring, &p);
@@ -407,11 +718,11 @@ static int test_accept_sqpoll(void)
407
718
  else if (ret < 0)
408
719
  return ret;
409
720
 
410
- should_fail = 1;
721
+ args.accept_should_error = 1;
411
722
  if (p.features & IORING_FEAT_SQPOLL_NONFIXED)
412
- should_fail = 0;
723
+ args.accept_should_error = 0;
413
724
 
414
- ret = test(&m_io_uring, should_fail, false);
725
+ ret = test(&m_io_uring, args);
415
726
  io_uring_queue_exit(&m_io_uring);
416
727
  return ret;
417
728
  }
@@ -421,15 +732,44 @@ int main(int argc, char *argv[])
421
732
  int ret;
422
733
 
423
734
  if (argc > 1)
424
- return 0;
425
-
426
- ret = test_accept();
735
+ return T_EXIT_SKIP;
736
+ ret = test_accept(1, false);
427
737
  if (ret) {
428
738
  fprintf(stderr, "test_accept failed\n");
429
739
  return ret;
430
740
  }
431
741
  if (no_accept)
432
- return 0;
742
+ return T_EXIT_SKIP;
743
+
744
+ ret = test_accept(2, false);
745
+ if (ret) {
746
+ fprintf(stderr, "test_accept(2) failed\n");
747
+ return ret;
748
+ }
749
+
750
+ ret = test_accept(2, true);
751
+ if (ret) {
752
+ fprintf(stderr, "test_accept(2, true) failed\n");
753
+ return ret;
754
+ }
755
+
756
+ ret = test_accept_nonblock(false, 1);
757
+ if (ret) {
758
+ fprintf(stderr, "test_accept_nonblock failed\n");
759
+ return ret;
760
+ }
761
+
762
+ ret = test_accept_nonblock(true, 1);
763
+ if (ret) {
764
+ fprintf(stderr, "test_accept_nonblock(before, 1) failed\n");
765
+ return ret;
766
+ }
767
+
768
+ ret = test_accept_nonblock(true, 3);
769
+ if (ret) {
770
+ fprintf(stderr, "test_accept_nonblock(before,3) failed\n");
771
+ return ret;
772
+ }
433
773
 
434
774
  ret = test_accept_fixed();
435
775
  if (ret) {
@@ -437,41 +777,123 @@ int main(int argc, char *argv[])
437
777
  return ret;
438
778
  }
439
779
 
780
+ ret = test_multishot_fixed_accept();
781
+ if (ret) {
782
+ fprintf(stderr, "test_multishot_fixed_accept failed\n");
783
+ return ret;
784
+ }
785
+
786
+ ret = test_accept_multishot_wrong_arg();
787
+ if (ret) {
788
+ fprintf(stderr, "test_accept_multishot_wrong_arg failed\n");
789
+ return ret;
790
+ }
791
+
440
792
  ret = test_accept_sqpoll();
441
793
  if (ret) {
442
794
  fprintf(stderr, "test_accept_sqpoll failed\n");
443
795
  return ret;
444
796
  }
445
797
 
446
- ret = test_accept_cancel(0);
798
+ ret = test_accept_cancel(0, 1, false);
447
799
  if (ret) {
448
800
  fprintf(stderr, "test_accept_cancel nodelay failed\n");
449
801
  return ret;
450
802
  }
451
803
 
452
- ret = test_accept_cancel(10000);
804
+ ret = test_accept_cancel(10000, 1, false);
453
805
  if (ret) {
454
806
  fprintf(stderr, "test_accept_cancel delay failed\n");
455
807
  return ret;
456
808
  }
457
809
 
458
- ret = test_accept_many(128, 0);
810
+ ret = test_accept_cancel(0, 4, false);
459
811
  if (ret) {
460
- fprintf(stderr, "test_accept_many failed\n");
812
+ fprintf(stderr, "test_accept_cancel nodelay failed\n");
813
+ return ret;
814
+ }
815
+
816
+ ret = test_accept_cancel(10000, 4, false);
817
+ if (ret) {
818
+ fprintf(stderr, "test_accept_cancel delay failed\n");
819
+ return ret;
820
+ }
821
+
822
+ ret = test_accept_cancel(0, 1, true);
823
+ if (ret) {
824
+ fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
825
+ return ret;
826
+ }
827
+
828
+ ret = test_accept_cancel(10000, 1, true);
829
+ if (ret) {
830
+ fprintf(stderr, "test_accept_cancel multishot delay failed\n");
831
+ return ret;
832
+ }
833
+
834
+ ret = test_accept_cancel(0, 4, true);
835
+ if (ret) {
836
+ fprintf(stderr, "test_accept_cancel multishot nodelay failed\n");
461
837
  return ret;
462
838
  }
463
839
 
464
- ret = test_accept_many(128, 100000);
840
+ ret = test_accept_cancel(10000, 4, true);
841
+ if (ret) {
842
+ fprintf(stderr, "test_accept_cancel multishot delay failed\n");
843
+ return ret;
844
+ }
845
+
846
+ ret = test_multishot_accept(1, true, true);
847
+ if (ret) {
848
+ fprintf(stderr, "test_multishot_accept(1, false, true) failed\n");
849
+ return ret;
850
+ }
851
+
852
+ ret = test_multishot_accept(1, false, false);
853
+ if (ret) {
854
+ fprintf(stderr, "test_multishot_accept(1, false, false) failed\n");
855
+ return ret;
856
+ }
857
+
858
+ ret = test_multishot_accept(1, true, false);
859
+ if (ret) {
860
+ fprintf(stderr, "test_multishot_accept(1, true, false) failed\n");
861
+ return ret;
862
+ }
863
+
864
+ ret = test_accept_many((struct test_accept_many_args) {});
465
865
  if (ret) {
466
866
  fprintf(stderr, "test_accept_many failed\n");
467
867
  return ret;
468
868
  }
469
869
 
870
+ ret = test_accept_many((struct test_accept_many_args) {
871
+ .usecs = 100000 });
872
+ if (ret) {
873
+ fprintf(stderr, "test_accept_many(sleep) failed\n");
874
+ return ret;
875
+ }
876
+
877
+ ret = test_accept_many((struct test_accept_many_args) {
878
+ .nonblock = true });
879
+ if (ret) {
880
+ fprintf(stderr, "test_accept_many(nonblock) failed\n");
881
+ return ret;
882
+ }
883
+
884
+ ret = test_accept_many((struct test_accept_many_args) {
885
+ .nonblock = true,
886
+ .single_sock = true,
887
+ .close_fds = true });
888
+ if (ret) {
889
+ fprintf(stderr, "test_accept_many(nonblock,close) failed\n");
890
+ return ret;
891
+ }
892
+
470
893
  ret = test_accept_pending_on_exit();
471
894
  if (ret) {
472
895
  fprintf(stderr, "test_accept_pending_on_exit failed\n");
473
896
  return ret;
474
897
  }
475
-
476
- return 0;
898
+ return T_EXIT_PASS;
477
899
  }