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
@@ -10,6 +10,10 @@
10
10
  #include <unistd.h>
11
11
  #include <sys/types.h>
12
12
 
13
+ #include <arpa/inet.h>
14
+ #include <netinet/ip.h>
15
+ #include <netinet/tcp.h>
16
+
13
17
  #include "helpers.h"
14
18
  #include "liburing.h"
15
19
 
@@ -24,6 +28,24 @@ void *t_malloc(size_t size)
24
28
  return ret;
25
29
  }
26
30
 
31
+ /*
32
+ * Helper for binding socket to an ephemeral port.
33
+ * The port number to be bound is returned in @addr->sin_port.
34
+ */
35
+ int t_bind_ephemeral_port(int fd, struct sockaddr_in *addr)
36
+ {
37
+ socklen_t addrlen;
38
+
39
+ addr->sin_port = 0;
40
+ if (bind(fd, (struct sockaddr *)addr, sizeof(*addr)))
41
+ return -errno;
42
+
43
+ addrlen = sizeof(*addr);
44
+ assert(!getsockname(fd, (struct sockaddr *)addr, &addrlen));
45
+ assert(addr->sin_port != 0);
46
+ return 0;
47
+ }
48
+
27
49
  /*
28
50
  * Helper for allocating size bytes aligned on a boundary.
29
51
  */
@@ -49,14 +71,14 @@ void *t_calloc(size_t nmemb, size_t size)
49
71
  /*
50
72
  * Helper for creating file and write @size byte buf with 0xaa value in the file.
51
73
  */
52
- void t_create_file(const char *file, size_t size)
74
+ static void __t_create_file(const char *file, size_t size, char pattern)
53
75
  {
54
76
  ssize_t ret;
55
77
  char *buf;
56
- int fd;
78
+ int fd;
57
79
 
58
80
  buf = t_malloc(size);
59
- memset(buf, 0xaa, size);
81
+ memset(buf, pattern, size);
60
82
 
61
83
  fd = open(file, O_WRONLY | O_CREAT, 0644);
62
84
  assert(fd >= 0);
@@ -68,6 +90,16 @@ void t_create_file(const char *file, size_t size)
68
90
  assert(ret == size);
69
91
  }
70
92
 
