uringmachine 0.24.0 → 0.26.0

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 (279) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +0 -3
  4. data/CHANGELOG.md +13 -0
  5. data/Gemfile +11 -0
  6. data/README.md +266 -112
  7. data/Rakefile +8 -0
  8. data/TODO.md +14 -21
  9. data/benchmark/common.rb +2 -0
  10. data/benchmark/openssl.rb +77 -0
  11. data/benchmark/openssl_socketpair.rb +112 -0
  12. data/benchmark/sqlite.rb +1 -1
  13. data/docs/design/buffer_pool.md +1 -1
  14. data/docs/wroclove.rb.md +52 -0
  15. data/ext/um/extconf.rb +15 -0
  16. data/ext/um/um.c +392 -358
  17. data/ext/um/um.h +48 -23
  18. data/ext/um/um_async_op.c +9 -8
  19. data/ext/um/um_async_op_class.c +34 -3
  20. data/ext/um/um_class.c +705 -19
  21. data/ext/um/um_const.c +31 -0
  22. data/ext/um/um_mutex_class.c +12 -0
  23. data/ext/um/um_op.c +15 -1
  24. data/ext/um/um_queue_class.c +16 -0
  25. data/ext/um/um_ssl.c +109 -0
  26. data/ext/um/um_stream.c +9 -8
  27. data/ext/um/um_sync.c +18 -11
  28. data/ext/um/um_utils.c +17 -8
  29. data/grant-2025/interim-report.md +1 -1
  30. data/grant-2025/journal.md +4 -4
  31. data/grant-2025/tasks.md +6 -4
  32. data/lib/uringmachine/dns_resolver.rb +38 -0
  33. data/lib/uringmachine/fiber_scheduler.rb +7 -5
  34. data/lib/uringmachine/version.rb +1 -1
  35. data/lib/uringmachine.rb +106 -6
  36. data/test/helper.rb +15 -0
  37. data/test/test_async_op.rb +3 -2
  38. data/test/test_fiber_scheduler.rb +41 -1
  39. data/test/test_ssl.rb +85 -0
  40. data/test/test_stream.rb +11 -0
  41. data/test/test_um.rb +445 -11
  42. data/uringmachine.gemspec +1 -7
  43. data/vendor/liburing/examples/send-zerocopy.c +43 -31
  44. data/vendor/liburing/examples/zcrx.c +260 -69
  45. data/vendor/liburing/liburing.spec +1 -1
  46. data/vendor/liburing/src/include/liburing/io_uring.h +12 -0
  47. data/vendor/liburing/src/include/liburing.h +3 -2
  48. data/vendor/liburing/src/liburing-ffi.map +4 -0
  49. data/vendor/liburing/src/liburing.map +4 -0
  50. data/vendor/liburing/src/queue.c +12 -0
  51. data/vendor/liburing/src/register.c +1 -0
  52. data/vendor/liburing/src/setup.c +15 -7
  53. data/vendor/liburing/test/Makefile +8 -4
  54. data/vendor/liburing/test/conn-unreach.c +1 -1
  55. data/vendor/liburing/test/epwait.c +32 -6
  56. data/vendor/liburing/test/io-wq-exit.c +131 -0
  57. data/vendor/liburing/test/iowait.c +1 -1
  58. data/vendor/liburing/test/min-timeout.c +3 -1
  59. data/vendor/liburing/test/open-close.c +39 -0
  60. data/vendor/liburing/test/poll-update-trigger.c +85 -0
  61. data/vendor/liburing/test/recvsend_bundle.c +14 -11
  62. data/vendor/liburing/test/sendzc-bug.c +146 -0
  63. data/vendor/liburing/test/sqe-mixed-nop.c +151 -7
  64. data/vendor/liburing/test/test.h +2 -0
  65. data/vendor/liburing/test/timestamp-bug.c +135 -0
  66. data/vendor/liburing/test/timestamp.c +5 -0
  67. data/vendor/liburing/test/vec-regbuf.c +136 -1
  68. metadata +38 -283
  69. data/vendor/libressl/.github/scripts/changelog.sh +0 -74
  70. data/vendor/libressl/.github/workflows/android.yml +0 -35
  71. data/vendor/libressl/.github/workflows/cifuzz.yml +0 -33
  72. data/vendor/libressl/.github/workflows/cmake-config.yml +0 -98
  73. data/vendor/libressl/.github/workflows/coverity.yml +0 -69
  74. data/vendor/libressl/.github/workflows/emscripten.yml +0 -71
  75. data/vendor/libressl/.github/workflows/fedora-rawhide.yml +0 -39
  76. data/vendor/libressl/.github/workflows/freebsd.yml +0 -71
  77. data/vendor/libressl/.github/workflows/linux.yml +0 -71
  78. data/vendor/libressl/.github/workflows/macos.yml +0 -37
  79. data/vendor/libressl/.github/workflows/release.yml +0 -81
  80. data/vendor/libressl/.github/workflows/rust-openssl.yml +0 -47
  81. data/vendor/libressl/.github/workflows/solaris.yml +0 -37
  82. data/vendor/libressl/.github/workflows/windows.yml +0 -70
  83. data/vendor/libressl/.gitignore +0 -333
  84. data/vendor/libressl/CMakeLists.txt +0 -581
  85. data/vendor/libressl/COPYING +0 -133
  86. data/vendor/libressl/ChangeLog +0 -3280
  87. data/vendor/libressl/FindLibreSSL.cmake +0 -232
  88. data/vendor/libressl/LibreSSLConfig.cmake.in +0 -36
  89. data/vendor/libressl/Makefile.am +0 -60
  90. data/vendor/libressl/Makefile.am.common +0 -20
  91. data/vendor/libressl/OPENBSD_BRANCH +0 -1
  92. data/vendor/libressl/README.md +0 -238
  93. data/vendor/libressl/README.mingw.md +0 -43
  94. data/vendor/libressl/apps/CMakeLists.txt +0 -18
  95. data/vendor/libressl/apps/Makefile.am +0 -5
  96. data/vendor/libressl/apps/nc/CMakeLists.txt +0 -67
  97. data/vendor/libressl/apps/nc/Makefile.am +0 -64
  98. data/vendor/libressl/apps/nc/compat/accept4.c +0 -17
  99. data/vendor/libressl/apps/nc/compat/readpassphrase.c +0 -205
  100. data/vendor/libressl/apps/nc/compat/socket.c +0 -29
  101. data/vendor/libressl/apps/nc/compat/sys/socket.h +0 -30
  102. data/vendor/libressl/apps/ocspcheck/CMakeLists.txt +0 -44
  103. data/vendor/libressl/apps/ocspcheck/Makefile.am +0 -45
  104. data/vendor/libressl/apps/ocspcheck/compat/.gitignore +0 -0
  105. data/vendor/libressl/apps/openssl/CMakeLists.txt +0 -97
  106. data/vendor/libressl/apps/openssl/Makefile.am +0 -108
  107. data/vendor/libressl/apps/openssl/apps_win.c +0 -138
  108. data/vendor/libressl/apps/openssl/certhash_win.c +0 -13
  109. data/vendor/libressl/apps/openssl/compat/clock_gettime_osx.c +0 -26
  110. data/vendor/libressl/apps/openssl/compat/poll_win.c +0 -329
  111. data/vendor/libressl/appveyor.yml +0 -53
  112. data/vendor/libressl/autogen.sh +0 -15
  113. data/vendor/libressl/check-release.sh +0 -86
  114. data/vendor/libressl/cmake_export_symbol.cmake +0 -71
  115. data/vendor/libressl/cmake_uninstall.cmake.in +0 -36
  116. data/vendor/libressl/config +0 -17
  117. data/vendor/libressl/configure.ac +0 -165
  118. data/vendor/libressl/crypto/CMakeLists.txt +0 -863
  119. data/vendor/libressl/crypto/Makefile.am +0 -962
  120. data/vendor/libressl/crypto/Makefile.am.arc4random +0 -46
  121. data/vendor/libressl/crypto/Makefile.am.elf-mips +0 -14
  122. data/vendor/libressl/crypto/Makefile.am.elf-mips64 +0 -14
  123. data/vendor/libressl/crypto/Makefile.am.elf-x86_64 +0 -35
  124. data/vendor/libressl/crypto/Makefile.am.macosx-x86_64 +0 -35
  125. data/vendor/libressl/crypto/Makefile.am.masm-x86_64 +0 -22
  126. data/vendor/libressl/crypto/Makefile.am.mingw64-x86_64 +0 -23
  127. data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_darwin.c +0 -60
  128. data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_linux.c +0 -62
  129. data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_none.c +0 -26
  130. data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_windows.c +0 -36
  131. data/vendor/libressl/crypto/arch/loongarch64/crypto_arch.h +0 -21
  132. data/vendor/libressl/crypto/arch/mips/crypto_arch.h +0 -21
  133. data/vendor/libressl/crypto/bn/arch/loongarch64/bn_arch.h +0 -23
  134. data/vendor/libressl/crypto/bn/arch/mips/bn_arch.h +0 -24
  135. data/vendor/libressl/crypto/compat/.gitignore +0 -31
  136. data/vendor/libressl/crypto/compat/arc4random.h +0 -41
  137. data/vendor/libressl/crypto/compat/b_win.c +0 -55
  138. data/vendor/libressl/crypto/compat/bsd-asprintf.c +0 -96
  139. data/vendor/libressl/crypto/compat/crypto_lock_win.c +0 -56
  140. data/vendor/libressl/crypto/compat/explicit_bzero_win.c +0 -13
  141. data/vendor/libressl/crypto/compat/freezero.c +0 -32
  142. data/vendor/libressl/crypto/compat/getdelim.c +0 -78
  143. data/vendor/libressl/crypto/compat/getline.c +0 -40
  144. data/vendor/libressl/crypto/compat/getopt_long.c +0 -528
  145. data/vendor/libressl/crypto/compat/getpagesize.c +0 -18
  146. data/vendor/libressl/crypto/compat/getprogname_linux.c +0 -23
  147. data/vendor/libressl/crypto/compat/getprogname_unimpl.c +0 -7
  148. data/vendor/libressl/crypto/compat/getprogname_windows.c +0 -13
  149. data/vendor/libressl/crypto/compat/posix_win.c +0 -296
  150. data/vendor/libressl/crypto/compat/syslog_r.c +0 -19
  151. data/vendor/libressl/crypto/compat/ui_openssl_win.c +0 -334
  152. data/vendor/libressl/dist.sh +0 -22
  153. data/vendor/libressl/gen-coverage-report.sh +0 -58
  154. data/vendor/libressl/gen-openbsd-tags.sh +0 -20
  155. data/vendor/libressl/include/CMakeLists.txt +0 -61
  156. data/vendor/libressl/include/Makefile.am +0 -79
  157. data/vendor/libressl/include/arch/loongarch64/opensslconf.h +0 -150
  158. data/vendor/libressl/include/arch/mips/opensslconf.h +0 -150
  159. data/vendor/libressl/include/compat/arpa/inet.h +0 -15
  160. data/vendor/libressl/include/compat/arpa/nameser.h +0 -25
  161. data/vendor/libressl/include/compat/cet.h +0 -19
  162. data/vendor/libressl/include/compat/dirent.h +0 -17
  163. data/vendor/libressl/include/compat/dirent_msvc.h +0 -611
  164. data/vendor/libressl/include/compat/endian.h +0 -161
  165. data/vendor/libressl/include/compat/err.h +0 -95
  166. data/vendor/libressl/include/compat/fcntl.h +0 -32
  167. data/vendor/libressl/include/compat/getopt.h +0 -50
  168. data/vendor/libressl/include/compat/limits.h +0 -25
  169. data/vendor/libressl/include/compat/netdb.h +0 -10
  170. data/vendor/libressl/include/compat/netinet/in.h +0 -19
  171. data/vendor/libressl/include/compat/netinet/ip.h +0 -49
  172. data/vendor/libressl/include/compat/netinet/tcp.h +0 -10
  173. data/vendor/libressl/include/compat/poll.h +0 -63
  174. data/vendor/libressl/include/compat/pthread.h +0 -122
  175. data/vendor/libressl/include/compat/readpassphrase.h +0 -44
  176. data/vendor/libressl/include/compat/resolv.h +0 -24
  177. data/vendor/libressl/include/compat/stdint.h +0 -31
  178. data/vendor/libressl/include/compat/stdio.h +0 -65
  179. data/vendor/libressl/include/compat/stdlib.h +0 -57
  180. data/vendor/libressl/include/compat/string.h +0 -98
  181. data/vendor/libressl/include/compat/sys/_null.h +0 -18
  182. data/vendor/libressl/include/compat/sys/ioctl.h +0 -11
  183. data/vendor/libressl/include/compat/sys/mman.h +0 -19
  184. data/vendor/libressl/include/compat/sys/param.h +0 -15
  185. data/vendor/libressl/include/compat/sys/queue.h +0 -536
  186. data/vendor/libressl/include/compat/sys/select.h +0 -10
  187. data/vendor/libressl/include/compat/sys/socket.h +0 -18
  188. data/vendor/libressl/include/compat/sys/stat.h +0 -129
  189. data/vendor/libressl/include/compat/sys/time.h +0 -37
  190. data/vendor/libressl/include/compat/sys/tree.h +0 -1006
  191. data/vendor/libressl/include/compat/sys/types.h +0 -69
  192. data/vendor/libressl/include/compat/sys/uio.h +0 -17
  193. data/vendor/libressl/include/compat/syslog.h +0 -38
  194. data/vendor/libressl/include/compat/time.h +0 -59
  195. data/vendor/libressl/include/compat/unistd.h +0 -83
  196. data/vendor/libressl/include/compat/win32netcompat.h +0 -57
  197. data/vendor/libressl/include/openssl/Makefile.am.tpl +0 -45
  198. data/vendor/libressl/libcrypto.pc.in +0 -28
  199. data/vendor/libressl/libressl.pub +0 -2
  200. data/vendor/libressl/libssl.pc.in +0 -28
  201. data/vendor/libressl/libtls.pc.in +0 -28
  202. data/vendor/libressl/m4/ax_add_fortify_source.m4 +0 -80
  203. data/vendor/libressl/m4/ax_check_compile_flag.m4 +0 -53
  204. data/vendor/libressl/m4/check-hardening-options.m4 +0 -110
  205. data/vendor/libressl/m4/check-libc.m4 +0 -189
  206. data/vendor/libressl/m4/check-os-options.m4 +0 -181
  207. data/vendor/libressl/m4/disable-compiler-warnings.m4 +0 -44
  208. data/vendor/libressl/man/CMakeLists.txt +0 -26
  209. data/vendor/libressl/man/links +0 -2780
  210. data/vendor/libressl/man/update_links.sh +0 -25
  211. data/vendor/libressl/openssl.pc.in +0 -11
  212. data/vendor/libressl/patches/bn_shift.patch +0 -34
  213. data/vendor/libressl/patches/crypto_arch.h.patch +0 -34
  214. data/vendor/libressl/patches/crypto_namespace.h.patch +0 -22
  215. data/vendor/libressl/patches/netcat.c.patch +0 -178
  216. data/vendor/libressl/patches/openssl.c.patch +0 -12
  217. data/vendor/libressl/patches/opensslfeatures.h.patch +0 -49
  218. data/vendor/libressl/patches/patch-amd64-crypto-cpu-caps.c.patch +0 -20
  219. data/vendor/libressl/patches/patch-i386-crypto-cpu-caps.c.patch +0 -20
  220. data/vendor/libressl/patches/speed.c.patch +0 -114
  221. data/vendor/libressl/patches/ssl_namespace.h.patch +0 -21
  222. data/vendor/libressl/patches/tls.h.patch +0 -16
  223. data/vendor/libressl/patches/tls_config.c.patch +0 -15
  224. data/vendor/libressl/patches/win32_amd64_bn_arch.h.patch +0 -28
  225. data/vendor/libressl/patches/windows_headers.patch +0 -80
  226. data/vendor/libressl/scripts/config.guess +0 -1774
  227. data/vendor/libressl/scripts/config.sub +0 -1907
  228. data/vendor/libressl/scripts/i686-w64-mingw32.cmake +0 -9
  229. data/vendor/libressl/scripts/test +0 -210
  230. data/vendor/libressl/scripts/wrap-compiler-for-flag-check +0 -31
  231. data/vendor/libressl/scripts/x86_64-w64-mingw32.cmake +0 -9
  232. data/vendor/libressl/ssl/CMakeLists.txt +0 -183
  233. data/vendor/libressl/ssl/Makefile.am +0 -187
  234. data/vendor/libressl/tests/CMakeLists.txt +0 -970
  235. data/vendor/libressl/tests/Makefile.am +0 -944
  236. data/vendor/libressl/tests/aeadtest.sh +0 -30
  237. data/vendor/libressl/tests/arc4randomforktest.sh +0 -21
  238. data/vendor/libressl/tests/asn1time_small.test +0 -10
  239. data/vendor/libressl/tests/cmake/CMakeLists.txt +0 -52
  240. data/vendor/libressl/tests/cmake/crypto.c +0 -7
  241. data/vendor/libressl/tests/cmake/ssl.c +0 -6
  242. data/vendor/libressl/tests/cmake/tls.c +0 -6
  243. data/vendor/libressl/tests/compat/pipe2.c +0 -186
  244. data/vendor/libressl/tests/dtlstest.sh +0 -28
  245. data/vendor/libressl/tests/evptest.sh +0 -22
  246. data/vendor/libressl/tests/keypairtest.sh +0 -27
  247. data/vendor/libressl/tests/mlkem_tests.sh +0 -39
  248. data/vendor/libressl/tests/ocsptest.bat +0 -25
  249. data/vendor/libressl/tests/ocsptest.sh +0 -23
  250. data/vendor/libressl/tests/openssl.cnf +0 -29
  251. data/vendor/libressl/tests/optionstest.c +0 -381
  252. data/vendor/libressl/tests/pidwraptest.c +0 -85
  253. data/vendor/libressl/tests/pidwraptest.sh +0 -26
  254. data/vendor/libressl/tests/quictest.bat +0 -27
  255. data/vendor/libressl/tests/quictest.sh +0 -30
  256. data/vendor/libressl/tests/renegotiation_test.bat +0 -27
  257. data/vendor/libressl/tests/renegotiation_test.sh +0 -30
  258. data/vendor/libressl/tests/rfc5280time_small.test +0 -10
  259. data/vendor/libressl/tests/servertest.bat +0 -27
  260. data/vendor/libressl/tests/servertest.sh +0 -30
  261. data/vendor/libressl/tests/shutdowntest.bat +0 -27
  262. data/vendor/libressl/tests/shutdowntest.sh +0 -30
  263. data/vendor/libressl/tests/ssltest.bat +0 -32
  264. data/vendor/libressl/tests/ssltest.sh +0 -48
  265. data/vendor/libressl/tests/testdsa.bat +0 -47
  266. data/vendor/libressl/tests/testdsa.sh +0 -57
  267. data/vendor/libressl/tests/testenc.bat +0 -85
  268. data/vendor/libressl/tests/testenc.sh +0 -93
  269. data/vendor/libressl/tests/testrsa.bat +0 -47
  270. data/vendor/libressl/tests/testrsa.sh +0 -57
  271. data/vendor/libressl/tests/testssl.bat +0 -171
  272. data/vendor/libressl/tests/tlstest.bat +0 -27
  273. data/vendor/libressl/tests/tlstest.sh +0 -28
  274. data/vendor/libressl/tls/CMakeLists.txt +0 -125
  275. data/vendor/libressl/tls/Makefile.am +0 -76
  276. data/vendor/libressl/tls/compat/ftruncate.c +0 -17
  277. data/vendor/libressl/tls/compat/pread.c +0 -29
  278. data/vendor/libressl/tls/compat/pwrite.c +0 -29
  279. data/vendor/libressl/update.sh +0 -460
