uringmachine 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 (307) hide show
  1. checksums.yaml +7 -0
  2. data/.github/dependabot.yml +12 -0
  3. data/.github/workflows/test.yml +35 -0
  4. data/.gitignore +59 -0
  5. data/.gitmodules +3 -0
  6. data/CHANGELOG.md +7 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +21 -0
  9. data/README.md +11 -0
  10. data/Rakefile +39 -0
  11. data/TODO.md +0 -0
  12. data/examples/echo_server.rb +52 -0
  13. data/examples/event_loop.rb +69 -0
  14. data/examples/fibers.rb +105 -0
  15. data/examples/http_server.rb +56 -0
  16. data/examples/http_server_multishot.rb +57 -0
  17. data/examples/http_server_simpler.rb +34 -0
  18. data/ext/um/extconf.rb +71 -0
  19. data/ext/um/iou.h +101 -0
  20. data/ext/um/op_ctx.c +138 -0
  21. data/ext/um/ring.c +755 -0
  22. data/ext/um/um.c +267 -0
  23. data/ext/um/um.h +97 -0
  24. data/ext/um/um_class.c +175 -0
  25. data/ext/um/um_ext.c +11 -0
  26. data/ext/um/um_op.c +87 -0
  27. data/ext/um/um_utils.c +23 -0
  28. data/lib/uringmachine/version.rb +3 -0
  29. data/lib/uringmachine.rb +8 -0
  30. data/test/helper.rb +70 -0
  31. data/test/test_iou.rb +876 -0
  32. data/test/test_um.rb +168 -0
  33. data/uringmachine.gemspec +27 -0
  34. data/vendor/liburing/.github/actions/codespell/stopwords +7 -0
  35. data/vendor/liburing/.github/pull_request_template.md +86 -0
  36. data/vendor/liburing/.github/workflows/build.yml +137 -0
  37. data/vendor/liburing/.github/workflows/codespell.yml +25 -0
  38. data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
  39. data/vendor/liburing/.gitignore +41 -0
  40. data/vendor/liburing/CHANGELOG +111 -0
  41. data/vendor/liburing/CITATION.cff +11 -0
  42. data/vendor/liburing/COPYING +502 -0
  43. data/vendor/liburing/COPYING.GPL +339 -0
  44. data/vendor/liburing/LICENSE +20 -0
  45. data/vendor/liburing/Makefile +96 -0
  46. data/vendor/liburing/Makefile.common +7 -0
  47. data/vendor/liburing/Makefile.quiet +11 -0
  48. data/vendor/liburing/README +106 -0
  49. data/vendor/liburing/SECURITY.md +6 -0
  50. data/vendor/liburing/configure +624 -0
  51. data/vendor/liburing/debian/README.Debian +7 -0
  52. data/vendor/liburing/debian/changelog +38 -0
  53. data/vendor/liburing/debian/control +39 -0
  54. data/vendor/liburing/debian/copyright +49 -0
  55. data/vendor/liburing/debian/liburing-dev.install +4 -0
  56. data/vendor/liburing/debian/liburing-dev.manpages +5 -0
  57. data/vendor/liburing/debian/liburing2.install +1 -0
  58. data/vendor/liburing/debian/liburing2.symbols +56 -0
  59. data/vendor/liburing/debian/patches/series +1 -0
  60. data/vendor/liburing/debian/rules +29 -0
  61. data/vendor/liburing/debian/source/format +1 -0
  62. data/vendor/liburing/debian/source/local-options +2 -0
  63. data/vendor/liburing/debian/source/options +1 -0
  64. data/vendor/liburing/debian/watch +3 -0
  65. data/vendor/liburing/examples/Makefile +53 -0
  66. data/vendor/liburing/examples/helpers.c +62 -0
  67. data/vendor/liburing/examples/helpers.h +7 -0
  68. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  69. data/vendor/liburing/examples/io_uring-cp.c +282 -0
  70. data/vendor/liburing/examples/io_uring-test.c +112 -0
  71. data/vendor/liburing/examples/io_uring-udp.c +403 -0
  72. data/vendor/liburing/examples/link-cp.c +193 -0
  73. data/vendor/liburing/examples/napi-busy-poll-client.c +509 -0
  74. data/vendor/liburing/examples/napi-busy-poll-server.c +450 -0
  75. data/vendor/liburing/examples/poll-bench.c +101 -0
  76. data/vendor/liburing/examples/proxy.c +2461 -0
  77. data/vendor/liburing/examples/proxy.h +102 -0
  78. data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
  79. data/vendor/liburing/examples/send-zerocopy.c +658 -0
  80. data/vendor/liburing/examples/ucontext-cp.c +258 -0
  81. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  82. data/vendor/liburing/liburing.pc.in +12 -0
  83. data/vendor/liburing/liburing.spec +66 -0
  84. data/vendor/liburing/make-debs.sh +55 -0
  85. data/vendor/liburing/src/Makefile +129 -0
  86. data/vendor/liburing/src/arch/aarch64/lib.h +47 -0
  87. data/vendor/liburing/src/arch/aarch64/syscall.h +91 -0
  88. data/vendor/liburing/src/arch/generic/lib.h +17 -0
  89. data/vendor/liburing/src/arch/generic/syscall.h +100 -0
  90. data/vendor/liburing/src/arch/riscv64/lib.h +48 -0
  91. data/vendor/liburing/src/arch/riscv64/syscall.h +100 -0
  92. data/vendor/liburing/src/arch/syscall-defs.h +94 -0
  93. data/vendor/liburing/src/arch/x86/lib.h +11 -0
  94. data/vendor/liburing/src/arch/x86/syscall.h +296 -0
  95. data/vendor/liburing/src/ffi.c +15 -0
  96. data/vendor/liburing/src/include/liburing/barrier.h +81 -0
  97. data/vendor/liburing/src/include/liburing/io_uring.h +818 -0
  98. data/vendor/liburing/src/include/liburing.h +1602 -0
  99. data/vendor/liburing/src/int_flags.h +11 -0
  100. data/vendor/liburing/src/lib.h +52 -0
  101. data/vendor/liburing/src/liburing-ffi.map +211 -0
  102. data/vendor/liburing/src/liburing.map +104 -0
  103. data/vendor/liburing/src/nolibc.c +55 -0
  104. data/vendor/liburing/src/queue.c +468 -0
  105. data/vendor/liburing/src/register.c +374 -0
  106. data/vendor/liburing/src/setup.c +689 -0
  107. data/vendor/liburing/src/setup.h +9 -0
  108. data/vendor/liburing/src/syscall.c +29 -0
  109. data/vendor/liburing/src/syscall.h +53 -0
  110. data/vendor/liburing/src/version.c +21 -0
  111. data/vendor/liburing/test/232c93d07b74.c +305 -0
  112. data/vendor/liburing/test/35fa71a030ca.c +329 -0
  113. data/vendor/liburing/test/500f9fbadef8.c +91 -0
  114. data/vendor/liburing/test/7ad0e4b2f83c.c +94 -0
  115. data/vendor/liburing/test/8a9973408177.c +107 -0
  116. data/vendor/liburing/test/917257daa0fe.c +54 -0
  117. data/vendor/liburing/test/Makefile +297 -0
  118. data/vendor/liburing/test/a0908ae19763.c +59 -0
  119. data/vendor/liburing/test/a4c0b3decb33.c +181 -0
  120. data/vendor/liburing/test/accept-link.c +255 -0
  121. data/vendor/liburing/test/accept-non-empty.c +256 -0
  122. data/vendor/liburing/test/accept-reuse.c +163 -0
  123. data/vendor/liburing/test/accept-test.c +83 -0
  124. data/vendor/liburing/test/accept.c +919 -0
  125. data/vendor/liburing/test/across-fork.c +284 -0
  126. data/vendor/liburing/test/b19062a56726.c +54 -0
  127. data/vendor/liburing/test/b5837bd5311d.c +78 -0
  128. data/vendor/liburing/test/bind-listen.c +408 -0
  129. data/vendor/liburing/test/buf-ring-nommap.c +123 -0
  130. data/vendor/liburing/test/buf-ring-put.c +83 -0
  131. data/vendor/liburing/test/buf-ring.c +473 -0
  132. data/vendor/liburing/test/ce593a6c480a.c +139 -0
  133. data/vendor/liburing/test/close-opath.c +123 -0
  134. data/vendor/liburing/test/config +14 -0
  135. data/vendor/liburing/test/connect-rep.c +204 -0
  136. data/vendor/liburing/test/connect.c +442 -0
  137. data/vendor/liburing/test/coredump.c +60 -0
  138. data/vendor/liburing/test/cq-full.c +97 -0
  139. data/vendor/liburing/test/cq-overflow.c +530 -0
  140. data/vendor/liburing/test/cq-peek-batch.c +103 -0
  141. data/vendor/liburing/test/cq-ready.c +95 -0
  142. data/vendor/liburing/test/cq-size.c +65 -0
  143. data/vendor/liburing/test/d4ae271dfaae.c +96 -0
  144. data/vendor/liburing/test/d77a67ed5f27.c +65 -0
  145. data/vendor/liburing/test/defer-taskrun.c +391 -0
  146. data/vendor/liburing/test/defer-tw-timeout.c +173 -0
  147. data/vendor/liburing/test/defer.c +319 -0
  148. data/vendor/liburing/test/double-poll-crash.c +195 -0
  149. data/vendor/liburing/test/drop-submit.c +94 -0
  150. data/vendor/liburing/test/eeed8b54e0df.c +120 -0
  151. data/vendor/liburing/test/empty-eownerdead.c +45 -0
  152. data/vendor/liburing/test/eploop.c +74 -0
  153. data/vendor/liburing/test/eventfd-disable.c +179 -0
  154. data/vendor/liburing/test/eventfd-reg.c +77 -0
  155. data/vendor/liburing/test/eventfd-ring.c +98 -0
  156. data/vendor/liburing/test/eventfd.c +113 -0
  157. data/vendor/liburing/test/evloop.c +73 -0
  158. data/vendor/liburing/test/exec-target.c +6 -0
  159. data/vendor/liburing/test/exit-no-cleanup.c +117 -0
  160. data/vendor/liburing/test/fadvise.c +202 -0
  161. data/vendor/liburing/test/fallocate.c +265 -0
  162. data/vendor/liburing/test/fc2a85cb02ef.c +132 -0
  163. data/vendor/liburing/test/fd-install.c +500 -0
  164. data/vendor/liburing/test/fd-pass.c +237 -0
  165. data/vendor/liburing/test/fdinfo.c +419 -0
  166. data/vendor/liburing/test/file-register.c +1189 -0
  167. data/vendor/liburing/test/file-update.c +231 -0
  168. data/vendor/liburing/test/file-verify.c +654 -0
  169. data/vendor/liburing/test/files-exit-hang-poll.c +114 -0
  170. data/vendor/liburing/test/files-exit-hang-timeout.c +137 -0
  171. data/vendor/liburing/test/fixed-buf-iter.c +115 -0
  172. data/vendor/liburing/test/fixed-buf-merge.c +101 -0
  173. data/vendor/liburing/test/fixed-hugepage.c +411 -0
  174. data/vendor/liburing/test/fixed-link.c +90 -0
  175. data/vendor/liburing/test/fixed-reuse.c +160 -0
  176. data/vendor/liburing/test/fpos.c +255 -0
  177. data/vendor/liburing/test/fsnotify.c +118 -0
  178. data/vendor/liburing/test/fsync.c +224 -0
  179. data/vendor/liburing/test/futex.c +571 -0
  180. data/vendor/liburing/test/hardlink.c +170 -0
  181. data/vendor/liburing/test/helpers.c +318 -0
  182. data/vendor/liburing/test/helpers.h +108 -0
  183. data/vendor/liburing/test/ignore-single-mmap.c +48 -0
  184. data/vendor/liburing/test/init-mem.c +164 -0
  185. data/vendor/liburing/test/io-cancel.c +561 -0
  186. data/vendor/liburing/test/io_uring_enter.c +264 -0
  187. data/vendor/liburing/test/io_uring_passthrough.c +482 -0
  188. data/vendor/liburing/test/io_uring_register.c +503 -0
  189. data/vendor/liburing/test/io_uring_setup.c +110 -0
  190. data/vendor/liburing/test/iopoll-leak.c +85 -0
  191. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  192. data/vendor/liburing/test/iopoll.c +465 -0
  193. data/vendor/liburing/test/lfs-openat-write.c +119 -0
  194. data/vendor/liburing/test/lfs-openat.c +273 -0
  195. data/vendor/liburing/test/link-timeout.c +1108 -0
  196. data/vendor/liburing/test/link.c +497 -0
  197. data/vendor/liburing/test/link_drain.c +255 -0
  198. data/vendor/liburing/test/madvise.c +195 -0
  199. data/vendor/liburing/test/min-timeout-wait.c +354 -0
  200. data/vendor/liburing/test/min-timeout.c +233 -0
  201. data/vendor/liburing/test/mkdir.c +112 -0
  202. data/vendor/liburing/test/msg-ring-fd.c +331 -0
  203. data/vendor/liburing/test/msg-ring-flags.c +212 -0
  204. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  205. data/vendor/liburing/test/msg-ring.c +467 -0
  206. data/vendor/liburing/test/multicqes_drain.c +429 -0
  207. data/vendor/liburing/test/napi-test.c +215 -0
  208. data/vendor/liburing/test/napi-test.sh +48 -0
  209. data/vendor/liburing/test/no-mmap-inval.c +42 -0
  210. data/vendor/liburing/test/nolibc.c +62 -0
  211. data/vendor/liburing/test/nop-all-sizes.c +99 -0
  212. data/vendor/liburing/test/nop.c +177 -0
  213. data/vendor/liburing/test/nvme.h +169 -0
  214. data/vendor/liburing/test/ooo-file-unreg.c +82 -0
  215. data/vendor/liburing/test/open-close.c +261 -0
  216. data/vendor/liburing/test/open-direct-link.c +188 -0
  217. data/vendor/liburing/test/open-direct-pick.c +180 -0
  218. data/vendor/liburing/test/openat2.c +312 -0
  219. data/vendor/liburing/test/personality.c +204 -0
  220. data/vendor/liburing/test/pipe-bug.c +95 -0
  221. data/vendor/liburing/test/pipe-eof.c +83 -0
  222. data/vendor/liburing/test/pipe-reuse.c +105 -0
  223. data/vendor/liburing/test/poll-cancel-all.c +496 -0
  224. data/vendor/liburing/test/poll-cancel-ton.c +135 -0
  225. data/vendor/liburing/test/poll-cancel.c +228 -0
  226. data/vendor/liburing/test/poll-link.c +221 -0
  227. data/vendor/liburing/test/poll-many.c +230 -0
  228. data/vendor/liburing/test/poll-mshot-overflow.c +265 -0
  229. data/vendor/liburing/test/poll-mshot-update.c +323 -0
  230. data/vendor/liburing/test/poll-race-mshot.c +276 -0
  231. data/vendor/liburing/test/poll-race.c +105 -0
  232. data/vendor/liburing/test/poll-ring.c +48 -0
  233. data/vendor/liburing/test/poll-v-poll.c +353 -0
  234. data/vendor/liburing/test/poll.c +327 -0
  235. data/vendor/liburing/test/probe.c +135 -0
  236. data/vendor/liburing/test/read-before-exit.c +129 -0
  237. data/vendor/liburing/test/read-mshot-empty.c +153 -0
  238. data/vendor/liburing/test/read-mshot.c +404 -0
  239. data/vendor/liburing/test/read-write.c +1013 -0
  240. data/vendor/liburing/test/recv-msgall-stream.c +398 -0
  241. data/vendor/liburing/test/recv-msgall.c +263 -0
  242. data/vendor/liburing/test/recv-multishot.c +602 -0
  243. data/vendor/liburing/test/recvsend_bundle.c +691 -0
  244. data/vendor/liburing/test/reg-fd-only.c +131 -0
  245. data/vendor/liburing/test/reg-hint.c +56 -0
  246. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  247. data/vendor/liburing/test/regbuf-merge.c +91 -0
  248. data/vendor/liburing/test/register-restrictions.c +633 -0
  249. data/vendor/liburing/test/rename.c +132 -0
  250. data/vendor/liburing/test/ring-leak.c +283 -0
  251. data/vendor/liburing/test/ring-leak2.c +249 -0
  252. data/vendor/liburing/test/ringbuf-read.c +196 -0
  253. data/vendor/liburing/test/ringbuf-status.c +242 -0
  254. data/vendor/liburing/test/rsrc_tags.c +461 -0
  255. data/vendor/liburing/test/runtests-loop.sh +16 -0
  256. data/vendor/liburing/test/runtests-quiet.sh +11 -0
  257. data/vendor/liburing/test/runtests.sh +168 -0
  258. data/vendor/liburing/test/rw_merge_test.c +98 -0
  259. data/vendor/liburing/test/self.c +91 -0
  260. data/vendor/liburing/test/send-zerocopy.c +971 -0
  261. data/vendor/liburing/test/send_recv.c +412 -0
  262. data/vendor/liburing/test/send_recvmsg.c +444 -0
  263. data/vendor/liburing/test/shared-wq.c +84 -0
  264. data/vendor/liburing/test/short-read.c +75 -0
  265. data/vendor/liburing/test/shutdown.c +165 -0
  266. data/vendor/liburing/test/sigfd-deadlock.c +88 -0
  267. data/vendor/liburing/test/single-issuer.c +169 -0
  268. data/vendor/liburing/test/skip-cqe.c +428 -0
  269. data/vendor/liburing/test/socket-getsetsock-cmd.c +346 -0
  270. data/vendor/liburing/test/socket-io-cmd.c +237 -0
  271. data/vendor/liburing/test/socket-rw-eagain.c +149 -0
  272. data/vendor/liburing/test/socket-rw-offset.c +149 -0
  273. data/vendor/liburing/test/socket-rw.c +137 -0
  274. data/vendor/liburing/test/socket.c +408 -0
  275. data/vendor/liburing/test/splice.c +512 -0
  276. data/vendor/liburing/test/sq-full-cpp.cc +45 -0
  277. data/vendor/liburing/test/sq-full.c +45 -0
  278. data/vendor/liburing/test/sq-poll-dup.c +211 -0
  279. data/vendor/liburing/test/sq-poll-kthread.c +169 -0
  280. data/vendor/liburing/test/sq-poll-share.c +138 -0
  281. data/vendor/liburing/test/sq-space_left.c +159 -0
  282. data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
  283. data/vendor/liburing/test/sqpoll-exec.c +132 -0
  284. data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
  285. data/vendor/liburing/test/sqpoll-sleep.c +69 -0
  286. data/vendor/liburing/test/statx.c +172 -0
  287. data/vendor/liburing/test/stdout.c +232 -0
  288. data/vendor/liburing/test/submit-and-wait.c +108 -0
  289. data/vendor/liburing/test/submit-link-fail.c +156 -0
  290. data/vendor/liburing/test/submit-reuse.c +237 -0
  291. data/vendor/liburing/test/symlink.c +117 -0
  292. data/vendor/liburing/test/sync-cancel.c +235 -0
  293. data/vendor/liburing/test/teardowns.c +58 -0
  294. data/vendor/liburing/test/test.h +36 -0
  295. data/vendor/liburing/test/thread-exit.c +143 -0
  296. data/vendor/liburing/test/timeout-new.c +256 -0
  297. data/vendor/liburing/test/timeout.c +1798 -0
  298. data/vendor/liburing/test/truncate.c +186 -0
  299. data/vendor/liburing/test/tty-write-dpoll.c +60 -0
  300. data/vendor/liburing/test/unlink.c +112 -0
  301. data/vendor/liburing/test/version.c +25 -0
  302. data/vendor/liburing/test/wait-timeout.c +287 -0
  303. data/vendor/liburing/test/waitid.c +373 -0
  304. data/vendor/liburing/test/wakeup-hang.c +162 -0
  305. data/vendor/liburing/test/wq-aff.c +146 -0
  306. data/vendor/liburing/test/xattr.c +442 -0
  307. metadata +412 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c2ac86e83825689e22080a04bf37ebfd553134d3209920d16f1ed413418847aa