93
+ void t_create_file(const char *file, size_t size)
94
+ {
95
+ __t_create_file(file, size, 0xaa);
96
+ }
97
+
98
+ void t_create_file_pattern(const char *file, size_t size, char pattern)
99
+ {
100
+ __t_create_file(file, size, pattern);
101
+ }
102
+
71
103
  /*
72
104
  * Helper for creating @buf_num number of iovec
73
105
  * with @buf_size bytes buffer of each iovec.
@@ -80,7 +112,7 @@ struct iovec *t_create_buffers(size_t buf_num, size_t buf_size)
80
112
  vecs = t_malloc(buf_num * sizeof(struct iovec));
81
113
  for (i = 0; i < buf_num; i++) {
82
114
  t_posix_memalign(&vecs[i].iov_base, buf_size, buf_size);
83
- vecs[i].iov_len = buf_size;
115
+ vecs[i].iov_len = buf_size;
84
116
  }
85
117
  return vecs;
86
118
  }
@@ -133,3 +165,104 @@ enum t_setup_ret t_register_buffers(struct io_uring *ring,
133
165
  fprintf(stderr, "buffer register failed: %s\n", strerror(-ret));
134
166
  return ret;
135
167
  }
168
+
169
+ int t_create_socket_pair(int fd[2], bool stream)
170
+ {
171
+ int ret;
172
+ int type = stream ? SOCK_STREAM : SOCK_DGRAM;
173
+ int val;
174
+ struct sockaddr_in serv_addr;
175
+ struct sockaddr *paddr;
176
+ size_t paddrlen;
177
+
178
+ type |= SOCK_CLOEXEC;
179
+ fd[0] = socket(AF_INET, type, 0);
180
+ if (fd[0] < 0)
181
+ return errno;
182
+ fd[1] = socket(AF_INET, type, 0);
183
+ if (fd[1] < 0) {
184
+ ret = errno;
185
+ close(fd[0]);
186
+ return ret;
187
+ }
188
+
189
+ val = 1;
190
+ if (setsockopt(fd[0], SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)))
191
+ goto errno_cleanup;
192
+
193
+ memset(&serv_addr, 0, sizeof(serv_addr));
194
+ serv_addr.sin_family = AF_INET;
195
+ serv_addr.sin_port = 0;
196
+ inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
197
+
198
+ paddr = (struct sockaddr *)&serv_addr;
199
+ paddrlen = sizeof(serv_addr);
200
+
201
+ if (bind(fd[0], paddr, paddrlen)) {
202
+ fprintf(stderr, "bind failed\n");
203
+ goto errno_cleanup;
204
+ }
205
+
206
+ if (stream && listen(fd[0], 16)) {
207
+ fprintf(stderr, "listen failed\n");
208
+ goto errno_cleanup;
209
+ }
210
+
211
+ if (getsockname(fd[0], (struct sockaddr *)&serv_addr,
212
+ (socklen_t *)&paddrlen)) {
213
+ fprintf(stderr, "getsockname failed\n");
214
+ goto errno_cleanup;
215
+ }
216
+ inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
217
+
218
+ if (connect(fd[1], (struct sockaddr *)&serv_addr, paddrlen)) {
219
+ fprintf(stderr, "connect failed\n");
220
+ goto errno_cleanup;
221
+ }
222
+
223
+ if (!stream) {
224
+ /* connect the other udp side */
225
+ if (getsockname(fd[1], (struct sockaddr *)&serv_addr,
226
+ (socklen_t *)&paddrlen)) {
227
+ fprintf(stderr, "getsockname failed\n");
228
+ goto errno_cleanup;
229
+ }
230
+ inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);
231
+
232
+ if (connect(fd[0], (struct sockaddr *)&serv_addr, paddrlen)) {
233
+ fprintf(stderr, "connect failed\n");
234
+ goto errno_cleanup;
235
+ }
236
+ return 0;
237
+ }
238
+
239
+ /* for stream case we must accept and cleanup the listen socket */
240
+
241
+ ret = accept(fd[0], NULL, NULL);
242
+ if (ret < 0)
243
+ goto errno_cleanup;
244
+
245
+ close(fd[0]);
246
+ fd[0] = ret;
247
+
248
+ return 0;
249
+
250
+ errno_cleanup:
251
+ ret = errno;
252
+ close(fd[0]);
253
+ close(fd[1]);
254
+ return ret;
255
+ }
256
+
257
+ bool t_probe_defer_taskrun(void)
258
+ {
259
+ struct io_uring ring;
260
+ int ret;
261
+
262
+ ret = io_uring_queue_init(1, &ring, IORING_SETUP_SINGLE_ISSUER |
263
+ IORING_SETUP_DEFER_TASKRUN);
264
+ if (ret < 0)
265
+ return false;
266
+ io_uring_queue_exit(&ring);
267
+ return true;
268
+ }
@@ -10,12 +10,26 @@ extern "C" {
10
10
  #endif
11
11
 
12
12
  #include "liburing.h"
13
+ #include <arpa/inet.h>
13
14
 
14
15
  enum t_setup_ret {
15
16
  T_SETUP_OK = 0,
16
17
  T_SETUP_SKIP,
17
18
  };
18
19
 
20
+ enum t_test_result {
21
+ T_EXIT_PASS = 0,
22
+ T_EXIT_FAIL = 1,
23
+ T_EXIT_SKIP = 77,
24
+ };
25
+
26
+ /*
27
+ * Helper for binding socket to an ephemeral port.
28
+ * The port number to be bound is returned in @addr->sin_port.
29
+ */
30
+ int t_bind_ephemeral_port(int fd, struct sockaddr_in *addr);
31
+
32
+
19
33
  /*
20
34
  * Helper for allocating memory in tests.
21
35
  */
@@ -40,12 +54,23 @@ void *t_calloc(size_t nmemb, size_t size);
40
54
  */
41
55
  void t_create_file(const char *file, size_t size);
42
56
 
57
+ /*
58
+ * Helper for creating file and write @size byte buf with @pattern value in
59
+ * the file.
60
+ */
61
+ void t_create_file_pattern(const char *file, size_t size, char pattern);
62
+
43
63
  /*
44
64
  * Helper for creating @buf_num number of iovec
45
65
  * with @buf_size bytes buffer of each iovec.
46
66
  */
47
67
  struct iovec *t_create_buffers(size_t buf_num, size_t buf_size);
48
68
 
69
+ /*
70
+ * Helper for creating connected socket pairs
71
+ */
72
+ int t_create_socket_pair(int fd[2], bool stream);
73
+
49
74
  /*
50
75
  * Helper for setting up a ring and checking for user privs
51
76
  */
@@ -58,6 +83,8 @@ enum t_setup_ret t_register_buffers(struct io_uring *ring,
58
83
  const struct iovec *iovecs,
59
84
  unsigned nr_iovecs);
60
85
 
86
+ bool t_probe_defer_taskrun(void);
87
+
61
88
  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
62
89
 
63
90
  #ifdef __cplusplus
@@ -128,7 +128,7 @@ static int start_cancel(struct io_uring *ring, int do_partial, int async_cancel)
128
128
  fprintf(stderr, "sqe get failed\n");
129
129
  goto err;
130
130
  }
