iou 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. checksums.yaml +7 -0
  2. data/.github/dependabot.yml +12 -0
  3. data/.gitignore +59 -0
  4. data/.gitmodules +3 -0
  5. data/Gemfile +3 -0
  6. data/LICENSE +21 -0
  7. data/README.md +106 -0
  8. data/Rakefile +39 -0
  9. data/TODO.md +4 -0
  10. data/examples/echo_server.rb +52 -0
  11. data/examples/event_loop.rb +69 -0
  12. data/examples/http_server.rb +56 -0
  13. data/examples/http_server_multishot.rb +59 -0
  14. data/ext/iou/extconf.rb +71 -0
  15. data/ext/iou/iou.c +729 -0
  16. data/ext/iou/iou.h +66 -0
  17. data/ext/iou/iou_ext.c +9 -0
  18. data/ext/iou/op_spec_data.c +61 -0
  19. data/iou.gemspec +27 -0
  20. data/lib/iou/version.rb +5 -0
  21. data/lib/iou.rb +3 -0
  22. data/test/helper.rb +59 -0
  23. data/test/test_iou.rb +794 -0
  24. data/vendor/liburing/.github/actions/codespell/stopwords +7 -0
  25. data/vendor/liburing/.github/pull_request_template.md +86 -0
  26. data/vendor/liburing/.github/workflows/build.yml +137 -0
  27. data/vendor/liburing/.github/workflows/codespell.yml +25 -0
  28. data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
  29. data/vendor/liburing/.gitignore +41 -0
  30. data/vendor/liburing/CHANGELOG +111 -0
  31. data/vendor/liburing/CITATION.cff +11 -0
  32. data/vendor/liburing/COPYING +502 -0
  33. data/vendor/liburing/COPYING.GPL +339 -0
  34. data/vendor/liburing/LICENSE +20 -0
  35. data/vendor/liburing/Makefile +96 -0
  36. data/vendor/liburing/Makefile.common +7 -0
  37. data/vendor/liburing/Makefile.quiet +11 -0
  38. data/vendor/liburing/README +106 -0
  39. data/vendor/liburing/SECURITY.md +6 -0
  40. data/vendor/liburing/configure +624 -0
  41. data/vendor/liburing/debian/README.Debian +7 -0
  42. data/vendor/liburing/debian/changelog +38 -0
  43. data/vendor/liburing/debian/control +39 -0
  44. data/vendor/liburing/debian/copyright +49 -0
  45. data/vendor/liburing/debian/liburing-dev.install +4 -0
  46. data/vendor/liburing/debian/liburing-dev.manpages +5 -0
  47. data/vendor/liburing/debian/liburing2.install +1 -0
  48. data/vendor/liburing/debian/liburing2.symbols +56 -0
  49. data/vendor/liburing/debian/patches/series +1 -0
  50. data/vendor/liburing/debian/rules +29 -0
  51. data/vendor/liburing/debian/source/format +1 -0
  52. data/vendor/liburing/debian/source/local-options +2 -0
  53. data/vendor/liburing/debian/source/options +1 -0
  54. data/vendor/liburing/debian/watch +3 -0
  55. data/vendor/liburing/examples/Makefile +53 -0
  56. data/vendor/liburing/examples/helpers.c +62 -0
  57. data/vendor/liburing/examples/helpers.h +7 -0
  58. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  59. data/vendor/liburing/examples/io_uring-cp.c +282 -0
  60. data/vendor/liburing/examples/io_uring-test.c +112 -0
  61. data/vendor/liburing/examples/io_uring-udp.c +403 -0
  62. data/vendor/liburing/examples/link-cp.c +193 -0
  63. data/vendor/liburing/examples/napi-busy-poll-client.c +509 -0
  64. data/vendor/liburing/examples/napi-busy-poll-server.c +450 -0
  65. data/vendor/liburing/examples/poll-bench.c +101 -0
  66. data/vendor/liburing/examples/proxy.c +2461 -0
  67. data/vendor/liburing/examples/proxy.h +102 -0
  68. data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
  69. data/vendor/liburing/examples/send-zerocopy.c +658 -0
  70. data/vendor/liburing/examples/ucontext-cp.c +258 -0
  71. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  72. data/vendor/liburing/liburing.pc.in +12 -0
  73. data/vendor/liburing/liburing.spec +66 -0
  74. data/vendor/liburing/make-debs.sh +55 -0
  75. data/vendor/liburing/src/Makefile +129 -0
  76. data/vendor/liburing/src/arch/aarch64/lib.h +47 -0
  77. data/vendor/liburing/src/arch/aarch64/syscall.h +91 -0
  78. data/vendor/liburing/src/arch/generic/lib.h +17 -0
  79. data/vendor/liburing/src/arch/generic/syscall.h +100 -0
  80. data/vendor/liburing/src/arch/riscv64/lib.h +48 -0
  81. data/vendor/liburing/src/arch/riscv64/syscall.h +100 -0
  82. data/vendor/liburing/src/arch/syscall-defs.h +94 -0
  83. data/vendor/liburing/src/arch/x86/lib.h +11 -0
  84. data/vendor/liburing/src/arch/x86/syscall.h +296 -0
  85. data/vendor/liburing/src/ffi.c +15 -0
  86. data/vendor/liburing/src/include/liburing/barrier.h +81 -0
  87. data/vendor/liburing/src/include/liburing/io_uring.h +818 -0
  88. data/vendor/liburing/src/include/liburing.h +1602 -0
  89. data/vendor/liburing/src/int_flags.h +11 -0
  90. data/vendor/liburing/src/lib.h +52 -0
  91. data/vendor/liburing/src/liburing-ffi.map +211 -0
  92. data/vendor/liburing/src/liburing.map +104 -0
  93. data/vendor/liburing/src/nolibc.c +55 -0
  94. data/vendor/liburing/src/queue.c +468 -0
  95. data/vendor/liburing/src/register.c +374 -0
  96. data/vendor/liburing/src/setup.c +689 -0
  97. data/vendor/liburing/src/setup.h +9 -0
  98. data/vendor/liburing/src/syscall.c +29 -0
  99. data/vendor/liburing/src/syscall.h +53 -0
  100. data/vendor/liburing/src/version.c +21 -0
  101. data/vendor/liburing/test/232c93d07b74.c +305 -0
  102. data/vendor/liburing/test/35fa71a030ca.c +329 -0
  103. data/vendor/liburing/test/500f9fbadef8.c +91 -0
  104. data/vendor/liburing/test/7ad0e4b2f83c.c +94 -0
  105. data/vendor/liburing/test/8a9973408177.c +107 -0
  106. data/vendor/liburing/test/917257daa0fe.c +54 -0
  107. data/vendor/liburing/test/Makefile +297 -0
  108. data/vendor/liburing/test/a0908ae19763.c +59 -0
  109. data/vendor/liburing/test/a4c0b3decb33.c +181 -0
  110. data/vendor/liburing/test/accept-link.c +255 -0
  111. data/vendor/liburing/test/accept-non-empty.c +256 -0
  112. data/vendor/liburing/test/accept-reuse.c +163 -0
  113. data/vendor/liburing/test/accept-test.c +83 -0
  114. data/vendor/liburing/test/accept.c +919 -0
  115. data/vendor/liburing/test/across-fork.c +284 -0
  116. data/vendor/liburing/test/b19062a56726.c +54 -0
  117. data/vendor/liburing/test/b5837bd5311d.c +78 -0
  118. data/vendor/liburing/test/bind-listen.c +408 -0
  119. data/vendor/liburing/test/buf-ring-nommap.c +123 -0
  120. data/vendor/liburing/test/buf-ring-put.c +83 -0
  121. data/vendor/liburing/test/buf-ring.c +473 -0
  122. data/vendor/liburing/test/ce593a6c480a.c +139 -0
  123. data/vendor/liburing/test/close-opath.c +123 -0
  124. data/vendor/liburing/test/config +14 -0
  125. data/vendor/liburing/test/connect-rep.c +204 -0
  126. data/vendor/liburing/test/connect.c +442 -0
  127. data/vendor/liburing/test/coredump.c +60 -0
  128. data/vendor/liburing/test/cq-full.c +97 -0
  129. data/vendor/liburing/test/cq-overflow.c +530 -0
  130. data/vendor/liburing/test/cq-peek-batch.c +103 -0
  131. data/vendor/liburing/test/cq-ready.c +95 -0
  132. data/vendor/liburing/test/cq-size.c +65 -0
  133. data/vendor/liburing/test/d4ae271dfaae.c +96 -0
  134. data/vendor/liburing/test/d77a67ed5f27.c +65 -0
  135. data/vendor/liburing/test/defer-taskrun.c +391 -0
  136. data/vendor/liburing/test/defer-tw-timeout.c +173 -0
  137. data/vendor/liburing/test/defer.c +319 -0
  138. data/vendor/liburing/test/double-poll-crash.c +195 -0
  139. data/vendor/liburing/test/drop-submit.c +94 -0
  140. data/vendor/liburing/test/eeed8b54e0df.c +120 -0
  141. data/vendor/liburing/test/empty-eownerdead.c +45 -0
  142. data/vendor/liburing/test/eploop.c +74 -0
  143. data/vendor/liburing/test/eventfd-disable.c +179 -0
  144. data/vendor/liburing/test/eventfd-reg.c +77 -0
  145. data/vendor/liburing/test/eventfd-ring.c +98 -0
  146. data/vendor/liburing/test/eventfd.c +113 -0
  147. data/vendor/liburing/test/evloop.c +73 -0
  148. data/vendor/liburing/test/exec-target.c +6 -0
  149. data/vendor/liburing/test/exit-no-cleanup.c +117 -0
  150. data/vendor/liburing/test/fadvise.c +202 -0
  151. data/vendor/liburing/test/fallocate.c +265 -0
  152. data/vendor/liburing/test/fc2a85cb02ef.c +132 -0
  153. data/vendor/liburing/test/fd-install.c +500 -0
  154. data/vendor/liburing/test/fd-pass.c +237 -0
  155. data/vendor/liburing/test/fdinfo.c +419 -0
  156. data/vendor/liburing/test/file-register.c +1189 -0
  157. data/vendor/liburing/test/file-update.c +231 -0
  158. data/vendor/liburing/test/file-verify.c +654 -0
  159. data/vendor/liburing/test/files-exit-hang-poll.c +114 -0
  160. data/vendor/liburing/test/files-exit-hang-timeout.c +137 -0
  161. data/vendor/liburing/test/fixed-buf-iter.c +115 -0
  162. data/vendor/liburing/test/fixed-buf-merge.c +101 -0
  163. data/vendor/liburing/test/fixed-hugepage.c +411 -0
  164. data/vendor/liburing/test/fixed-link.c +90 -0
  165. data/vendor/liburing/test/fixed-reuse.c +160 -0
  166. data/vendor/liburing/test/fpos.c +255 -0
  167. data/vendor/liburing/test/fsnotify.c +118 -0
  168. data/vendor/liburing/test/fsync.c +224 -0
  169. data/vendor/liburing/test/futex.c +571 -0
  170. data/vendor/liburing/test/hardlink.c +170 -0
  171. data/vendor/liburing/test/helpers.c +318 -0
  172. data/vendor/liburing/test/helpers.h +108 -0
  173. data/vendor/liburing/test/ignore-single-mmap.c +48 -0
  174. data/vendor/liburing/test/init-mem.c +164 -0
  175. data/vendor/liburing/test/io-cancel.c +561 -0
  176. data/vendor/liburing/test/io_uring_enter.c +264 -0
  177. data/vendor/liburing/test/io_uring_passthrough.c +482 -0
  178. data/vendor/liburing/test/io_uring_register.c +503 -0
  179. data/vendor/liburing/test/io_uring_setup.c +110 -0
  180. data/vendor/liburing/test/iopoll-leak.c +85 -0
  181. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  182. data/vendor/liburing/test/iopoll.c +465 -0
  183. data/vendor/liburing/test/lfs-openat-write.c +119 -0
  184. data/vendor/liburing/test/lfs-openat.c +273 -0
  185. data/vendor/liburing/test/link-timeout.c +1108 -0
  186. data/vendor/liburing/test/link.c +497 -0
  187. data/vendor/liburing/test/link_drain.c +255 -0
  188. data/vendor/liburing/test/madvise.c +195 -0
  189. data/vendor/liburing/test/min-timeout-wait.c +354 -0
  190. data/vendor/liburing/test/min-timeout.c +233 -0
  191. data/vendor/liburing/test/mkdir.c +112 -0
  192. data/vendor/liburing/test/msg-ring-fd.c +331 -0
  193. data/vendor/liburing/test/msg-ring-flags.c +212 -0
  194. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  195. data/vendor/liburing/test/msg-ring.c +467 -0
  196. data/vendor/liburing/test/multicqes_drain.c +429 -0
  197. data/vendor/liburing/test/napi-test.c +215 -0
  198. data/vendor/liburing/test/napi-test.sh +48 -0
  199. data/vendor/liburing/test/no-mmap-inval.c +42 -0
  200. data/vendor/liburing/test/nolibc.c +62 -0
  201. data/vendor/liburing/test/nop-all-sizes.c +99 -0
  202. data/vendor/liburing/test/nop.c +177 -0
  203. data/vendor/liburing/test/nvme.h +169 -0
  204. data/vendor/liburing/test/ooo-file-unreg.c +82 -0
  205. data/vendor/liburing/test/open-close.c +261 -0
  206. data/vendor/liburing/test/open-direct-link.c +188 -0
  207. data/vendor/liburing/test/open-direct-pick.c +180 -0
  208. data/vendor/liburing/test/openat2.c +312 -0
  209. data/vendor/liburing/test/personality.c +204 -0
  210. data/vendor/liburing/test/pipe-bug.c +95 -0
  211. data/vendor/liburing/test/pipe-eof.c +83 -0
  212. data/vendor/liburing/test/pipe-reuse.c +105 -0
  213. data/vendor/liburing/test/poll-cancel-all.c +496 -0
  214. data/vendor/liburing/test/poll-cancel-ton.c +135 -0
  215. data/vendor/liburing/test/poll-cancel.c +228 -0
  216. data/vendor/liburing/test/poll-link.c +221 -0
  217. data/vendor/liburing/test/poll-many.c +230 -0
  218. data/vendor/liburing/test/poll-mshot-overflow.c +265 -0
  219. data/vendor/liburing/test/poll-mshot-update.c +323 -0
  220. data/vendor/liburing/test/poll-race-mshot.c +276 -0
  221. data/vendor/liburing/test/poll-race.c +105 -0
  222. data/vendor/liburing/test/poll-ring.c +48 -0
  223. data/vendor/liburing/test/poll-v-poll.c +353 -0
  224. data/vendor/liburing/test/poll.c +327 -0
  225. data/vendor/liburing/test/probe.c +135 -0
  226. data/vendor/liburing/test/read-before-exit.c +129 -0
  227. data/vendor/liburing/test/read-mshot-empty.c +153 -0
  228. data/vendor/liburing/test/read-mshot.c +404 -0
  229. data/vendor/liburing/test/read-write.c +1013 -0
  230. data/vendor/liburing/test/recv-msgall-stream.c +398 -0
  231. data/vendor/liburing/test/recv-msgall.c +263 -0
  232. data/vendor/liburing/test/recv-multishot.c +602 -0
  233. data/vendor/liburing/test/recvsend_bundle.c +691 -0
  234. data/vendor/liburing/test/reg-fd-only.c +131 -0
  235. data/vendor/liburing/test/reg-hint.c +56 -0
  236. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  237. data/vendor/liburing/test/regbuf-merge.c +91 -0
  238. data/vendor/liburing/test/register-restrictions.c +633 -0
  239. data/vendor/liburing/test/rename.c +132 -0
  240. data/vendor/liburing/test/ring-leak.c +283 -0
  241. data/vendor/liburing/test/ring-leak2.c +249 -0
  242. data/vendor/liburing/test/ringbuf-read.c +196 -0
  243. data/vendor/liburing/test/ringbuf-status.c +242 -0
  244. data/vendor/liburing/test/rsrc_tags.c +461 -0
  245. data/vendor/liburing/test/runtests-loop.sh +16 -0
  246. data/vendor/liburing/test/runtests-quiet.sh +11 -0
  247. data/vendor/liburing/test/runtests.sh +168 -0
  248. data/vendor/liburing/test/rw_merge_test.c +98 -0
  249. data/vendor/liburing/test/self.c +91 -0
  250. data/vendor/liburing/test/send-zerocopy.c +971 -0
  251. data/vendor/liburing/test/send_recv.c +412 -0
  252. data/vendor/liburing/test/send_recvmsg.c +444 -0
  253. data/vendor/liburing/test/shared-wq.c +84 -0
  254. data/vendor/liburing/test/short-read.c +75 -0
  255. data/vendor/liburing/test/shutdown.c +165 -0
  256. data/vendor/liburing/test/sigfd-deadlock.c +88 -0
  257. data/vendor/liburing/test/single-issuer.c +169 -0
  258. data/vendor/liburing/test/skip-cqe.c +428 -0
  259. data/vendor/liburing/test/socket-getsetsock-cmd.c +346 -0
  260. data/vendor/liburing/test/socket-io-cmd.c +237 -0
  261. data/vendor/liburing/test/socket-rw-eagain.c +149 -0
  262. data/vendor/liburing/test/socket-rw-offset.c +149 -0
  263. data/vendor/liburing/test/socket-rw.c +137 -0
  264. data/vendor/liburing/test/socket.c +408 -0
  265. data/vendor/liburing/test/splice.c +512 -0
  266. data/vendor/liburing/test/sq-full-cpp.cc +45 -0
  267. data/vendor/liburing/test/sq-full.c +45 -0
  268. data/vendor/liburing/test/sq-poll-dup.c +211 -0
  269. data/vendor/liburing/test/sq-poll-kthread.c +169 -0
  270. data/vendor/liburing/test/sq-poll-share.c +138 -0
  271. data/vendor/liburing/test/sq-space_left.c +159 -0
  272. data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
  273. data/vendor/liburing/test/sqpoll-exec.c +132 -0
  274. data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
  275. data/vendor/liburing/test/sqpoll-sleep.c +69 -0
  276. data/vendor/liburing/test/statx.c +172 -0
  277. data/vendor/liburing/test/stdout.c +232 -0
  278. data/vendor/liburing/test/submit-and-wait.c +108 -0
  279. data/vendor/liburing/test/submit-link-fail.c +156 -0
  280. data/vendor/liburing/test/submit-reuse.c +237 -0
  281. data/vendor/liburing/test/symlink.c +117 -0
  282. data/vendor/liburing/test/sync-cancel.c +235 -0
  283. data/vendor/liburing/test/teardowns.c +58 -0
  284. data/vendor/liburing/test/test.h +36 -0
  285. data/vendor/liburing/test/thread-exit.c +143 -0
  286. data/vendor/liburing/test/timeout-new.c +256 -0
  287. data/vendor/liburing/test/timeout.c +1798 -0
  288. data/vendor/liburing/test/truncate.c +186 -0
  289. data/vendor/liburing/test/tty-write-dpoll.c +60 -0
  290. data/vendor/liburing/test/unlink.c +112 -0
  291. data/vendor/liburing/test/version.c +25 -0
  292. data/vendor/liburing/test/wait-timeout.c +287 -0
  293. data/vendor/liburing/test/waitid.c +373 -0
  294. data/vendor/liburing/test/wakeup-hang.c +162 -0
  295. data/vendor/liburing/test/wq-aff.c +146 -0
  296. data/vendor/liburing/test/xattr.c +442 -0
  297. metadata +402 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 81760683a4ded7963311f6d8961dff7d0f13edd164afb4cf3056f151889f612d