data/ext/um/um_const.c CHANGED
@@ -14,10 +14,15 @@
14
14
  #include <net/if.h>
15
15
  #include <poll.h>
16
16
  #include <signal.h>
17
+ #include <sys/inotify.h>
17
18
 
18
19
  #define DEF_CONST_INT(mod, v) rb_define_const(mod, #v, INT2NUM(v))
19
20
 
20
21
  void um_define_net_constants(VALUE mod) {
22
+ DEF_CONST_INT(mod, STDIN_FILENO);
23
+ DEF_CONST_INT(mod, STDOUT_FILENO);
24
+ DEF_CONST_INT(mod, STDERR_FILENO);
25
+
21
26
  DEF_CONST_INT(mod, AT_FDCWD);
22
27
  DEF_CONST_INT(mod, AT_EMPTY_PATH);
23
28
  DEF_CONST_INT(mod, AT_NO_AUTOMOUNT);
@@ -437,4 +442,30 @@ void um_define_net_constants(VALUE mod) {
437
442
  DEF_CONST_INT(mod, SIGUSR2);
438
443
  DEF_CONST_INT(mod, SIGPWR);
439
444
  DEF_CONST_INT(mod, SIGPOLL);
445
+
446
+ DEF_CONST_INT(mod, IN_ACCESS);
447
+ DEF_CONST_INT(mod, IN_ATTRIB);
448
+ DEF_CONST_INT(mod, IN_CLOSE_WRITE);
449
+ DEF_CONST_INT(mod, IN_CLOSE_NOWRITE);
450
+ DEF_CONST_INT(mod, IN_CREATE);
451
+ DEF_CONST_INT(mod, IN_DELETE);
452
+ DEF_CONST_INT(mod, IN_DELETE_SELF);
453
+ DEF_CONST_INT(mod, IN_MODIFY);
454
+ DEF_CONST_INT(mod, IN_MOVE_SELF);
455
+ DEF_CONST_INT(mod, IN_MOVED_FROM);
456
+ DEF_CONST_INT(mod, IN_MOVED_TO);
457
+ DEF_CONST_INT(mod, IN_OPEN);
458
+ DEF_CONST_INT(mod, IN_ALL_EVENTS);
459
+ DEF_CONST_INT(mod, IN_MOVE);
460
+ DEF_CONST_INT(mod, IN_CLOSE);
461
+ DEF_CONST_INT(mod, IN_DONT_FOLLOW);
462
+ DEF_CONST_INT(mod, IN_EXCL_UNLINK);
463
+ DEF_CONST_INT(mod, IN_MASK_ADD);
464
+ DEF_CONST_INT(mod, IN_ONESHOT);
465
+ DEF_CONST_INT(mod, IN_ONLYDIR);
466
+ DEF_CONST_INT(mod, IN_MASK_CREATE);
467
+ DEF_CONST_INT(mod, IN_IGNORED);
468
+ DEF_CONST_INT(mod, IN_ISDIR);
469
+ DEF_CONST_INT(mod, IN_Q_OVERFLOW);
470
+ DEF_CONST_INT(mod, IN_UNMOUNT);
440
471
  }
@@ -1,6 +1,13 @@
1
1
  #include "um.h"
2
2
  #include <stdlib.h>
3
3
 
4
+ /*
5
+ * Document-class: UringMachine::Mutex
6
+ *
7
+ * A futex-based Mutex implementation for controlling access to a shared
8
+ * resource. The mutex can be used by calling `UringMachine#synchronize`.
9
+ */
10
+
4
11
  VALUE cMutex;
5
12
 
6
13
  static const rb_data_type_t Mutex_type = {
@@ -25,6 +32,11 @@ inline struct um_mutex *Mutex_data(VALUE self) {
25
32
  return mutex;
26
33
  }
27
34
 
35
+ /* Initializes a new mutex instance. The mutex can be used by calling
36
+ `UringMachine#synchronize`.
37
+ *
38
+ * @return [void]
39
+ */
28
40
  VALUE Mutex_initialize(VALUE self) {
29
41
  struct um_mutex *mutex = Mutex_data(self);
30
42
  um_mutex_init(mutex);
data/ext/um/um_op.c CHANGED
@@ -37,7 +37,6 @@ const char * um_op_kind_name(enum um_op_kind kind) {
37
37
  case OP_READ_MULTISHOT: return "OP_READ_MULTISHOT";
38
38
  case OP_RECV_MULTISHOT: return "OP_RECV_MULTISHOT";
39
39
  case OP_TIMEOUT_MULTISHOT: return "OP_TIMEOUT_MULTISHOT";
40
- case OP_SLEEP_MULTISHOT: return "OP_SLEEP_MULTISHOT";
41
40
  default: return "UNKNOWN_OP_KIND";
42
41
  }
43
42
  }
@@ -59,6 +58,7 @@ inline void um_op_transient_add(struct um *machine, struct um_op *op) {
59
58
  }
60
59
 
61
60
  inline void um_op_transient_remove(struct um *machine, struct um_op *op) {
61
+ op->flags &= ~OP_F_TRANSIENT;
62
62
  if (op->prev)
63
63
  op->prev->next = op->next;
64
64
  if (op->next)
@@ -185,3 +185,17 @@ inline void um_op_free(struct um *machine, struct um_op *op) {
185
185
  machine->op_freelist = op;
186
186
  machine->metrics.ops_free++;
187
187
  }
188
+
189
+ inline struct um_op *um_op_acquire(struct um *machine) {
190
+ return um_op_alloc(machine);
191
+ }
192
+
193
+ inline void um_op_release(struct um *machine, struct um_op *op) {
194
+ op->ref_count--;
195
+ if (op->ref_count) return;
196
+
197
+ if (op->flags & OP_F_FREE_IOVECS) free(op->iovecs);
198
+ if (op->flags & OP_F_MULTISHOT)
199
+ um_op_multishot_results_clear(machine, op);
200
+ um_op_free(machine, op);
201
+ }
@@ -1,6 +1,14 @@
1
1
  #include "um.h"
2
2
  #include <stdlib.h>
3
3
 
4
+ /*
5
+ * Document-class: UringMachine::Queue
6
+ *
7
+ * A futex-based Queue implementation. The queue can be manipulated by calling
8
+ * `UringMachine#push`, `UringMachine#unshift`, `UringMachine#pop` and
9
+ * `UringMachine#shift`.
10
+ */
11
+
4
12
  VALUE cQueue;
5
13
 
6
14
  static void Queue_mark(void *ptr) {
@@ -40,6 +48,10 @@ inline struct um_queue *Queue_data(VALUE self) {
40
48
  return queue;
41
49
  }
42
50
 
51
+ /* Initializes a new queue instance.
52
+ *
53
+ * @return [void]
54
+ */
43
55
  VALUE Queue_initialize(VALUE self) {
44
56
  struct um_queue *queue = Queue_data(self);
45
57
  RB_OBJ_WRITE(self, &queue->self, self);
@@ -47,6 +59,10 @@ VALUE Queue_initialize(VALUE self) {
47
59
  return self;
48
60
  }
49
61
 
62
+ /* Returns the number of items in the queue.
63
+ *
64
+ * @return [Integer] number of items in the queue
65
+ */
50
66
  VALUE Queue_count(VALUE self) {
51
67
  struct um_queue *queue = Queue_data(self);
52
68
  return UINT2NUM(queue->count);
data/ext/um/um_ssl.c ADDED
@@ -0,0 +1,109 @@
1
+ #include "um.h"
2
+ #include <openssl/ssl.h>
3
+ #include <openssl/bio.h>
4
+
5
+ #define IDX_BIO_DATA_MACHINE 1
6
+ #define IDX_BIO_DATA_FD 2
7
+
8
+ static int um_bio_read(BIO *bio, char *buf, int blen)
9
+ {
10
+ struct um *machine = (struct um *)BIO_get_ex_data(bio, IDX_BIO_DATA_MACHINE);
11
+ long fd = (long)BIO_get_ex_data(bio, IDX_BIO_DATA_FD);
12
+ return (int)um_read_raw(machine, fd, buf, blen);
13
+ }
14
+
15
+ static int um_bio_write(BIO *bio, const char *buf, int blen)
16
+ {
17
+ struct um *machine = (struct um *)BIO_get_ex_data(bio, IDX_BIO_DATA_MACHINE);
18
+ long fd = (long)BIO_get_ex_data(bio, IDX_BIO_DATA_FD);
19
+ return (int)um_write_raw(machine, fd, buf, blen);
20
+ }
21
+
22
+ static long um_bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
23
+ {
24
+ switch(cmd) {
25
+ case BIO_CTRL_GET_CLOSE:
26
+ return (long)BIO_get_shutdown(bio);
27
+ case BIO_CTRL_SET_CLOSE:
28
+ BIO_set_shutdown(bio, (int)num);
29
+ return 1;
30
+ case BIO_CTRL_FLUSH:
31
+ // we don't buffer writes, so noop
32
+ return 1;
33
+ default:
34
+ return 0;
35
+ }
36
+ }
37
+
38
+ BIO_METHOD *um_ssl_create_bio_method(void)
39
+ {
40
+ BIO_METHOD *m = BIO_meth_new(BIO_TYPE_MEM, "UringMachine BIO");
41
+ if(m) {
42
+ BIO_meth_set_write(m, &um_bio_write);
43
+ BIO_meth_set_read(m, &um_bio_read);
44
+ BIO_meth_set_ctrl(m, &um_bio_ctrl);
45
+ }
46
+ else
47
+ rb_raise(eUMError, "Failed to set SSL BIO");
48
+ return m;
49
+ }
50
+
51
+
52
+ static BIO_METHOD *um_bio_method = NULL;
53
+ static ID id_ivar_um_bio;
54
+
55
+ void um_ssl_set_bio(struct um *machine, VALUE ssl_obj)
56
+ {
57
+ if (!um_bio_method) {
58
+ um_bio_method = um_ssl_create_bio_method();
59
+ id_ivar_um_bio = rb_intern_const("@__um_bio__");
60
+ }
61
+
62
+ long fd = NUM2LONG(rb_funcall(ssl_obj, rb_intern_const("fileno"), 0));
63
+ rb_ivar_set(ssl_obj, id_ivar_um_bio, Qtrue);
64
+
65
+ BIO *bio = BIO_new(um_bio_method);
66
+ if(!bio)
67
+ rb_raise(eUMError, "Failed to create custom BIO");
68
+
69
+ int ret = BIO_set_ex_data(bio, IDX_BIO_DATA_MACHINE, (void *)machine);
70
+ if (!ret)
71
+ rb_raise(eUMError, "Failed to set BIO metadata");
72
+
73
+ ret = BIO_set_ex_data(bio, IDX_BIO_DATA_FD, (void *)fd);
74
+ if (!ret)
75
+ rb_raise(eUMError, "Failed to set BIO metadata");
76
+
77
+ SSL *ssl = RTYPEDDATA_GET_DATA(ssl_obj);
78
+ BIO_up_ref(bio);
79
+ SSL_set0_rbio(ssl, bio);
80
+ SSL_set0_wbio(ssl, bio);
81
+ }
82
+
83
+ int um_ssl_read(struct um *machine, VALUE ssl_obj, VALUE buf, int maxlen) {
84
+ SSL *ssl = RTYPEDDATA_GET_DATA(ssl_obj);
85
+ void *ptr = um_prepare_read_buffer(buf, maxlen, 0);
86
+ int ret = SSL_read(ssl, ptr, maxlen);
87
+ if (ret > 0) {
88
+ um_update_read_buffer(buf, 0, ret);
89
+ }
90
+ else {
91
+ rb_raise(eUMError, "Failed to read");
92
+ }
93
+ return ret;
94
+ }
95
+
96
+ int um_ssl_write(struct um *machine, VALUE ssl_obj, VALUE buf, int len) {
97
+ SSL *ssl = RTYPEDDATA_GET_DATA(ssl_obj);
98
+ const void *base;
99
+ size_t size;
100
+ um_get_buffer_bytes_for_writing(buf, &base, &size, true);
101
+ if ((len == (int)-1) || (len > (int)size)) len = (int)size;
102
+ if (unlikely(!len)) return INT2NUM(0);
103
+
104
+ int ret = SSL_write(ssl, base, len);
105
+ if (ret <= 0) {
106
+ rb_raise(eUMError, "Failed to read");
107
+ }
108
+ return ret;
109
+ }
data/ext/um/um_stream.c CHANGED
@@ -113,7 +113,7 @@ VALUE resp_get_line(struct um_stream *stream, VALUE out_buffer) {
113
113
  stream->pos += len + 2;
114
114
 
115
115
  if (NIL_P(out_buffer)) {
116
- VALUE str = rb_str_new(start, len + 1);
116
+ VALUE str = rb_interned_str(start, len + 1);
117
117
  rb_str_set_len(str, len);
118
118
  RSTRING_PTR(str)[len] = 0;
119
119
  RB_GC_GUARD(str);
@@ -170,7 +170,8 @@ VALUE resp_decode_array(struct um_stream *stream, VALUE out_buffer, ulong len) {
170
170
  VALUE array = rb_ary_new2(len);
171
171
 
172
172
  for (ulong i = 0; i < len; i++) {
173
- VALUE value = resp_decode(stream, out_buffer);
173
+ VALUE buf = rb_str_new(NULL, 100);
174
+ VALUE value = resp_decode(stream, buf);
174
175
  rb_ary_push(array, value);
175
176
  RB_GC_GUARD(value);
176
177
  }
@@ -180,11 +181,11 @@ VALUE resp_decode_array(struct um_stream *stream, VALUE out_buffer, ulong len) {
180
181
  }
181
182
 
182
183
  static inline VALUE resp_decode_simple_string(char *ptr, ulong len) {
183
- return rb_str_new(ptr + 1, len - 1);
184
+ return rb_interned_str(ptr + 1, len - 1);
184
185
  }
185
186
 
186
- static inline VALUE resp_decode_string(struct um_stream *stream, VALUE out_buffer, ulong len) {
187
- return resp_get_string(stream, len, out_buffer);
187
+ static inline VALUE resp_decode_string(struct um_stream *stream, ulong len) {
188
+ return resp_get_string(stream, len, Qnil);
188
189
  }
189
190
 
190
191
  static inline VALUE resp_decode_string_with_encoding(struct um_stream *stream, VALUE out_buffer, ulong len) {
@@ -210,7 +211,7 @@ static inline VALUE resp_decode_simple_error(char *ptr, ulong len) {
210
211
  static ID ID_new = 0;
211
212
  if (!ID_new) ID_new = rb_intern("new");
212
213
 
213
- VALUE msg = rb_str_new(ptr + 1, len - 1);
214
+ VALUE msg = rb_interned_str(ptr + 1, len - 1);
214
215
  VALUE err = rb_funcall(eStreamRESPError, ID_new, 1, msg);
215
216
  RB_GC_GUARD(msg);
216
217
  return err;
@@ -220,7 +221,7 @@ static inline VALUE resp_decode_error(struct um_stream *stream, VALUE out_buffer
220
221
  static ID ID_new = 0;
221
222
  if (!ID_new) ID_new = rb_intern("new");
222
223
 
223
- VALUE msg = resp_decode_string(stream, out_buffer, len);
224
+ VALUE msg = resp_decode_string(stream, len);
224
225
  VALUE err = rb_funcall(eStreamRESPError, ID_new, 1, msg);
225
226
  RB_GC_GUARD(msg);
226
227
  return err;
@@ -251,7 +252,7 @@ VALUE resp_decode(struct um_stream *stream, VALUE out_buffer) {
251
252
  return resp_decode_simple_string(ptr, len);
252
253
  case '$': // string
253
254
  data_len = resp_parse_length_field(ptr, len);
254
- return resp_decode_string(stream, out_buffer, data_len);
255
+ return resp_decode_string(stream, data_len);
255
256
  case '=': // string with encoding
256
257
  data_len = resp_parse_length_field(ptr, len);
257
258
  return resp_decode_string_with_encoding(stream, out_buffer, data_len);
data/ext/um/um_sync.c CHANGED
@@ -6,35 +6,42 @@
6
6
 
7
7
  // The value argument is the current (known) futex value.
8
8
  void um_futex_wait(struct um *machine, uint32_t *futex, uint32_t value) {
9
- struct um_op op;
10
- um_prep_op(machine, &op, OP_FUTEX_WAIT, 0);
11
- struct io_uring_sqe *sqe = um_get_sqe(machine, &op);
9
+ struct um_op *op = um_op_acquire(machine);
10
+ um_prep_op(machine, op, OP_FUTEX_WAIT, 2, 0);
11
+ struct io_uring_sqe *sqe = um_get_sqe(machine, op);
12
12
  io_uring_prep_futex_wait(
13
13
  sqe, (uint32_t *)futex, value, FUTEX_BITSET_MATCH_ANY, FUTEX2_SIZE_U32, 0
14
14
  );
15
15
 
16
16
  VALUE ret = um_yield(machine);
17
- if (!um_op_completed_p(&op))
18
- um_cancel_and_wait(machine, &op);
17
+
18
+ if (unlikely(!OP_CQE_DONE_P(op)))
19
+ um_cancel_op_and_await_cqe(machine, op);
19
20
  else {
20
- if (op.result.res != -EAGAIN)
21
- um_raise_on_error_result(op.result.res);
21
+ int res = op->result.res;
22
+ if (res != -EAGAIN) {
23
+ um_op_release(machine, op);
24
+ um_raise_on_error_result(res);
25
+ }
22
26
  }
27
+ um_op_release(machine, op);
23
28
 
24
29
  RAISE_IF_EXCEPTION(ret);
25
30
  RB_GC_GUARD(ret);
26
31
  }
27
32
 
28
33
  void um_futex_wake(struct um *machine, uint32_t *futex, uint32_t num_waiters) {
29
- struct um_op op;
30
- um_prep_op(machine, &op, OP_FUTEX_WAKE, 0);
31
- struct io_uring_sqe *sqe = um_get_sqe(machine, &op);
34
+ struct um_op *op = um_op_acquire(machine);
35
+ um_prep_op(machine, op, OP_FUTEX_WAKE, 2, 0);
36
+ struct io_uring_sqe *sqe = um_get_sqe(machine, op);
32
37
  io_uring_prep_futex_wake(
33
38
  sqe, (uint32_t *)futex, num_waiters, FUTEX_BITSET_MATCH_ANY, FUTEX2_SIZE_U32, 0
34
39
  );
35
40
 
36
41
  VALUE ret = um_yield(machine);
37
- um_check_completion(machine, &op);
42
+
43
+ um_verify_op_completion(machine, op, true);
44
+ um_op_release(machine, op);
38
45
 
39
46
  RAISE_IF_EXCEPTION(ret);
40
47
  RB_GC_GUARD(ret);
data/ext/um/um_utils.c CHANGED
@@ -17,21 +17,20 @@ inline double um_timestamp_to_double(__s64 tv_sec, __u32 tv_nsec) {
17
17
  return (double)tv_sec + ((double)tv_nsec) / 1000000000;
18
18
  }
19
19
 
20
- inline double um_get_time_cpu() {
20
+ inline double um_get_time_cpu(void) {
21
21
  struct timespec ts;
22
22
  if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts)) return -1.0;
23
23
 
24
24
  return um_timestamp_to_double(ts.tv_sec, ts.tv_nsec);
25
25
  }
26
26
 
27
- inline double um_get_time_monotonic() {
27
+ inline double um_get_time_monotonic(void) {
28
28
  struct timespec ts;
29
29
  if (clock_gettime(CLOCK_MONOTONIC, &ts)) return -1.0;
30
30
 
31
31
  return um_timestamp_to_double(ts.tv_sec, ts.tv_nsec);
32
32
  }
33
33
 
34
-
35
34
  #define RAISE_EXCEPTION(e) rb_funcall(e, ID_invoke, 0);
36
35
 
37
36
  inline int um_value_is_exception_p(VALUE v) {
@@ -93,21 +92,27 @@ static inline void adjust_read_buffer_len(VALUE buffer, int result, ssize_t ofs)
93
92
  }
94
93
  }
95
94
 
96
- inline void um_update_read_buffer(struct um *machine, VALUE buffer, ssize_t buffer_offset, __s32 result, __u32 flags) {
95
+ inline void um_update_read_buffer(VALUE buffer, ssize_t buffer_offset, __s32 result) {
97
96
  if (!result) return;
98
97
 
99
98
  adjust_read_buffer_len(buffer, result, buffer_offset);
100
99
  }
101
100
 
102
- inline void um_get_buffer_bytes_for_writing(VALUE buffer, const void **base, size_t *size) {
101
+ // returns false if buffer is invalid and raise_on_bad_buffer is false
102
+ inline int um_get_buffer_bytes_for_writing(VALUE buffer, const void **base, size_t *size, int raise_on_bad_buffer) {
103
103
  if (TYPE(buffer) == T_STRING) {
104
104
  *base = RSTRING_PTR(buffer);
105
105
  *size = RSTRING_LEN(buffer);
106
106
  }
107
107
  else if (IO_BUFFER_P(buffer))
108
108
  rb_io_buffer_get_bytes_for_reading(buffer, base, size); // reading *from* buffer
109
- else
110
- um_raise_internal_error("Invalid buffer provided");
109
+ else {
110
+ if (raise_on_bad_buffer)
111
+ um_raise_internal_error("Invalid buffer provided");
112
+ else
113
+ return false;
114
+ }
115
+ return true;
111
116
  }
112
117
 
113
118
  int um_setup_buffer_ring(struct um *machine, unsigned size, unsigned count) {
@@ -205,7 +210,11 @@ inline struct iovec *um_alloc_iovecs_for_writing(int argc, VALUE *argv, size_t *
205
210
  size_t len = 0;
206
211
 
207
212
  for (int i = 0; i < argc; i++) {
208
- um_get_buffer_bytes_for_writing(argv[i], (const void **)&iovecs[i].iov_base, &iovecs[i].iov_len);
213
+ int ok = um_get_buffer_bytes_for_writing(argv[i], (const void **)&iovecs[i].iov_base, &iovecs[i].iov_len, false);
214
+ if (unlikely(!ok)) {
215
+ free(iovecs);
216
+ um_raise_internal_error("Invalid buffer provided");
217
+ }
209
218
  len += iovecs[i].iov_len;
210
219
  }
211
220
  if (total_len) *total_len = len;
@@ -1,6 +1,6 @@
1
1
  # Interim Report for Ruby Association Grant Program 2025
2
2
 
3
- ## Project Summary
3
+ ## Project Summary
4
4
 
5
5
  Io_uring is a relatively new Linux API, permitting the invocation of Linux
6
6
  system calls asynchronously. UringMachine is a gem that brings low-level access
@@ -574,7 +574,7 @@ Ruby I/O layer. Some interesting warts in the Ruby `IO` implementation:
574
574
  - Implemented sidecar mode - the basic idea is that UringMachine starts an
575
575
  auxiliary thread that loops entering the kernel with a call to
576
576
  `io_uring_enter` in order to make CQEs available. On return from the system
577
- call, it signals through a futex that ready CQEs can be processed.
577
+ call, it signals through a futex that ready CQEs can be processed.
578
578
 
579
579
  On fiber switch, the next fiber to run is shifted from the runqueue. If the
580
580
  runqueue is empty, the UringMachine will wait for the signal, and then process
@@ -590,7 +590,7 @@ Ruby I/O layer. Some interesting warts in the Ruby `IO` implementation:
590
590
 
591
591
  # 2026-01-07
592
592
 
593
- - In the last week I've been working on implementing a buffer pool
593
+ - In the last week I've been working on implementing a buffer pool
594
594
  with automatic buffer manangement. I've been contemplating the design for a
595
595
  few weeks already, and after the vacation has decided the idea is solid enough
596
596
  for me to start writing some code. But let me back up and explain what I'm
@@ -601,7 +601,7 @@ Ruby I/O layer. Some interesting warts in the Ruby `IO` implementation:
601
601
  buffers for reading or receiving repeatedly from an fd, letting the
602
602
  application know with each CQE which buffer was used and with how much data.
603
603
  This is particularly useful when dealing with bursts of incoming data.
604
-
604
+
605
605
  The application initiates multishot read/recv operations on each connection,
606
606
  and the kernel has at its disposition a pool of application-provided buffers
607
607
  it can use whenever a chunk of data is read / received. So the kernel consumes
@@ -631,4 +631,4 @@ Ruby I/O layer. Some interesting warts in the Ruby `IO` implementation:
631
631
  ID will continue where the previous one left off. So it's great that buffer
632
632
  space can be used fully by the kernel, but the application is required to keep
633
633
  track of a "cursor" for each buffer.
634
-
634
+
data/grant-2025/tasks.md CHANGED
@@ -20,7 +20,7 @@
20
20
 
21
21
  - [v] Make writev automatically complete partial writes
22
22
 
23
- - [ ] Add inotify API
23
+ - [v] Add inotify API
24
24
 
25
25
  https://www.man7.org/linux/man-pages/man7/inotify.7.html
26
26
 
@@ -134,10 +134,12 @@
134
134
  - [v] hook for close
135
135
  - [ ] hooks for send/recv/sendmsg/recvmsg
136
136
 
137
- - [ ] SSL
138
- - [ ] openssl gem: custom BIO?
137
+ - [v] SSL
138
+ - [v] setup custom BIO
139
+ - [v] SSL read/write methods
139
140
 
140
- - curl: https://github.com/curl/curl/blob/5f4cd4c689c822ce957bb415076f0c78e5f474b5/lib/vtls/openssl.c#L786-L803
141
+ - [v] RDoc
142
+ - [v] Rewrite README to show some examples
141
143
 
142
144
  - [ ] UringMachine website
143
145
  - [ ] domain: uringmachine.dev
@@ -3,7 +3,13 @@
3
3
  require 'resolv'
4
4
 
5
5
  class UringMachine
6
+ # A basic DNS resolver implementation.
6
7
  class DNSResolver
8
+
9
+ # Initializes the DNS resolver.
10
+ #
11
+ # @param machine [UringMachine] UringMachine instance
12
+ # @return [void]
7
13
  def initialize(machine)
8
14
  @machine = machine
9
15
  @requests = UM::Queue.new
@@ -12,11 +18,19 @@ class UringMachine
12
18
  @last_id = 0
13
19
  end
14
20
 
21
+ # Resolves the given hostname.
22
+ #
23
+ # @param hostname [String] hostname
24
+ # @param type [Symbol] DNS record type
25
+ # @return [String] IP address
15
26
  def resolve(hostname, type)
16
27
  @machine.push(@requests, [hostname, type, Fiber.current])
17
28
  @machine.yield
18
29
  end
19
30
 
31
+ private
32
+
33
+ # Handles resolve requests as they come.
20
34
  def handle_requests_loop
21
35
  while true
22
36
  hostname, type, fiber = @machine.shift(@requests)
@@ -25,6 +39,9 @@ class UringMachine
25
39
  end
26
40
  end
27
41
 
42
+ # Returns an array of nameservers.
43
+ #
44
+ # @return [Array<String>] name servers
28
45
  def get_nameservers
29
46
  nameservers = []
30
47
  IO.readlines('/etc/resolv.conf').each do |line|
@@ -35,10 +52,16 @@ class UringMachine
35
52
  nameservers
36
53
  end
37
54
 
55
+ # Returns a DNS socket fd connected to a name server.
56
+ #
57
+ # @return [Integer] fd
38
58
  def socket_fd
39
59
  @socket_fd ||= prepare_socket
40
60
  end
41
61
 
62
+ # Prepares a socket fd connected to a name server.
63
+ #
64
+ # @return [Integer] fd
42
65
  def prepare_socket
43
66
  fd = @machine.socket(UM::AF_INET, UM::SOCK_DGRAM, 0, 0)
44
67
  @machine.bind(fd, '0.0.0.0', 0)
@@ -46,6 +69,12 @@ class UringMachine
46
69
  fd
47
70
  end
48
71
 
72
+ # Resolves a DNS query.
73
+ #
74
+ # @param hostname [String] hostname
75
+ # @param type [Symbol] DNS record type
76
+ # @param try_count [Integer] retry counter
77
+ # @return [Array<String>] array of addresses
49
78
  def do_resolve(hostname, type, try_count = 0)
50
79
  fd = socket_fd
51
80
  req = prepare_request_packet(hostname, type)
@@ -67,6 +96,11 @@ class UringMachine
67
96
  addrs
68
97
  end
69
98
 
99
+ # Prepares a request packet.
100
+ #
101
+ # @param hostname [String] hostname
102
+ # @param type [Symbol] DNS record type
103
+ # @return [Resolv::DNS::Message]
70
104
  def prepare_request_packet(hostname, type)
71
105
  msg = Resolv::DNS::Message.new
72
106
  msg.id = (@last_id += 1)
@@ -75,6 +109,10 @@ class UringMachine
75
109
  msg
76
110
  end
77
111
 
112
+ # Returns the message type class.
113
+ #
114
+ # @param type [Symbol] DNS record type
115
+ # @return [Class] message type class
78
116
  def msg_type(type)
79
117
  # TODO: add support for other types
80
118
  Resolv::DNS::Resource::IN::A
@@ -5,6 +5,7 @@ require 'etc'
5
5
  require 'uringmachine'
6
6
 
7
7
  class UringMachine
8
+
8
9
  # Implements a worker thread pool for running blocking operations. Worker
9
10
  # threads are started as needed. Worker thread count is limited to the number
10
11
  # of CPU cores available.
@@ -12,6 +13,7 @@ class UringMachine
12
13
 
13
14
  # Initializes a new worker pool.
14
15
  #
16
+ # @param max_workers [Integer] maximum worker thread count
15
17
  # @return [void]
16
18
  def initialize(max_workers = Etc.nprocessors)
17
19
  @max_workers = max_workers
@@ -71,9 +73,9 @@ class UringMachine
71
73
  end
72
74
  end
73
75
 
74
- # UringMachine::FiberScheduler implements the Fiber::Scheduler interface for
75
- # creating fiber-based concurrent applications in Ruby, in tight integration
76
- # with the standard Ruby I/O and locking APIs.
76
+ # Implements the `Fiber::Scheduler` interface for creating fiber-based
77
+ # concurrent applications in Ruby, in tight integration with the standard Ruby
78
+ # I/O and locking APIs.
77
79
  class FiberScheduler
78
80
 
79
81
  # The blocking operation thread pool is shared by all fiber schedulers.
@@ -198,7 +200,7 @@ class UringMachine
198
200
  # @param io [IO] IO object
199
201
  # @param events [Number] readiness bitmask
200
202
  # @param timeout [Number, nil] optional timeout
201
- # @param return
203
+ # @return [void]
202
204
  def io_wait(io, events, timeout = nil)
203
205
  timeout ||= io.timeout
204
206
  if timeout
@@ -314,7 +316,7 @@ class UringMachine
314
316
  #
315
317
  # @param io [IO] IO object
316
318
  # @param buffer [IO::Buffer] write buffer
317
- # @param length [Integer] file offset
319
+ # @param from [Integer] file offset
318
320
  # @param length [Integer] write length
319
321
  # @param offset [Integer] buffer offset
320
322
  # @return [Integer] bytes written
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class UringMachine
4
- VERSION = '0.24.0'
4
+ VERSION = '0.26.0'
5
5
  end