131
- io_uring_prep_cancel(sqe, i + 1, 0);
131
+ io_uring_prep_cancel64(sqe, i + 1, 0);
132
132
  if (async_cancel)
133
133
  sqe->flags |= IOSQE_ASYNC;
134
134
  sqe->user_data = 0;
@@ -246,7 +246,7 @@ static int test_dont_cancel_another_ring(void)
246
246
  fprintf(stderr, "%s: failed to get sqe\n", __FUNCTION__);
247
247
  return 1;
248
248
  }
249
- io_uring_prep_cancel(sqe, 1, 0);
249
+ io_uring_prep_cancel64(sqe, 1, 0);
250
250
  sqe->user_data = 2;
251
251
 
252
252
  ret = io_uring_submit(&ring2);
@@ -326,7 +326,7 @@ static int test_cancel_req_across_fork(void)
326
326
  fprintf(stderr, "%s: failed to get sqe\n", __FUNCTION__);
327
327
  return 1;
328
328
  }
329
- io_uring_prep_cancel(sqe, 1, 0);
329
+ io_uring_prep_cancel64(sqe, 1, 0);
330
330
  sqe->user_data = 2;
331
331
 
332
332
  ret = io_uring_submit(&ring);
@@ -365,8 +365,13 @@ static int test_cancel_req_across_fork(void)
365
365
  exit(0);
366
366
  } else {
367
367
  int wstatus;
368
+ pid_t childpid;
368
369
 
369
- if (waitpid(p, &wstatus, 0) == (pid_t)-1) {
370
+ do {
371
+ childpid = waitpid(p, &wstatus, 0);
372
+ } while (childpid == (pid_t)-1 && errno == EINTR);
373
+
374
+ if (childpid == (pid_t)-1) {
370
375
  perror("waitpid()");
371
376
  return 1;
372
377
  }
@@ -503,26 +508,26 @@ int main(int argc, char *argv[])
503
508
  int i, ret;
504
509
 
505
510
  if (argc > 1)
506
- return 0;
511
+ return T_EXIT_SKIP;
507
512
 
508
513
  if (test_dont_cancel_another_ring()) {
509
514
  fprintf(stderr, "test_dont_cancel_another_ring() failed\n");
510
- return 1;
515
+ return T_EXIT_FAIL;
511
516
  }
512
517
 
513
518
  if (test_cancel_req_across_fork()) {
514
519
  fprintf(stderr, "test_cancel_req_across_fork() failed\n");
515
- return 1;
520
+ return T_EXIT_FAIL;
516
521
  }
517
522
 
518
523
  if (test_cancel_inflight_exit()) {
519
524
  fprintf(stderr, "test_cancel_inflight_exit() failed\n");
520
- return 1;
525
+ return T_EXIT_FAIL;
521
526
  }
522
527
 
523
528
  if (test_sqpoll_cancel_iowq_requests()) {
524
529
  fprintf(stderr, "test_sqpoll_cancel_iowq_requests() failed\n");
525
- return 1;
530
+ return T_EXIT_FAIL;
526
531
  }
527
532
 
528
533
  t_create_file(fname, FILE_SIZE);
@@ -543,8 +548,8 @@ int main(int argc, char *argv[])
543
548
  }
544
549
 
545
550
  unlink(fname);
546
- return 0;
551
+ return T_EXIT_PASS;
547
552
  err:
548
553
  unlink(fname);
549
- return 1;
554
+ return T_EXIT_FAIL;
550
555
  }