4
+ data.tar.gz: c700916bbe4b519bc95522da3855fa084f40ab56d8c8cebd2f1d04521681add2
5
+ SHA512:
6
+ metadata.gz: f1aba30375539d2f16083bce2db47a3807abd2a2fa484c270d57a8954bbe3a21d9785408bba667c48e991b47805b38686a4b263602b2b57cf17f30fd32c59187
7
+ data.tar.gz: e812e047b19ea89c9a0731de4f216dbacf3e1bdc62e363bc5f31fb843b19fc072a3b0e3272152ff215efd90591ec220bc23aff12d7a6dae755153c9fe6892a76
@@ -0,0 +1,12 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for more information:
4
+ # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5
+ # https://containers.dev/guide/dependabot
6
+
7
+ version: 2
8
+ updates:
9
+ - package-ecosystem: "devcontainers"
10
+ directory: "/"
11
+ schedule:
12
+ interval: weekly
data/.gitignore ADDED
@@ -0,0 +1,59 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ # Ignore Byebug command history file.
17
+ .byebug_history
18
+
19
+ ## Specific to RubyMotion:
20
+ .dat*
21
+ .repl_history
22
+ build/
23
+ *.bridgesupport
24
+ build-iPhoneOS/
25
+ build-iPhoneSimulator/
26
+
27
+ ## Specific to RubyMotion (use of CocoaPods):
28
+ #
29
+ # We recommend against adding the Pods directory to your .gitignore. However
30
+ # you should judge for yourself, the pros and cons are mentioned at:
31
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
32
+ #
33
+ # vendor/Pods/
34
+
35
+ ## Documentation cache and generated files:
36
+ /.yardoc/
37
+ /_yardoc/
38
+ /doc/
39
+ /rdoc/
40
+
41
+ ## Environment normalization:
42
+ /.bundle/
43
+ /vendor/bundle
44
+ /lib/bundler/man/
45
+
46
+ # for a library or gem, you might want to ignore these files since the code is
47
+ # intended to run in multiple environments; otherwise, check them in:
48
+ Gemfile.lock
49
+ .ruby-version
50
+ .ruby-gemset
51
+
52
+ # Ignore compiled extension
53
+ lib/*.so
54
+
55
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
56
+ .rvmrc
57
+
58
+ # Used by RuboCop. Remote config files pulled in from inherit_from directive.
59
+ # .rubocop-https?--*
data/.gitmodules ADDED
@@ -0,0 +1,3 @@
1
+ [submodule "vendor/liburing"]
2
+ path = vendor/liburing
3
+ url = https://github.com/axboe/liburing
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Digital Fabric
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # IOU: io_uring for Ruby
2
+
3
+ <a href="http://rubygems.org/gems/iou">
4
+ <img src="https://badge.fury.io/rb/iou.svg" alt="Ruby gem">
5
+ </a>
6
+ <a href="https://github.com/digital-fabric/iou/actions?query=workflow%3ATests">
7
+ <img src="https://github.com/digital-fabric/iou/workflows/Tests/badge.svg" alt="Tests">
8
+ </a>
9
+ <a href="https://github.com/digital-fabric/iou/blob/master/LICENSE">
10
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
11
+ </a>
12
+
13
+ ## What is IOU?
14
+
15
+ IOU is a Ruby gem for working with the io_uring API. IOU provides a simple and
16
+ idiomatic API for working with io_uring. IOU does not make any assumptions about
17
+ the concurrency model in your application. It can be used in multi-threaded,
18
+ multi-fibered, or callback-based apps. It largely follows the
19
+ [liburing](https://github.com/axboe/liburing/) API, but provides certain
20
+ Ruby-esque amenities to make it easier to use io_uring in Ruby apps.
21
+
22
+ ## Features
23
+
24
+ - Prepare and submit operations: accept, read, write, timeout, nop.
25
+ - Cancel operations.
26
+ - Multishot timeout, accept, read.
27
+ - Setup buffer ring for multishot read (provides a nice boost for read performance).
28
+ - Associate arbitrary data with operations.
29
+ - Run callback on completion of operations.
30
+ - Emit arbitrary values for in-app signalling.
31
+
32
+ ## Basic Usage
33
+
34
+ Operations are performed by preparing them (using the different `#prep_xxx`
35
+ methods), submitting them, then waiting or polling for completion of those
36
+ operations. Here's a simple example of how IOU is used:
37
+
38
+ ```ruby
39
+ ring = IOU::Ring.new
40
+ # prepare a 3 second timeout operation
41
+ ring.prep_timeout(interval: 3)
42
+
43
+ # submit all unsubmitted operations to io_uring
44
+ ring.submit
45
+
46
+ # wait for completion, this will block for 3 seconds!
47
+ ring.wait_for_completion
48
+ #=> { id: 1, op: :timeout, interval: 3}
49
+ ```
50
+
51
+ ## Cancelling operations
52
+
53
+ Any operation can be cancelled by calling `#prep_cancel`:
54
+
55
+ ```ruby
56
+ id = ring.prep_timeout(interval: 3)
57
+ ...
58
+ ring.prep_cancel(id)
59
+ ```
60
+
61
+ ## Callback-style completions
62
+
63
+ Callback-style handling of completions can be done using `#process_completions`:
64
+
65
+ ```ruby
66
+ timeout_id = ring.prep_timeout(interval: 3)
67
+ ring.submit
68
+
69
+ # passing true to process_completions means wait for at least one completion
70
+ # to be available
71
+ ring.process_completions(true) do |completion|
72
+ # the completion is a hash containing the operation spec
73
+ if completion[:id] == timeout_id
74
+ puts "timeout elapsed!"
75
+ end
76
+ end
77
+
78
+ # another way to do callbacks is to provide a block to prep_timeout:
79
+ timeout_id = ring.prep_timeout(interval: 3) do
80
+ puts "timeout elapsed"
81
+ end
82
+
83
+ # wait for completion and trigger the callback
84
+ ring.process_completions(true)
85
+ ```
86
+
87
+ ## I/O with IOU
88
+
89
+ I/O operations, such as `read`, `write`, `recv`, `send`, `accept` etc are done
90
+ using raw fd's.
91
+
92
+ ```ruby
93
+ # write to STDOUT using IOU
94
+ ring.prep_write(fd: STDOUT.fileno, buffer: 'Hello world!')
95
+ ring.submit
96
+ ring.wait_for_completion
97
+ ```
98
+
99
+ ## Examples
100
+
101
+ Examples for using IOU can be found in the examples directory:
102
+
103
+ - [v] Echo server
104
+ - [v] HTTP server
105
+ - [v] Event loop (in the style of EventMachine)
106
+ - [ ] Fiber-based concurrency
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/clean"
5
+ require "rake/testtask"
6
+ require "rake/extensiontask"
7
+
8
+ Rake::ExtensionTask.new("iou_ext") do |ext|
9
+ ext.ext_dir = "ext/iou"
10
+ end
11
+
12
+ task :recompile => [:clean, :compile]
13
+ task :default => [:compile, :test]
14
+
15
+ test_config = -> (t) {
16
+ t.libs << "test"
17
+ t.test_files = FileList["test/**/test_*.rb"]
18
+ }
19
+ Rake::TestTask.new(test: :compile, &test_config)
20
+
21
+ task :stress_test do
22
+ exec 'ruby test/stress.rb'
23
+ end
24
+
25
+ CLEAN.include "**/*.o", "**/*.so", "**/*.so.*", "**/*.a", "**/*.bundle", "**/*.jar", "pkg", "tmp"
26
+
27
+ task :release do
28
+ require_relative './lib/iou/version'
29
+ version = IOU::VERSION
30
+
31
+ puts 'Building iou...'
32
+ `gem build iou.gemspec`
33
+
34
+ puts "Pushing iou #{version}..."
35
+ `gem push iou-#{version}.gem`
36
+
37
+ puts "Cleaning up..."
38
+ `rm *.gem`
39
+ end
data/TODO.md ADDED
@@ -0,0 +1,4 @@
1
+ # io_uring ops
2
+
3
+ - [ ] recv
4
+ - [ ] send
@@ -0,0 +1,52 @@
1
+ require_relative '../lib/iou'
2
+ require 'socket'
3
+
4
+ socket = TCPServer.open('127.0.0.1', 1234)
5
+ puts 'Listening on port 1234...'
6
+
7
+ @ring = IOU::Ring.new
8
+
9
+ @ring.prep_accept(fd: socket.fileno, multishot: true) do |c|
10
+ setup_connection(c[:result]) if c[:result] > 0
11
+ end
12
+
13
+ def setup_connection(fd)
14
+ puts "Connection accepted fd #{fd}"
15
+
16
+ buffer = +''
17
+ echo_prep_read(fd, buffer)
18
+ end
19
+
20
+ def echo_prep_read(fd, buffer)
21
+ @ring.prep_read(fd: fd, buffer: buffer, len: 4096, buffer_offset: -1) do |c|
22
+ if c[:result] > 0
23
+ echo_lines(fd, buffer)
24
+ echo_prep_read(fd, buffer)
25
+ elsif c[:result] == 0
26
+ puts "Connection closed by client on fd #{fd}"
27
+ else
28
+ puts "Got error #{c[:result]} on fd #{fd}, closing connection..."
29
+ @ring.prep_close(fd: fd) do |c|
30
+ puts "Connection closed on fd #{fd}, result #{c[:result]}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ def echo_lines(fd, buffer)
37
+ sep = $/
38
+ sep_size = sep.bytesize
39
+
40
+ while true
41
+ idx = buffer.index(sep)
42
+ if idx
43
+ line = buffer.slice!(0, idx + sep_size)
44
+ @ring.prep_write(fd: fd, buffer: line)
45
+ else
46
+ break
47
+ end
48
+ end
49
+ end
50
+
51
+ trap('SIGINT') { exit! }
52
+ @ring.process_completions_loop
@@ -0,0 +1,69 @@
1
+ require_relative '../lib/iou'
2
+ require 'socket'
3
+
4
+ class IOUEventLoop
5
+ attr_reader :ring
6
+
7
+ def initialize
8
+ @ring = IOU::Ring.new
9
+ end
10
+
11
+ def async_queue
12
+ @async_queue ||= []
13
+ end
14
+
15
+ def async(&block)
16
+ @async_queue << block
17
+ signal if @waiting
18
+ end
19
+
20
+ def signal
21
+ # generate an event to cause process_completions to return
22
+ ring.prep_nop
23
+ ring.submit
24
+ end
25
+
26
+ def run_async_tasks
27
+ pending = @async_queue
28
+ @async_queue = []
29
+ pending&.each(&:call)
30
+ end
31
+
32
+ def run
33
+ yield if block_given?
34
+ while !@stopped
35
+ run_async_tasks
36
+ @waiting = true
37
+ ring.process_completions
38
+ @waiting = false
39
+ end
40
+ end
41
+
42
+ def stop
43
+ @stopped = true
44
+ signal if @waiting
45
+ end
46
+
47
+ def timeout(delay, &block)
48
+ ring.prep_timeout(interval: delay, &block)
49
+ ring.submit
50
+ end
51
+
52
+ def interval(period, &block)
53
+ ring.prep_timeout(interval: period, multishot: true, &block)
54
+ ring.submit
55
+ end
56
+ end
57
+
58
+ # exaple usage
59
+ event_loop = IOUEventLoop.new
60
+
61
+ trap('SIGINT') { event_loop.stop }
62
+
63
+ event_loop.run do
64
+ event_loop.interval(1) do
65
+ puts "The time is #{Time.now}"
66
+ end
67
+ end
68
+
69
+ puts "Stopped"
@@ -0,0 +1,56 @@
1
+ require_relative '../lib/iou'
2
+ require 'socket'
3
+ require 'http/parser'
4
+
5
+ def log(msg)
6
+ # return
7
+ STDERR.puts msg
8
+ end
9
+
10
+ socket = TCPServer.open('127.0.0.1', 1234)
11
+ log 'Listening on port 1234...'
12
+
13
+ @ring = IOU::Ring.new
14
+ @bg_id = @ring.setup_buffer_ring(count: 1024, size: 4096)
15
+
16
+ @ring.prep_accept(fd: socket.fileno, multishot: true) do |c|
17
+ setup_connection(c[:result]) if c[:result] > 0
18
+ end
19
+
20
+ def setup_connection(fd)
21
+ log "Connection accepted fd #{fd}"
22
+
23
+ parser = Http::Parser.new
24
+ parser.on_message_complete = -> {
25
+ http_send_response(fd, "Hello, world!\n") do
26
+ @ring.prep_close(fd: fd)
27
+ end
28
+ }
29
+
30
+ http_prep_read(fd, parser)
31
+ end
32
+
33
+ def http_prep_read(fd, parser)
34
+ buffer = +''
35
+ @ring.prep_read(fd: fd, buffer: buffer, len: 4096) do |c|
36
+ if c[:result] > 0
37
+ http_prep_read(fd, parser)
38
+ parser << buffer
39
+ elsif c[:result] == 0
40
+ log "Connection closed by client on fd #{fd}"
41
+ else
42
+ log "Got error #{c[:result]} on fd #{fd}, closing connection..."
43
+ @ring.prep_close(fd: fd) do |c|
44
+ log "Connection closed on fd #{fd}, result #{c[:result]}"
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ def http_send_response(fd, body)
51
+ msg = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: keep-alive\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}"
52
+ @ring.prep_write(fd: fd, buffer: msg)
53
+ end
54
+
55
+ trap('SIGINT') { exit! }
56
+ @ring.process_completions_loop
@@ -0,0 +1,59 @@
1
+ require_relative '../lib/iou'
2
+ require 'socket'
3
+ require 'http/parser'
4
+
5
+ def log(msg)
6
+ # return
7
+ STDERR.puts msg
8
+ end
9
+
10
+ socket = TCPServer.open('127.0.0.1', 1234)
11
+ log 'Listening on port 1234... (multishot read)'
12
+
13
+ @ring = IOU::Ring.new
14
+ @bg_id = @ring.setup_buffer_ring(count: 1024, size: 4096)
15
+
16
+ @ring.prep_accept(fd: socket.fileno, multishot: true) do |c|
17
+ setup_connection(c[:result]) if c[:result] > 0
18
+ end
19
+
20
+ def setup_connection(fd)
21
+ log "Connection accepted fd #{fd}"
22
+
23
+ parser = Http::Parser.new
24
+ parser.on_message_complete = -> {
25
+ http_send_response(fd, "Hello, world!\n") do
26
+ @ring.prep_close(fd: fd)
27
+ end
28
+ }
29
+
30
+ http_prep_read(fd, parser)
31
+ end
32
+
33
+ def http_prep_read(fd, parser)
34
+ id = @ring.prep_read(fd: fd, multishot: true, buffer_group: @bg_id) do |c|
35
+ if c[:result] > 0
36
+ parser << c[:buffer]
37
+ elsif c[:result] == 0
38
+ log "Connection closed by client on fd #{fd}"
39
+ else
40
+ if c[:result] != -Errno::ECANCELED::Errno
41
+ log "Got error #{c[:result]} on fd #{fd}, closing connection..."
42
+ end
43
+ @ring.prep_close(fd: fd) do |c|
44
+ log "Connection closed on fd #{fd}, result #{c[:result]}"
45
+ end
46
+ end
47
+ rescue HTTP::Parser::Error
48
+ puts "Error parsing, closing connection..."
49
+ @ring.prep_cancel(id)
50
+ end
51
+ end
52
+
53
+ def http_send_response(fd, body)
54
+ msg = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: keep-alive\r\nContent-Length: #{body.bytesize}\r\n\r\n#{body}"
55
+ @ring.prep_write(fd: fd, buffer: msg)
56
+ end
57
+
58
+ trap('SIGINT') { exit! }
59
+ @ring.process_completions_loop
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems'
4
+ require 'mkmf'
5
+ require 'rbconfig'
6
+
7
+ dir_config 'iou_ext'
8
+
9
+ KERNEL_INFO_RE = /Linux (\d)\.(\d+)(?:\.)?((?:\d+\.?)*)(?:\-)?([\w\-]+)?/
10
+ def get_config
11
+ config = { linux: !!(RUBY_PLATFORM =~ /linux/) }
12
+ raise "IOU only works on Linux!" if !config[:linux]
13
+
14
+ kernel_info = `uname -sr`
15
+ m = kernel_info.match(KERNEL_INFO_RE)
16
+ raise "Could not parse Linux kernel information (#{kernel_info.inspect})" if !m
17
+
18
+ version, major_revision, distribution = m[1].to_i, m[2].to_i, m[4]
19
+
20
+ combined_version = version.to_i * 100 + major_revision.to_i
21
+ raise "IOU requires kernel version 6.4 or newer!" if combined_version < 604
22
+
23
+ config[:kernel_version] = combined_version
24
+ config[:pidfd_open] = combined_version > 503
25
+ config[:multishot_accept] = combined_version >= 519
26
+ config[:multishot_recv] = combined_version >= 600
27
+ config[:multishot_recvmsg] = combined_version >= 600
28
+ config[:multishot_timeout] = combined_version >= 604
29
+ config[:submit_all_flag] = combined_version >= 518
30
+ config[:coop_taskrun_flag] = combined_version >= 519
31
+ config[:single_issuer_flag] = combined_version >= 600
32
+
33
+ config
34
+ end
35
+
36
+ config = get_config
37
+ puts "Building IOU (\n#{config.map { |(k, v)| " #{k}: #{v}\n"}.join})"
38
+
39
+ # require_relative 'zlib_conf'
40
+
41
+ liburing_path = File.expand_path('../../vendor/liburing', __dir__)
42
+ FileUtils.cd liburing_path do
43
+ system('./configure', exception: true)
44
+ FileUtils.cd File.join(liburing_path, 'src') do
45
+ system('make', 'liburing.a', exception: true)
46
+ end
47
+ end
48
+
49
+ if !find_header 'liburing.h', File.join(liburing_path, 'src/include')
50
+ raise "Couldn't find liburing.h"
51
+ end
52
+
53
+ if !find_library('uring', nil, File.join(liburing_path, 'src'))
54
+ raise "Couldn't find liburing.a"
55
+ end
56
+
57
+ def define_bool(name, value)
58
+ $defs << "-D#{name}=#{value ? 1 : 0 }"
59
+ end
60
+
61
+ $defs << '-DHAVE_IO_URING_PREP_MULTISHOT_ACCEPT' if config[:multishot_accept]
62
+ $defs << '-DHAVE_IO_URING_PREP_RECV_MULTISHOT' if config[:multishot_recv]
63
+ $defs << '-DHAVE_IO_URING_PREP_RECVMSG_MULTISHOT' if config[:multishot_recvmsg]
64
+ $defs << '-DHAVE_IO_URING_TIMEOUT_MULTISHOT' if config[:multishot_timeout]
65
+ $defs << '-DHAVE_IORING_SETUP_SUBMIT_ALL' if config[:submit_all_flag]
66
+ $defs << '-DHAVE_IORING_SETUP_COOP_TASKRUN' if config[:coop_taskrun_flag]
67
+ $CFLAGS << ' -Wno-pointer-arith'
68
+
69
+ CONFIG['optflags'] << ' -fno-strict-aliasing'
70
+
71
+ create_makefile 'iou_ext'