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/lib/uringmachine.rb
CHANGED
|
@@ -6,27 +6,52 @@ require 'uringmachine/dns_resolver'
|
|
|
6
6
|
|
|
7
7
|
UM = UringMachine
|
|
8
8
|
|
|
9
|
+
# A UringMachine instance provides an interface for performing I/O operations
|
|
10
|
+
# and automatically switching between fibers. A single UringMachine instance
|
|
11
|
+
# should be used for each thread.
|
|
9
12
|
class UringMachine
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
|
|
14
|
+
# Returns the set of running fibers.
|
|
15
|
+
#
|
|
16
|
+
# return [Set]
|
|
17
|
+
def fiber_set
|
|
18
|
+
@fiber_set ||= Set.new
|
|
12
19
|
end
|
|
13
20
|
|
|
21
|
+
# Terminate is an exception used to terminate fibers without further bubbling.
|
|
14
22
|
class Terminate < Exception
|
|
15
23
|
end
|
|
16
24
|
|
|
25
|
+
# Creates a new fiber and schedules it to be ran.
|
|
26
|
+
#
|
|
27
|
+
# @param value [any] Value to be passed to the given block
|
|
28
|
+
# @param klass [Class] fiber class
|
|
29
|
+
# @param block [Proc] block to run in fiber
|
|
30
|
+
# @return [Fiber] new fiber
|
|
17
31
|
def spin(value = nil, klass = Fiber, &block)
|
|
18
|
-
fiber = klass.new { |v| run_block_in_fiber(block, fiber, v) }
|
|
32
|
+
fiber = klass.new(blocking: false) { |v| run_block_in_fiber(block, fiber, v) }
|
|
19
33
|
self.schedule(fiber, value)
|
|
20
34
|
|
|
21
|
-
|
|
35
|
+
fiber_set << fiber
|
|
36
|
+
fiber
|
|
22
37
|
end
|
|
23
38
|
|
|
39
|
+
# Runs the given block in the given fiber. This method is used to run fibers
|
|
40
|
+
# indirectly.
|
|
41
|
+
#
|
|
42
|
+
# @param fiber [Fiber] fiber
|
|
43
|
+
# @param block [Proc] block to run
|
|
44
|
+
# @return [Fiber]
|
|
24
45
|
def run(fiber, &block)
|
|
25
46
|
run_block_in_fiber(block, fiber, nil)
|
|
26
47
|
self.schedule(fiber, nil)
|
|
27
|
-
|
|
48
|
+
fiber_set << fiber
|
|
49
|
+
fiber
|
|
28
50
|
end
|
|
29
51
|
|
|
52
|
+
# Waits for the given fibers to terminate.
|
|
53
|
+
#
|
|
54
|
+
# @return [Array<any>] return values of the given fibers
|
|
30
55
|
def join(*fibers)
|
|
31
56
|
results = fibers.inject({}) { |h, f| h[f] = nil; h }
|
|
32
57
|
queue = nil
|
|
@@ -51,6 +76,11 @@ class UringMachine
|
|
|
51
76
|
fibers.size == 1 ? values.first : values
|
|
52
77
|
end
|
|
53
78
|
|
|
79
|
+
# Waits for the given fibers to terminate, without collecting their return
|
|
80
|
+
# values.
|
|
81
|
+
#
|
|
82
|
+
# @param fibers [Fiber, Array<Fiber>] fibers to wait for
|
|
83
|
+
# @return [Integer] number of fibers
|
|
54
84
|
def await_fibers(fibers)
|
|
55
85
|
if fibers.is_a?(Fiber)
|
|
56
86
|
f = fibers
|
|
@@ -80,13 +110,50 @@ class UringMachine
|
|
|
80
110
|
fibers.count
|
|
81
111
|
end
|
|
82
112
|
|
|
113
|
+
# Resolves a hostname to an IP address by performing a DNS query.
|
|
114
|
+
#
|
|
115
|
+
# @param hostname [String] hostname
|
|
116
|
+
# @param type [Symbol] record type
|
|
117
|
+
# @return [String] IP address
|
|
83
118
|
def resolve(hostname, type = :A)
|
|
84
119
|
@resolver ||= DNSResolver.new(self)
|
|
85
120
|
@resolver.resolve(hostname, type)
|
|
86
121
|
end
|
|
87
122
|
|
|
123
|
+
# Watches for filesystem events using inotify in an infinite loop, yielding
|
|
124
|
+
# incoming events to the given block.
|
|
125
|
+
#
|
|
126
|
+
# @param root [String] directory to watch
|
|
127
|
+
# @param mask [Integer] event mask
|
|
128
|
+
# @return [void]
|
|
129
|
+
def file_watch(root, mask)
|
|
130
|
+
fd = UM.inotify_init
|
|
131
|
+
wd_map = {}
|
|
132
|
+
recursive_file_watch(fd, root, wd_map, mask)
|
|
133
|
+
while true
|
|
134
|
+
events = inotify_get_events(fd)
|
|
135
|
+
events.each do |event|
|
|
136
|
+
if event[:mask] | UM::IN_IGNORED == UM::IN_IGNORED
|
|
137
|
+
wd_map.delete(event[:wd])
|
|
138
|
+
next
|
|
139
|
+
end
|
|
140
|
+
transformed_event = transform_file_watch_event(event, wd_map)
|
|
141
|
+
if event[:mask] == UM::IN_CREATE | UM::IN_ISDIR
|
|
142
|
+
recursive_file_watch(fd, transformed_event[:fn], wd_map, mask)
|
|
143
|
+
end
|
|
144
|
+
yield transformed_event
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
ensure
|
|
148
|
+
close_async(fd)
|
|
149
|
+
end
|
|
150
|
+
|
|
88
151
|
private
|
|
89
152
|
|
|
153
|
+
# @param block [Proc]
|
|
154
|
+
# @param fiber [Fiber]
|
|
155
|
+
# @param value [any]
|
|
156
|
+
# @return [void]
|
|
90
157
|
def run_block_in_fiber(block, fiber, value)
|
|
91
158
|
ret = block.(value)
|
|
92
159
|
fiber.set_result(ret)
|
|
@@ -95,13 +162,15 @@ class UringMachine
|
|
|
95
162
|
ensure
|
|
96
163
|
fiber.mark_as_done
|
|
97
164
|
# cleanup
|
|
98
|
-
|
|
165
|
+
fiber_set.delete(fiber)
|
|
99
166
|
self.notify_done_listeners(fiber)
|
|
100
167
|
|
|
101
168
|
# switch away to a different fiber
|
|
102
169
|
self.switch
|
|
103
170
|
end
|
|
104
171
|
|
|
172
|
+
# @param fiber [Fiber]
|
|
173
|
+
# @return [void]
|
|
105
174
|
def notify_done_listeners(fiber)
|
|
106
175
|
listeners = fiber.done_listeners
|
|
107
176
|
return if !listeners
|
|
@@ -109,25 +178,53 @@ class UringMachine
|
|
|
109
178
|
listeners.each { self.push(it, fiber) }
|
|
110
179
|
end
|
|
111
180
|
|
|
181
|
+
# @param fd [Integer] inotify fd
|
|
182
|
+
# @param dir [String] directory path
|
|
183
|
+
# @param wd_map [Hash] hash mapping wd to directory
|
|
184
|
+
# @param mask [Integer] inotify event mask
|
|
185
|
+
# @return [void]
|
|
186
|
+
def recursive_file_watch(fd, dir, wd_map, mask)
|
|
187
|
+
wd = UM.inotify_add_watch(fd, dir, mask)
|
|
188
|
+
wd_map[wd] = dir
|
|
189
|
+
Dir[File.join(dir, '*')].each do
|
|
190
|
+
recursive_file_watch(fd, it, wd_map, mask) if File.directory?(it)
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# @param event [Hash] inotify event
|
|
195
|
+
# @param wd_map [Hash] hash mapping wd to directory
|
|
196
|
+
def transform_file_watch_event(event, wd_map)
|
|
197
|
+
{
|
|
198
|
+
mask: event[:mask],
|
|
199
|
+
fn: File.join(wd_map[event[:wd]], event[:name])
|
|
200
|
+
}
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Fiber extensions
|
|
112
204
|
module FiberExtensions
|
|
113
205
|
attr_reader :result, :done, :done_listeners
|
|
114
206
|
|
|
207
|
+
# Marks the fiber as done (terminated)
|
|
115
208
|
def mark_as_done
|
|
116
209
|
@done = true
|
|
117
210
|
end
|
|
118
211
|
|
|
212
|
+
# Sets the fiber return value
|
|
119
213
|
def set_result(value)
|
|
120
214
|
@result = value
|
|
121
215
|
end
|
|
122
216
|
|
|
217
|
+
# Returns true if the fiber is done (terminated)
|
|
123
218
|
def done?
|
|
124
219
|
@done
|
|
125
220
|
end
|
|
126
221
|
|
|
222
|
+
# Adds the given queue to the list of done listeners
|
|
127
223
|
def add_done_listener(queue)
|
|
128
224
|
(@done_listeners ||= []) << queue
|
|
129
225
|
end
|
|
130
226
|
|
|
227
|
+
# Returns the fiber's associated mailbox
|
|
131
228
|
def mailbox
|
|
132
229
|
@mailbox ||= UM::Queue.new
|
|
133
230
|
end
|
|
@@ -137,7 +234,10 @@ class UringMachine
|
|
|
137
234
|
include FiberExtensions
|
|
138
235
|
end
|
|
139
236
|
|
|
237
|
+
# Thread extensions
|
|
140
238
|
module ThreadExtensions
|
|
239
|
+
|
|
240
|
+
# Returns the thread's associated UringMachine instance
|
|
141
241
|
def machine
|
|
142
242
|
@machine ||= UM.new
|
|
143
243
|
end
|
data/test/helper.rb
CHANGED
|
@@ -85,4 +85,19 @@ class UMBaseTest < Minitest::Test
|
|
|
85
85
|
@@port += 1
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
|
+
|
|
89
|
+
def make_tmp_file_tree(dir, spec)
|
|
90
|
+
FileUtils.mkdir(dir) rescue nil
|
|
91
|
+
spec.each do |k, v|
|
|
92
|
+
fn = File.join(dir, k.to_s)
|
|
93
|
+
case v
|
|
94
|
+
when String
|
|
95
|
+
IO.write(fn, v)
|
|
96
|
+
when Hash
|
|
97
|
+
FileUtils.mkdir(fn) rescue nil
|
|
98
|
+
make_tmp_file_tree(fn, v)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
dir
|
|
102
|
+
end
|
|
88
103
|
end
|
data/test/test_async_op.rb
CHANGED
|
@@ -51,11 +51,12 @@ class AsyncOpTest < UMBaseTest
|
|
|
51
51
|
@op.cancel
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
assert_raises(Errno::ECANCELED) {
|
|
55
|
+
@op.await
|
|
56
|
+
}
|
|
55
57
|
|
|
56
58
|
assert_equal 0, machine.metrics[:ops_pending]
|
|
57
59
|
assert_equal true, @op.done?
|
|
58
|
-
assert_equal (-ECANCELED), res
|
|
59
60
|
assert_equal true, @op.cancelled?
|
|
60
61
|
end
|
|
61
62
|
|
|
@@ -112,6 +112,43 @@ class FiberSchedulerTest < UMBaseTest
|
|
|
112
112
|
o.close rescue nil
|
|
113
113
|
end
|
|
114
114
|
|
|
115
|
+
def test_fiber_scheduler_io_with_machine_spin
|
|
116
|
+
i, o = IO.pipe
|
|
117
|
+
buffer = []
|
|
118
|
+
|
|
119
|
+
f1 = machine.spin do
|
|
120
|
+
sleep 0.01
|
|
121
|
+
o.write 'foo'
|
|
122
|
+
buffer << :f1
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
f2 = machine.spin do
|
|
126
|
+
sleep 0.02
|
|
127
|
+
o.write 'bar'
|
|
128
|
+
buffer << :f2
|
|
129
|
+
o.close
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
f3 = machine.spin do
|
|
133
|
+
str = i.read
|
|
134
|
+
buffer << str
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
machine.join(f1, f2, f3)
|
|
138
|
+
assert_equal [true] * 3, [f1, f2, f3].map(&:done?)
|
|
139
|
+
assert_equal [:f1, :f2, 'foobar'], buffer
|
|
140
|
+
|
|
141
|
+
assert_equal({
|
|
142
|
+
kernel_sleep: 2,
|
|
143
|
+
io_write: 2,
|
|
144
|
+
io_read: 3,
|
|
145
|
+
io_close: 1
|
|
146
|
+
}, scheduler_calls_tally)
|
|
147
|
+
ensure
|
|
148
|
+
i.close rescue nil
|
|
149
|
+
o.close rescue nil
|
|
150
|
+
end
|
|
151
|
+
|
|
115
152
|
def test_io_read_with_timeout
|
|
116
153
|
i, o = IO.pipe
|
|
117
154
|
i.timeout = 0.01
|
|
@@ -356,9 +393,12 @@ class FiberSchedulerTest < UMBaseTest
|
|
|
356
393
|
sleep 0.001
|
|
357
394
|
buf = IO.read(fn)
|
|
358
395
|
end
|
|
359
|
-
assert_equal 2, machine.metrics[:total_ops]
|
|
360
396
|
|
|
361
397
|
@scheduler.join
|
|
398
|
+
metrics = machine.metrics
|
|
399
|
+
assert_in_range 5..12, metrics[:total_ops]
|
|
400
|
+
assert_equal 0, metrics[:ops_pending]
|
|
401
|
+
assert_equal 256, metrics[:ops_free]
|
|
362
402
|
assert_equal 'foobar', buf
|
|
363
403
|
assert_equal({
|
|
364
404
|
fiber: 2,
|
data/test/test_ssl.rb
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'helper'
|
|
4
|
+
require 'openssl'
|
|
5
|
+
require 'localhost/authority'
|
|
6
|
+
|
|
7
|
+
class SSLTest < UMBaseTest
|
|
8
|
+
def setup
|
|
9
|
+
super
|
|
10
|
+
authority = Localhost::Authority.fetch
|
|
11
|
+
@server_ctx = authority.server_context
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_ssl_stock
|
|
15
|
+
sock1, sock2 = UNIXSocket.pair
|
|
16
|
+
|
|
17
|
+
s1 = OpenSSL::SSL::SSLSocket.new(sock1, @server_ctx)
|
|
18
|
+
s1.sync_close = true
|
|
19
|
+
s2 = OpenSSL::SSL::SSLSocket.new(sock2, OpenSSL::SSL::SSLContext.new)
|
|
20
|
+
s2.sync_close = true
|
|
21
|
+
|
|
22
|
+
t = Thread.new { s1.accept rescue nil }
|
|
23
|
+
|
|
24
|
+
s2.connect
|
|
25
|
+
|
|
26
|
+
assert_equal 6, s1.write('foobar')
|
|
27
|
+
assert_equal 'foobar', s2.readpartial(6)
|
|
28
|
+
ensure
|
|
29
|
+
t.join(0.1)
|
|
30
|
+
sock1&.close rescue nil
|
|
31
|
+
sock2&.close rescue nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_ssl_custom_bio
|
|
35
|
+
sock1, sock2 = UNIXSocket.pair
|
|
36
|
+
|
|
37
|
+
s1 = OpenSSL::SSL::SSLSocket.new(sock1, @server_ctx)
|
|
38
|
+
s1.sync_close = true
|
|
39
|
+
s2 = OpenSSL::SSL::SSLSocket.new(sock2, OpenSSL::SSL::SSLContext.new)
|
|
40
|
+
s2.sync_close = true
|
|
41
|
+
|
|
42
|
+
@machine.ssl_set_bio(s2)
|
|
43
|
+
assert_equal true, s2.instance_variable_get(:@__um_bio__)
|
|
44
|
+
|
|
45
|
+
t = Thread.new { s1.accept rescue nil }
|
|
46
|
+
|
|
47
|
+
assert_equal 0, @machine.metrics[:total_ops]
|
|
48
|
+
s2.connect
|
|
49
|
+
refute_equal 0, @machine.metrics[:total_ops]
|
|
50
|
+
|
|
51
|
+
assert_equal 6, s1.write('foobar')
|
|
52
|
+
assert_equal 'foobar', s2.readpartial(6)
|
|
53
|
+
ensure
|
|
54
|
+
t&.join(0.1)
|
|
55
|
+
sock1&.close rescue nil
|
|
56
|
+
sock2&.close rescue nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_ssl_read_write
|
|
60
|
+
sock1, sock2 = UNIXSocket.pair
|
|
61
|
+
|
|
62
|
+
s1 = OpenSSL::SSL::SSLSocket.new(sock1, @server_ctx)
|
|
63
|
+
s1.sync_close = true
|
|
64
|
+
s2 = OpenSSL::SSL::SSLSocket.new(sock2, OpenSSL::SSL::SSLContext.new)
|
|
65
|
+
s2.sync_close = true
|
|
66
|
+
|
|
67
|
+
@machine.ssl_set_bio(s2)
|
|
68
|
+
assert_equal true, s2.instance_variable_get(:@__um_bio__)
|
|
69
|
+
|
|
70
|
+
t = Thread.new { s1.accept rescue nil }
|
|
71
|
+
|
|
72
|
+
assert_equal 0, @machine.metrics[:total_ops]
|
|
73
|
+
s2.connect
|
|
74
|
+
refute_equal 0, @machine.metrics[:total_ops]
|
|
75
|
+
|
|
76
|
+
assert_equal 6, @machine.ssl_write(s1, 'foobar', 6)
|
|
77
|
+
buf = +''
|
|
78
|
+
assert_equal 6, @machine.ssl_read(s2, buf, 6)
|
|
79
|
+
assert_equal 'foobar', buf
|
|
80
|
+
ensure
|
|
81
|
+
t&.join(0.1)
|
|
82
|
+
sock1&.close rescue nil
|
|
83
|
+
sock2&.close rescue nil
|
|
84
|
+
end
|
|
85
|
+
end
|
data/test/test_stream.rb
CHANGED
|
@@ -163,6 +163,8 @@ class StreamRespTest < StreamBaseTest
|
|
|
163
163
|
machine.write(@wfd, "%2\r\n+a\r\n:42\r\n+b\r\n*3\r\n+foo\r\n+bar\r\n+baz\r\n")
|
|
164
164
|
assert_equal({ 'a' => 42, 'b' => ['foo', 'bar', 'baz'] }, @stream.resp_decode)
|
|
165
165
|
|
|
166
|
+
machine.write(@wfd, "%2\r\n+a\r\n:42\r\n+b\r\n*3\r\n+foo\r\n+xbar\r\n+yybaz\r\n")
|
|
167
|
+
assert_equal({ 'a' => 42, 'b' => ['foo', 'xbar', 'yybaz'] }, @stream.resp_decode)
|
|
166
168
|
end
|
|
167
169
|
|
|
168
170
|
def test_resp_encode
|
|
@@ -181,6 +183,9 @@ class StreamRespTest < StreamBaseTest
|
|
|
181
183
|
assert_equal "*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",
|
|
182
184
|
s.resp_encode(+'', ['foo', 'bar'])
|
|
183
185
|
|
|
186
|
+
assert_equal "*2\r\n$3\r\nfoo\r\n$4\r\nxbar\r\n",
|
|
187
|
+
s.resp_encode(+'', ['foo', 'xbar'])
|
|
188
|
+
|
|
184
189
|
assert_equal "%2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$3\r\nbaz\r\n:42\r\n",
|
|
185
190
|
s.resp_encode(+'', { 'foo' => 'bar', 'baz' => 42 })
|
|
186
191
|
end
|
|
@@ -191,10 +196,16 @@ class StreamRespTest < StreamBaseTest
|
|
|
191
196
|
assert_equal "*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",
|
|
192
197
|
s.resp_encode_cmd(+'', 'foo', 'bar')
|
|
193
198
|
|
|
199
|
+
assert_equal "*2\r\n$3\r\nfoo\r\n$4\r\nxbar\r\n",
|
|
200
|
+
s.resp_encode_cmd(+'', 'foo', 'xbar')
|
|
201
|
+
|
|
194
202
|
assert_equal "*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",
|
|
195
203
|
s.resp_encode_cmd(+'', 'foo', :bar)
|
|
196
204
|
|
|
197
205
|
assert_equal "*2\r\n$3\r\nfoo\r\n$3\r\n123\r\n",
|
|
198
206
|
s.resp_encode_cmd(+'', 'foo', 123)
|
|
207
|
+
|
|
208
|
+
assert_equal "*4\r\n$3\r\nset\r\n$6\r\nfoobar\r\n$2\r\nnx\r\n$2\r\nxx\r\n",
|
|
209
|
+
s.resp_encode_cmd(+'', :set, 'foobar', :nx, :xx)
|
|
199
210
|
end
|
|
200
211
|
end
|