@@ -32,61 +32,39 @@
32
32
  #define IORING_MAX_ENTRIES 4096
33
33
  #define IORING_MAX_ENTRIES_FALLBACK 128
34
34
 
35
- int
36
- expect_failed_submit(struct io_uring *ring, int error)
35
+ static int expect_fail(int fd, unsigned int to_submit,
36
+ unsigned int min_complete, unsigned int flags,
37
+ sigset_t *sig, int error)
37
38
  {
38
39
  int ret;
39
40
 
40
- ret = io_uring_submit(ring);
41
- if (ret == 1) {
42
- printf("expected failure, but io_uring_submit succeeded.\n");
41
+ ret = io_uring_enter(fd, to_submit, min_complete, flags, sig);
42
+ if (ret >= 0) {
43
+ fprintf(stderr, "expected %s, but call succeeded\n", strerror(-error));
43
44
  return 1;
44
45
  }
45
46
 
46
- if (errno != error) {
47
- printf("expected %d, got %d\n", error, errno);
47
+ if (ret != error) {
48
+ fprintf(stderr, "expected %d, got %d\n", error, ret);
48
49
  return 1;
49
50
  }
50
51
 
51
52
  return 0;
52
53
  }
53
54
 
54
- int
55
- expect_fail(int fd, unsigned int to_submit, unsigned int min_complete,
56
- unsigned int flags, sigset_t *sig, int error)
55
+ static int try_io_uring_enter(int fd, unsigned int to_submit,
56
+ unsigned int min_complete, unsigned int flags,
57
+ sigset_t *sig, int expect)
57
58
  {
58
59
  int ret;
59
60
 
60
- ret = __sys_io_uring_enter(fd, to_submit, min_complete, flags, sig);
61
- if (ret != -1) {
62
- printf("expected %s, but call succeeded\n", strerror(error));
63
- return 1;
64
- }
65
-
66
- if (errno != error) {
67
- printf("expected %d, got %d\n", error, errno);
68
- return 1;
69
- }
70
-
71
- return 0;
72
- }
61
+ if (expect < 0)
62
+ return expect_fail(fd, to_submit, min_complete, flags, sig,
63
+ expect);
73
64
 
74
- int
75
- try_io_uring_enter(int fd, unsigned int to_submit, unsigned int min_complete,
76
- unsigned int flags, sigset_t *sig, int expect, int error)
77
- {
78
- int ret;
79
-
80
- printf("io_uring_enter(%d, %u, %u, %u, %p)\n", fd, to_submit,
81
- min_complete, flags, sig);
82
-
83
- if (expect == -1)
84
- return expect_fail(fd, to_submit, min_complete,
85
- flags, sig, error);
86
-
87
- ret = __sys_io_uring_enter(fd, to_submit, min_complete, flags, sig);
65
+ ret = io_uring_enter(fd, to_submit, min_complete, flags, sig);
88
66
  if (ret != expect) {
89
- printf("Expected %d, got %d\n", expect, errno);
67
+ fprintf(stderr, "Expected %d, got %d\n", expect, ret);
90
68
  return 1;
91
69
  }
92
70
 
@@ -96,8 +74,7 @@ try_io_uring_enter(int fd, unsigned int to_submit, unsigned int min_complete,
96
74
  /*
97
75
  * prep a read I/O. index is treated like a block number.
98
76
  */
99
- int
100
- setup_file(char *template, off_t len)
77
+ static int setup_file(char *template, off_t len)
101
78
  {
102
79
  int fd, ret;
103
80
  char buf[4096];
@@ -115,15 +92,15 @@ setup_file(char *template, off_t len)
115
92
 
116
93
  ret = read(fd, buf, 4096);
117
94
  if (ret != 4096) {
118
- printf("read returned %d, expected 4096\n", ret);
95
+ fprintf(stderr, "read returned %d, expected 4096\n", ret);
119
96
  exit(1);
120
97
  }
121
98
 
122
99
  return fd;
123
100
  }
124
101
 
125
- void
126
- io_prep_read(struct io_uring_sqe *sqe, int fd, off_t offset, size_t len)
102
+ static void io_prep_read(struct io_uring_sqe *sqe, int fd, off_t offset,
103
+ size_t len)
127
104
  {
128
105
  struct iovec *iov;
129
106
 
@@ -138,8 +115,7 @@ io_prep_read(struct io_uring_sqe *sqe, int fd, off_t offset, size_t len)
138
115
  io_uring_sqe_set_data(sqe, iov); // free on completion
139
116
  }
140
117
 
141
- void
142
- reap_events(struct io_uring *ring, unsigned nr)
118
+ static void reap_events(struct io_uring *ring, unsigned nr)
143
119
  {
144
120
  int ret;
145
121
  unsigned left = nr;
@@ -147,17 +123,15 @@ reap_events(struct io_uring *ring, unsigned nr)
147
123
  struct iovec *iov;
148
124
  struct timeval start, now, elapsed;
149
125
 
150
- printf("Reaping %u I/Os\n", nr);
151
126
  gettimeofday(&start, NULL);
152
127
  while (left) {
153
128
  ret = io_uring_wait_cqe(ring, &cqe);
154
129
  if (ret < 0) {
155
- printf("io_uring_wait_cqe returned %d\n", ret);
156
- printf("expected success\n");
130
+ fprintf(stderr, "io_uring_wait_cqe returned %d\n", ret);
157
131
  exit(1);
158
132
  }
159
133
  if (cqe->res != 4096)
160
- printf("cqe->res: %d, expected 4096\n", cqe->res);
134
+ fprintf(stderr, "cqe->res: %d, expected 4096\n", cqe->res);
161
135
  iov = io_uring_cqe_get_data(cqe);
162
136
  free(iov->iov_base);
163
137
  free(iov);
@@ -167,15 +141,14 @@ reap_events(struct io_uring *ring, unsigned nr)
167
141
  gettimeofday(&now, NULL);
168
142
  timersub(&now, &start, &elapsed);
169
143
  if (elapsed.tv_sec > 10) {
170
- printf("Timed out waiting for I/Os to complete.\n");
171
- printf("%u expected, %u completed\n", nr, left);
144
+ fprintf(stderr, "Timed out waiting for I/Os to complete.\n");
145
+ fprintf(stderr, "%u expected, %u completed\n", nr, left);
172
146
  break;
173
147
  }
174
148
  }
175
149
  }
176
150
 
177
- void
178
- submit_io(struct io_uring *ring, unsigned nr)
151
+ static void submit_io(struct io_uring *ring, unsigned nr)
179
152
  {
180
153
  int fd, ret;
181
154
  off_t file_len;
@@ -183,7 +156,6 @@ submit_io(struct io_uring *ring, unsigned nr)
183
156
  static char template[32] = "/tmp/io_uring_enter-test.XXXXXX";
184
157
  struct io_uring_sqe *sqe;
185
158
 
186
- printf("Allocating %u sqes\n", nr);
187
159
  file_len = nr * 4096;
188
160
  fd = setup_file(template, file_len);
189
161
  for (i = 0; i < nr; i++) {
@@ -194,18 +166,15 @@ submit_io(struct io_uring *ring, unsigned nr)
194
166
  }
195
167
 
196
168
  /* submit the I/Os */
197
- printf("Submitting %u I/Os\n", nr);
198
169
  ret = io_uring_submit(ring);
199
170
  unlink(template);
200
171
  if (ret < 0) {
201
172
  perror("io_uring_enter");
202
173
  exit(1);
203
174
  }
204
- printf("Done\n");
205
175
  }
206
176
 
207
- int
208
- main(int argc, char **argv)
177
+ int main(int argc, char **argv)
209
178
  {
210
179
  int ret;
211
180
  unsigned int status = 0;
@@ -216,37 +185,36 @@ main(int argc, char **argv)
216
185
  unsigned completed, dropped;
217
186
 
218
187
  if (argc > 1)
219
- return 0;
188
+ return T_EXIT_SKIP;
220
189
 
221
190
  ret = io_uring_queue_init(IORING_MAX_ENTRIES, &ring, 0);
222
191
  if (ret == -ENOMEM)
223
192
  ret = io_uring_queue_init(IORING_MAX_ENTRIES_FALLBACK, &ring, 0);
224
193
  if (ret < 0) {
225
194
  perror("io_uring_queue_init");
226
- exit(1);
195
+ exit(T_EXIT_FAIL);
227
196
  }
228
- mask = *sq->kring_mask;
197
+ mask = sq->ring_mask;
229
198
 
230
199
  /* invalid flags */
231
- status |= try_io_uring_enter(ring.ring_fd, 1, 0, ~0U, NULL, -1, EINVAL);
200
+ status |= try_io_uring_enter(ring.ring_fd, 1, 0, ~0U, NULL, -EINVAL);
232
201
 
233
202
  /* invalid fd, EBADF */
234
- status |= try_io_uring_enter(-1, 0, 0, 0, NULL, -1, EBADF);
203
+ status |= try_io_uring_enter(-1, 0, 0, 0, NULL, -EBADF);
235
204
 
236
205
  /* valid, non-ring fd, EOPNOTSUPP */
237
- status |= try_io_uring_enter(0, 0, 0, 0, NULL, -1, EOPNOTSUPP);
206
+ status |= try_io_uring_enter(0, 0, 0, 0, NULL, -EOPNOTSUPP);
238
207
 
239
208
  /* to_submit: 0, flags: 0; should get back 0. */
240
- status |= try_io_uring_enter(ring.ring_fd, 0, 0, 0, NULL, 0, 0);
209
+ status |= try_io_uring_enter(ring.ring_fd, 0, 0, 0, NULL, 0);
241
210
 
242
211
  /* fill the sq ring */
243
- sq_entries = *ring.sq.kring_entries;
212
+ sq_entries = ring.sq.ring_entries;
244
213
  submit_io(&ring, sq_entries);
245
- printf("Waiting for %u events\n", sq_entries);
246
- ret = __sys_io_uring_enter(ring.ring_fd, 0, sq_entries,
247
- IORING_ENTER_GETEVENTS, NULL);
214
+ ret = io_uring_enter(ring.ring_fd, 0, sq_entries,
215
+ IORING_ENTER_GETEVENTS, NULL);
248
216
  if (ret < 0) {
249
- perror("io_uring_enter");
217
+ fprintf(stderr, "io_uring_enter: %s\n", strerror(-ret));
250
218
  status = 1;
251
219
  } else {
252
220
  /*
@@ -256,7 +224,7 @@ main(int argc, char **argv)
256
224
  */
257
225
  completed = *ring.cq.ktail - *ring.cq.khead;
258
226
  if (completed != sq_entries) {
259
- printf("Submitted %u I/Os, but only got %u completions\n",
227
+ fprintf(stderr, "Submitted %u I/Os, but only got %u completions\n",
260
228
  sq_entries, completed);
261
229
  status = 1;
262
230
  }
@@ -267,8 +235,7 @@ main(int argc, char **argv)
267
235
  * Add an invalid index to the submission queue. This should
268
236
  * result in the dropped counter increasing.
269
237
  */
270
- printf("Submitting invalid sqe index.\n");
271
- index = *sq->kring_entries + 1; // invalid index
238
+ index = sq->ring_entries + 1; // invalid index
272
239
  dropped = *sq->kdropped;
273
240
  ktail = *sq->ktail;
274
241
  sq->array[ktail & mask] = index;
@@ -279,18 +246,16 @@ main(int argc, char **argv)
279
246
  */
280
247
  io_uring_smp_store_release(sq->ktail, ktail);
281
248
 
282
- ret = __sys_io_uring_enter(ring.ring_fd, 1, 0, 0, NULL);
249
+ ret = io_uring_enter(ring.ring_fd, 1, 0, 0, NULL);
283
250
  /* now check to see if our sqe was dropped */
284
251
  if (*sq->kdropped == dropped) {
285
- printf("dropped counter did not increase\n");
252
+ fprintf(stderr, "dropped counter did not increase\n");
286
253
  status = 1;
287
254
  }
288
255
 
289
- if (!status) {
290
- printf("PASS\n");
291
- return 0;
292
- }
256
+ if (!status)
257
+ return T_EXIT_PASS;
293
258
 
294
- printf("FAIL\n");
295
- return -1;
259
+ fprintf(stderr, "FAIL\n");
260
+ return T_EXIT_FAIL;
296
261
  }