4
+ data.tar.gz: a599878fb9a7745069b39efcb60c3610eea525693adadc2236d4ad06cbc9ad83
5
+ SHA512:
6
+ metadata.gz: 21f2236193e8df1799718ec96ffef7f72132fa57b3e61371544d35f1748459f1e2b9bb10a577ca3e9cee8e6666f2675aca4a9bd9f21c9f4923f8be633859cbe3
7
+ data.tar.gz: 2bfa3c754a5911edb2b9f2437c265fe978db9b39fcc05bce8c3047e81ce051e26a934014313edeb428ee6b40997ce490c50f9459a0e414b9aad2dc75530a31cf
@@ -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
@@ -0,0 +1,35 @@
1
+ name: Tests
2
+
3
+ on: [push, pull_request]
4
+
5
+ concurrency:
6
+ group: tests-${{ format('{0}-{1}', github.head_ref || github.run_number, github.job) }}
7
+ cancel-in-progress: true
8
+
9
+ jobs:
10
+ build:
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ # macos-latest uses arm64, macos-13 uses x86
15
+ os: [ubuntu-latest]
16
+ ruby: ['3.3', 'head']
17
+
18
+ name: ${{matrix.os}}, ${{matrix.ruby}}
19
+
20
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
21
+
22
+ runs-on: ${{matrix.os}}
23
+ steps:
24
+ - uses: actions/checkout@v4
25
+ with:
26
+ submodules: recursive
27
+
28
+ - uses: ruby/setup-ruby@v1
29
+ with:
30
+ ruby-version: ${{matrix.ruby}}
31
+ bundler-cache: true # 'bundle install' and cache
32
+ - name: Compile C-extension
33
+ run: bundle exec rake compile
34
+ - name: Run tests
35
+ run: bundle exec rake test
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/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # 2024-10-03 Version 0.1
2
+
3
+ The basic fiber scheduling stuff
4
+
5
+ - `#schedule`, `#interrupt`
6
+ - `#snooze`, `#yield`
7
+ - `#timeout`, `#sleep`
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,11 @@
1
+ # UringMachine
2
+
3
+ <a href="http://rubygems.org/gems/uringmachine">
4
+ <img src="https://badge.fury.io/rb/uringmachine.svg" alt="Ruby gem">
5
+ </a>
6
+ <a href="https://github.com/digital-fabric/uringmachine/actions?query=workflow%3ATests">
7
+ <img src="https://github.com/digital-fabric/uringmachine/workflows/Tests/badge.svg" alt="Tests">
8
+ </a>
9
+ <a href="https://github.com/digital-fabric/uringmachine/blob/master/LICENSE">
10
+ <img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="MIT License">
11
+ </a>
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("um_ext") do |ext|
9
+ ext.ext_dir = "ext/um"
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/uringmachine/version'
29
+ version = UM::VERSION
30
+
31
+ puts 'Building uringmachine...'
32
+ `gem build uringmachine.gemspec`
33
+
34
+ puts "Pushing uringmachine #{version}..."
35
+ `gem push uringmachine-#{version}.gem`
36
+
37
+ puts "Cleaning up..."
38
+ `rm *.gem`
39
+ end
data/TODO.md ADDED
File without changes
@@ -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,105 @@
1
+ require_relative '../lib/iou'
2
+ require 'socket'
3
+ require 'fiber'
4
+
5
+ class ::Fiber
6
+ attr_accessor :__op_id
7
+ end
8
+
9
+ class Scheduler
10
+ class Cancel < Exception
11
+ end
12
+
13
+ attr_reader :ring
14
+
15
+ def initialize
16
+ @ring = IOU::Ring.new
17
+ @runqueue = []
18
+ end
19
+
20
+ def switchpoint
21
+ while true
22
+ f, v = @runqueue.shift
23
+ if f
24
+ return f.transfer(v)
25
+ end
26
+
27
+ @ring.process_completions
28
+ end
29
+ end
30
+
31
+ def fiber_wait(op_id)
32
+ Fiber.current.__op_id = op_id
33
+ v = switchpoint
34
+ Fiber.current.__op_id = nil
35
+ raise v if v.is_a?(Exception)
36
+
37
+ v
38
+ end
39
+
40
+ def read(**args)
41
+ f = Fiber.current
42
+ id = ring.prep_read(**args) do |c|
43
+ if c[:result] < 0
44
+ @runqueue << [f, RuntimeError.new('error')]
45
+ else
46
+ @runqueue << [f, c[:buffer]]
47
+ end
48
+ end
49
+ fiber_wait(id)
50
+ end
51
+
52
+ def write(**args)
53
+ f = Fiber.current
54
+ id = ring.prep_write(**args) do |c|
55
+ if c[:result] < 0
56
+ @runqueue << [f, RuntimeError.new('error')]
57
+ else
58
+ @runqueue << [f, c[:result]]
59
+ end
60
+ end
61
+ fiber_wait(id)
62
+ end
63
+
64
+ def sleep(interval)
65
+ f = Fiber.current
66
+ id = ring.prep_timeout(interval: interval) do |c|
67
+ if c[:result] == Errno::ECANCELED::Errno
68
+ @runqueue << [f, c[:result]]
69
+ else
70
+ @runqueue << [f, c[:result]]
71
+ end
72
+ end
73
+ fiber_wait(id)
74
+ end
75
+
76
+ def cancel_fiber_op(f)
77
+ op_id = f.__op_id
78
+ if op_id
79
+ ring.prep_cancel(op_id)
80
+ end
81
+ end
82
+
83
+ def move_on_after(interval)
84
+ f = Fiber.current
85
+ cancel_id = ring.prep_timeout(interval: interval) do |c|
86
+ if c[:result] != Errno::ECANCELED::Errno
87
+ cancel_fiber_op(f)
88
+ end
89
+ end
90
+ v = yield
91
+ ring.prep_cancel(cancel_id)
92
+ v
93
+ end
94
+ end
95
+
96
+ s = Scheduler.new
97
+
98
+ puts "Going to sleep..."
99
+ s.sleep 3
100
+ puts "Woke up"
101
+
102
+ s.move_on_after(1) do
103
+ puts "Going to sleep (move on after 1 second)"
104
+ s.sleep 3
105
+ end
@@ -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,57 @@
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")
26
+ }
27
+
28
+ http_prep_read(fd, parser)
29
+ end
30
+
31
+ def http_prep_read(fd, parser)
32
+ id = @ring.prep_read(fd: fd, multishot: true, buffer_group: @bg_id) do |c|
33
+ if c[:result] > 0
34
+ parser << c[:buffer]
35
+ elsif c[:result] == 0
36
+ log "Connection closed by client on fd #{fd}"
37
+ else
38
+ if c[:result] != -Errno::ECANCELED::Errno
39
+ log "Got error #{c[:result]} on fd #{fd}, closing connection..."
40
+ end
41
+ @ring.prep_close(fd: fd) do |c|
42
+ log "Connection closed on fd #{fd}, result #{c[:result]}"
43
+ end
44
+ end
45
+ rescue HTTP::Parser::Error
46
+ puts "Error parsing, closing connection..."
47
+ @ring.prep_cancel(id)
48
+ end
49
+ end
50
+
51
+ def http_send_response(fd, body)
52
+ 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}"
53
+ @ring.prep_write(fd: fd, buffer: msg)
54
+ end
55
+
56
+ trap('SIGINT') { exit! }
57
+ @ring.process_completions_loop
@@ -0,0 +1,34 @@
1
+ require_relative '../lib/iou'
2
+ require 'socket'
3
+ require 'http/parser'
4
+
5
+ socket = TCPServer.open('127.0.0.1', 1234)
6
+ puts 'Listening on port 1234... (multishot read)'
7
+
8
+ @ring = IOU::Ring.new
9
+ @buffer_group = @ring.setup_buffer_ring(count: 1024, size: 4096)
10
+
11
+ @ring.prep_accept(fd: socket.fileno, multishot: true) do |c|
12
+ http_handle_connection(c[:result]) if c[:result] > 0
13
+ end
14
+
15
+ def http_handle_connection(fd)
16
+ parser = Http::Parser.new
17
+ parser.on_message_complete = -> { http_send_response(fd, "Hello, world!\n") }
18
+
19
+ @ring.prep_read(fd: fd, multishot: true, buffer_group: @buffer_group) do |c|
20
+ if c[:result] > 0
21
+ parser << c[:buffer]
22
+ else
23
+ puts "Connection closed on fd #{fd}"
24
+ end
25
+ end
26
+ end
27
+
28
+ def http_send_response(fd, body)
29
+ 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}"
30
+ @ring.prep_write(fd: fd, buffer: msg)
31
+ end
32
+
33
+ trap('SIGINT') { exit! }
34
+ @ring.process_completions_loop
data/ext/um/extconf.rb ADDED
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rubygems'
4
+ require 'mkmf'
5
+ require 'rbconfig'
6
+
7
+ dir_config 'um_ext'
8
+
9
+ KERNEL_INFO_RE = /Linux (\d)\.(\d+)(?:\.)?((?:\d+\.?)*)(?:\-)?([\w\-]+)?/
10
+ def get_config
11
+ config = { linux: !!(RUBY_PLATFORM =~ /linux/) }
12
+ raise "UringMachine 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 "UringMachine 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 UringMachine (\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 'um_ext'