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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.gitmodules +0 -3
- data/CHANGELOG.md +13 -0
- data/Gemfile +11 -0
- data/README.md +266 -112
- data/Rakefile +8 -0
- data/TODO.md +14 -21
- data/benchmark/common.rb +2 -0
- data/benchmark/openssl.rb +77 -0
- data/benchmark/openssl_socketpair.rb +112 -0
- data/benchmark/sqlite.rb +1 -1
- data/docs/design/buffer_pool.md +1 -1
- data/docs/wroclove.rb.md +52 -0
- data/ext/um/extconf.rb +15 -0
- data/ext/um/um.c +392 -358
- data/ext/um/um.h +48 -23
- data/ext/um/um_async_op.c +9 -8
- data/ext/um/um_async_op_class.c +34 -3
- data/ext/um/um_class.c +705 -19
- data/ext/um/um_const.c +31 -0
- data/ext/um/um_mutex_class.c +12 -0
- data/ext/um/um_op.c +15 -1
- data/ext/um/um_queue_class.c +16 -0
- data/ext/um/um_ssl.c +109 -0
- data/ext/um/um_stream.c +9 -8
- data/ext/um/um_sync.c +18 -11
- data/ext/um/um_utils.c +17 -8
- data/grant-2025/interim-report.md +1 -1
- data/grant-2025/journal.md +4 -4
- data/grant-2025/tasks.md +6 -4
- data/lib/uringmachine/dns_resolver.rb +38 -0
- data/lib/uringmachine/fiber_scheduler.rb +7 -5
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +106 -6
- data/test/helper.rb +15 -0
- data/test/test_async_op.rb +3 -2
- data/test/test_fiber_scheduler.rb +41 -1
- data/test/test_ssl.rb +85 -0
- data/test/test_stream.rb +11 -0
- data/test/test_um.rb +445 -11
- data/uringmachine.gemspec +1 -7
- data/vendor/liburing/examples/send-zerocopy.c +43 -31
- data/vendor/liburing/examples/zcrx.c +260 -69
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/include/liburing/io_uring.h +12 -0
- data/vendor/liburing/src/include/liburing.h +3 -2
- data/vendor/liburing/src/liburing-ffi.map +4 -0
- data/vendor/liburing/src/liburing.map +4 -0
- data/vendor/liburing/src/queue.c +12 -0
- data/vendor/liburing/src/register.c +1 -0
- data/vendor/liburing/src/setup.c +15 -7
- data/vendor/liburing/test/Makefile +8 -4
- data/vendor/liburing/test/conn-unreach.c +1 -1
- data/vendor/liburing/test/epwait.c +32 -6
- data/vendor/liburing/test/io-wq-exit.c +131 -0
- data/vendor/liburing/test/iowait.c +1 -1
- data/vendor/liburing/test/min-timeout.c +3 -1
- data/vendor/liburing/test/open-close.c +39 -0
- data/vendor/liburing/test/poll-update-trigger.c +85 -0
- data/vendor/liburing/test/recvsend_bundle.c +14 -11
- data/vendor/liburing/test/sendzc-bug.c +146 -0
- data/vendor/liburing/test/sqe-mixed-nop.c +151 -7
- data/vendor/liburing/test/test.h +2 -0
- data/vendor/liburing/test/timestamp-bug.c +135 -0
- data/vendor/liburing/test/timestamp.c +5 -0
- data/vendor/liburing/test/vec-regbuf.c +136 -1
- metadata +38 -283
- data/vendor/libressl/.github/scripts/changelog.sh +0 -74
- data/vendor/libressl/.github/workflows/android.yml +0 -35
- data/vendor/libressl/.github/workflows/cifuzz.yml +0 -33
- data/vendor/libressl/.github/workflows/cmake-config.yml +0 -98
- data/vendor/libressl/.github/workflows/coverity.yml +0 -69
- data/vendor/libressl/.github/workflows/emscripten.yml +0 -71
- data/vendor/libressl/.github/workflows/fedora-rawhide.yml +0 -39
- data/vendor/libressl/.github/workflows/freebsd.yml +0 -71
- data/vendor/libressl/.github/workflows/linux.yml +0 -71
- data/vendor/libressl/.github/workflows/macos.yml +0 -37
- data/vendor/libressl/.github/workflows/release.yml +0 -81
- data/vendor/libressl/.github/workflows/rust-openssl.yml +0 -47
- data/vendor/libressl/.github/workflows/solaris.yml +0 -37
- data/vendor/libressl/.github/workflows/windows.yml +0 -70
- data/vendor/libressl/.gitignore +0 -333
- data/vendor/libressl/CMakeLists.txt +0 -581
- data/vendor/libressl/COPYING +0 -133
- data/vendor/libressl/ChangeLog +0 -3280
- data/vendor/libressl/FindLibreSSL.cmake +0 -232
- data/vendor/libressl/LibreSSLConfig.cmake.in +0 -36
- data/vendor/libressl/Makefile.am +0 -60
- data/vendor/libressl/Makefile.am.common +0 -20
- data/vendor/libressl/OPENBSD_BRANCH +0 -1
- data/vendor/libressl/README.md +0 -238
- data/vendor/libressl/README.mingw.md +0 -43
- data/vendor/libressl/apps/CMakeLists.txt +0 -18
- data/vendor/libressl/apps/Makefile.am +0 -5
- data/vendor/libressl/apps/nc/CMakeLists.txt +0 -67
- data/vendor/libressl/apps/nc/Makefile.am +0 -64
- data/vendor/libressl/apps/nc/compat/accept4.c +0 -17
- data/vendor/libressl/apps/nc/compat/readpassphrase.c +0 -205
- data/vendor/libressl/apps/nc/compat/socket.c +0 -29
- data/vendor/libressl/apps/nc/compat/sys/socket.h +0 -30
- data/vendor/libressl/apps/ocspcheck/CMakeLists.txt +0 -44
- data/vendor/libressl/apps/ocspcheck/Makefile.am +0 -45
- data/vendor/libressl/apps/ocspcheck/compat/.gitignore +0 -0
- data/vendor/libressl/apps/openssl/CMakeLists.txt +0 -97
- data/vendor/libressl/apps/openssl/Makefile.am +0 -108
- data/vendor/libressl/apps/openssl/apps_win.c +0 -138
- data/vendor/libressl/apps/openssl/certhash_win.c +0 -13
- data/vendor/libressl/apps/openssl/compat/clock_gettime_osx.c +0 -26
- data/vendor/libressl/apps/openssl/compat/poll_win.c +0 -329
- data/vendor/libressl/appveyor.yml +0 -53
- data/vendor/libressl/autogen.sh +0 -15
- data/vendor/libressl/check-release.sh +0 -86
- data/vendor/libressl/cmake_export_symbol.cmake +0 -71
- data/vendor/libressl/cmake_uninstall.cmake.in +0 -36
- data/vendor/libressl/config +0 -17
- data/vendor/libressl/configure.ac +0 -165
- data/vendor/libressl/crypto/CMakeLists.txt +0 -863
- data/vendor/libressl/crypto/Makefile.am +0 -962
- data/vendor/libressl/crypto/Makefile.am.arc4random +0 -46
- data/vendor/libressl/crypto/Makefile.am.elf-mips +0 -14
- data/vendor/libressl/crypto/Makefile.am.elf-mips64 +0 -14
- data/vendor/libressl/crypto/Makefile.am.elf-x86_64 +0 -35
- data/vendor/libressl/crypto/Makefile.am.macosx-x86_64 +0 -35
- data/vendor/libressl/crypto/Makefile.am.masm-x86_64 +0 -22
- data/vendor/libressl/crypto/Makefile.am.mingw64-x86_64 +0 -23
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_darwin.c +0 -60
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_linux.c +0 -62
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_none.c +0 -26
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_windows.c +0 -36
- data/vendor/libressl/crypto/arch/loongarch64/crypto_arch.h +0 -21
- data/vendor/libressl/crypto/arch/mips/crypto_arch.h +0 -21
- data/vendor/libressl/crypto/bn/arch/loongarch64/bn_arch.h +0 -23
- data/vendor/libressl/crypto/bn/arch/mips/bn_arch.h +0 -24
- data/vendor/libressl/crypto/compat/.gitignore +0 -31
- data/vendor/libressl/crypto/compat/arc4random.h +0 -41
- data/vendor/libressl/crypto/compat/b_win.c +0 -55
- data/vendor/libressl/crypto/compat/bsd-asprintf.c +0 -96
- data/vendor/libressl/crypto/compat/crypto_lock_win.c +0 -56
- data/vendor/libressl/crypto/compat/explicit_bzero_win.c +0 -13
- data/vendor/libressl/crypto/compat/freezero.c +0 -32
- data/vendor/libressl/crypto/compat/getdelim.c +0 -78
- data/vendor/libressl/crypto/compat/getline.c +0 -40
- data/vendor/libressl/crypto/compat/getopt_long.c +0 -528
- data/vendor/libressl/crypto/compat/getpagesize.c +0 -18
- data/vendor/libressl/crypto/compat/getprogname_linux.c +0 -23
- data/vendor/libressl/crypto/compat/getprogname_unimpl.c +0 -7
- data/vendor/libressl/crypto/compat/getprogname_windows.c +0 -13
- data/vendor/libressl/crypto/compat/posix_win.c +0 -296
- data/vendor/libressl/crypto/compat/syslog_r.c +0 -19
- data/vendor/libressl/crypto/compat/ui_openssl_win.c +0 -334
- data/vendor/libressl/dist.sh +0 -22
- data/vendor/libressl/gen-coverage-report.sh +0 -58
- data/vendor/libressl/gen-openbsd-tags.sh +0 -20
- data/vendor/libressl/include/CMakeLists.txt +0 -61
- data/vendor/libressl/include/Makefile.am +0 -79
- data/vendor/libressl/include/arch/loongarch64/opensslconf.h +0 -150
- data/vendor/libressl/include/arch/mips/opensslconf.h +0 -150
- data/vendor/libressl/include/compat/arpa/inet.h +0 -15
- data/vendor/libressl/include/compat/arpa/nameser.h +0 -25
- data/vendor/libressl/include/compat/cet.h +0 -19
- data/vendor/libressl/include/compat/dirent.h +0 -17
- data/vendor/libressl/include/compat/dirent_msvc.h +0 -611
- data/vendor/libressl/include/compat/endian.h +0 -161
- data/vendor/libressl/include/compat/err.h +0 -95
- data/vendor/libressl/include/compat/fcntl.h +0 -32
- data/vendor/libressl/include/compat/getopt.h +0 -50
- data/vendor/libressl/include/compat/limits.h +0 -25
- data/vendor/libressl/include/compat/netdb.h +0 -10
- data/vendor/libressl/include/compat/netinet/in.h +0 -19
- data/vendor/libressl/include/compat/netinet/ip.h +0 -49
- data/vendor/libressl/include/compat/netinet/tcp.h +0 -10
- data/vendor/libressl/include/compat/poll.h +0 -63
- data/vendor/libressl/include/compat/pthread.h +0 -122
- data/vendor/libressl/include/compat/readpassphrase.h +0 -44
- data/vendor/libressl/include/compat/resolv.h +0 -24
- data/vendor/libressl/include/compat/stdint.h +0 -31
- data/vendor/libressl/include/compat/stdio.h +0 -65
- data/vendor/libressl/include/compat/stdlib.h +0 -57
- data/vendor/libressl/include/compat/string.h +0 -98
- data/vendor/libressl/include/compat/sys/_null.h +0 -18
- data/vendor/libressl/include/compat/sys/ioctl.h +0 -11
- data/vendor/libressl/include/compat/sys/mman.h +0 -19
- data/vendor/libressl/include/compat/sys/param.h +0 -15
- data/vendor/libressl/include/compat/sys/queue.h +0 -536
- data/vendor/libressl/include/compat/sys/select.h +0 -10
- data/vendor/libressl/include/compat/sys/socket.h +0 -18
- data/vendor/libressl/include/compat/sys/stat.h +0 -129
- data/vendor/libressl/include/compat/sys/time.h +0 -37
- data/vendor/libressl/include/compat/sys/tree.h +0 -1006
- data/vendor/libressl/include/compat/sys/types.h +0 -69
- data/vendor/libressl/include/compat/sys/uio.h +0 -17
- data/vendor/libressl/include/compat/syslog.h +0 -38
- data/vendor/libressl/include/compat/time.h +0 -59
- data/vendor/libressl/include/compat/unistd.h +0 -83
- data/vendor/libressl/include/compat/win32netcompat.h +0 -57
- data/vendor/libressl/include/openssl/Makefile.am.tpl +0 -45
- data/vendor/libressl/libcrypto.pc.in +0 -28
- data/vendor/libressl/libressl.pub +0 -2
- data/vendor/libressl/libssl.pc.in +0 -28
- data/vendor/libressl/libtls.pc.in +0 -28
- data/vendor/libressl/m4/ax_add_fortify_source.m4 +0 -80
- data/vendor/libressl/m4/ax_check_compile_flag.m4 +0 -53
- data/vendor/libressl/m4/check-hardening-options.m4 +0 -110
- data/vendor/libressl/m4/check-libc.m4 +0 -189
- data/vendor/libressl/m4/check-os-options.m4 +0 -181
- data/vendor/libressl/m4/disable-compiler-warnings.m4 +0 -44
- data/vendor/libressl/man/CMakeLists.txt +0 -26
- data/vendor/libressl/man/links +0 -2780
- data/vendor/libressl/man/update_links.sh +0 -25
- data/vendor/libressl/openssl.pc.in +0 -11
- data/vendor/libressl/patches/bn_shift.patch +0 -34
- data/vendor/libressl/patches/crypto_arch.h.patch +0 -34
- data/vendor/libressl/patches/crypto_namespace.h.patch +0 -22
- data/vendor/libressl/patches/netcat.c.patch +0 -178
- data/vendor/libressl/patches/openssl.c.patch +0 -12
- data/vendor/libressl/patches/opensslfeatures.h.patch +0 -49
- data/vendor/libressl/patches/patch-amd64-crypto-cpu-caps.c.patch +0 -20
- data/vendor/libressl/patches/patch-i386-crypto-cpu-caps.c.patch +0 -20
- data/vendor/libressl/patches/speed.c.patch +0 -114
- data/vendor/libressl/patches/ssl_namespace.h.patch +0 -21
- data/vendor/libressl/patches/tls.h.patch +0 -16
- data/vendor/libressl/patches/tls_config.c.patch +0 -15
- data/vendor/libressl/patches/win32_amd64_bn_arch.h.patch +0 -28
- data/vendor/libressl/patches/windows_headers.patch +0 -80
- data/vendor/libressl/scripts/config.guess +0 -1774
- data/vendor/libressl/scripts/config.sub +0 -1907
- data/vendor/libressl/scripts/i686-w64-mingw32.cmake +0 -9
- data/vendor/libressl/scripts/test +0 -210
- data/vendor/libressl/scripts/wrap-compiler-for-flag-check +0 -31
- data/vendor/libressl/scripts/x86_64-w64-mingw32.cmake +0 -9
- data/vendor/libressl/ssl/CMakeLists.txt +0 -183
- data/vendor/libressl/ssl/Makefile.am +0 -187
- data/vendor/libressl/tests/CMakeLists.txt +0 -970
- data/vendor/libressl/tests/Makefile.am +0 -944
- data/vendor/libressl/tests/aeadtest.sh +0 -30
- data/vendor/libressl/tests/arc4randomforktest.sh +0 -21
- data/vendor/libressl/tests/asn1time_small.test +0 -10
- data/vendor/libressl/tests/cmake/CMakeLists.txt +0 -52
- data/vendor/libressl/tests/cmake/crypto.c +0 -7
- data/vendor/libressl/tests/cmake/ssl.c +0 -6
- data/vendor/libressl/tests/cmake/tls.c +0 -6
- data/vendor/libressl/tests/compat/pipe2.c +0 -186
- data/vendor/libressl/tests/dtlstest.sh +0 -28
- data/vendor/libressl/tests/evptest.sh +0 -22
- data/vendor/libressl/tests/keypairtest.sh +0 -27
- data/vendor/libressl/tests/mlkem_tests.sh +0 -39
- data/vendor/libressl/tests/ocsptest.bat +0 -25
- data/vendor/libressl/tests/ocsptest.sh +0 -23
- data/vendor/libressl/tests/openssl.cnf +0 -29
- data/vendor/libressl/tests/optionstest.c +0 -381
- data/vendor/libressl/tests/pidwraptest.c +0 -85
- data/vendor/libressl/tests/pidwraptest.sh +0 -26
- data/vendor/libressl/tests/quictest.bat +0 -27
- data/vendor/libressl/tests/quictest.sh +0 -30
- data/vendor/libressl/tests/renegotiation_test.bat +0 -27
- data/vendor/libressl/tests/renegotiation_test.sh +0 -30
- data/vendor/libressl/tests/rfc5280time_small.test +0 -10
- data/vendor/libressl/tests/servertest.bat +0 -27
- data/vendor/libressl/tests/servertest.sh +0 -30
- data/vendor/libressl/tests/shutdowntest.bat +0 -27
- data/vendor/libressl/tests/shutdowntest.sh +0 -30
- data/vendor/libressl/tests/ssltest.bat +0 -32
- data/vendor/libressl/tests/ssltest.sh +0 -48
- data/vendor/libressl/tests/testdsa.bat +0 -47
- data/vendor/libressl/tests/testdsa.sh +0 -57
- data/vendor/libressl/tests/testenc.bat +0 -85
- data/vendor/libressl/tests/testenc.sh +0 -93
- data/vendor/libressl/tests/testrsa.bat +0 -47
- data/vendor/libressl/tests/testrsa.sh +0 -57
- data/vendor/libressl/tests/testssl.bat +0 -171
- data/vendor/libressl/tests/tlstest.bat +0 -27
- data/vendor/libressl/tests/tlstest.sh +0 -28
- data/vendor/libressl/tls/CMakeLists.txt +0 -125
- data/vendor/libressl/tls/Makefile.am +0 -76
- data/vendor/libressl/tls/compat/ftruncate.c +0 -17
- data/vendor/libressl/tls/compat/pread.c +0 -29
- data/vendor/libressl/tls/compat/pwrite.c +0 -29
- 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
|
}
|
data/ext/um/um_mutex_class.c
CHANGED
|
@@ -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
|
+
}
|
data/ext/um/um_queue_class.c
CHANGED
|
@@ -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 =
|
|
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
|
|
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
|
|
184
|
+
return rb_interned_str(ptr + 1, len - 1);
|
|
184
185
|
}
|
|
185
186
|
|
|
186
|
-
static inline VALUE resp_decode_string(struct um_stream *stream,
|
|
187
|
-
return resp_get_string(stream, len,
|
|
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 =
|
|
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,
|
|
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,
|
|
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,
|
|
11
|
-
struct io_uring_sqe *sqe = um_get_sqe(machine,
|
|
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
|
-
|
|
18
|
-
|
|
17
|
+
|
|
18
|
+
if (unlikely(!OP_CQE_DONE_P(op)))
|
|
19
|
+
um_cancel_op_and_await_cqe(machine, op);
|
|
19
20
|
else {
|
|
20
|
-
|
|
21
|
-
|
|
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,
|
|
31
|
-
struct io_uring_sqe *sqe = um_get_sqe(machine,
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
data/grant-2025/journal.md
CHANGED
|
@@ -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
|
-
- [
|
|
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
|
-
- [
|
|
138
|
-
- [
|
|
137
|
+
- [v] SSL
|
|
138
|
+
- [v] setup custom BIO
|
|
139
|
+
- [v] SSL read/write methods
|
|
139
140
|
|
|
140
|
-
|
|
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
|
-
#
|
|
75
|
-
#
|
|
76
|
-
#
|
|
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
|
-
# @
|
|
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
|
|
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
|
data/lib/uringmachine/version.rb
CHANGED