uringmachine 0.24.0 → 0.25.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 +9 -0
- data/Gemfile +11 -0
- data/README.md +266 -112
- data/Rakefile +8 -0
- data/TODO.md +0 -17
- 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/ext/um/extconf.rb +15 -0
- data/ext/um/um.c +18 -2
- data/ext/um/um.h +7 -2
- data/ext/um/um_async_op_class.c +31 -0
- 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_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_utils.c +3 -4
- 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_fiber_scheduler.rb +37 -0
- data/test/test_ssl.rb +85 -0
- data/test/test_stream.rb +11 -0
- data/test/test_um.rb +156 -2
- 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 +37 -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
|
|
@@ -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
|
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
|
data/test/test_um.rb
CHANGED
|
@@ -540,7 +540,7 @@ class ReadTest < UMBaseTest
|
|
|
540
540
|
|
|
541
541
|
machine.close(w)
|
|
542
542
|
|
|
543
|
-
res = machine.read(r, read_buffer)
|
|
543
|
+
res = machine.read(r, read_buffer, 6)
|
|
544
544
|
assert_equal 3, res
|
|
545
545
|
assert_equal 'bar', read_buffer.get_string(0, 3)
|
|
546
546
|
end
|
|
@@ -570,7 +570,7 @@ class ReadTest < UMBaseTest
|
|
|
570
570
|
def test_read_invalid_buffer
|
|
571
571
|
r, _w = UM.pipe
|
|
572
572
|
assert_raises(UM::Error) {
|
|
573
|
-
machine.read(r, [])
|
|
573
|
+
machine.read(r, [], 3)
|
|
574
574
|
}
|
|
575
575
|
end
|
|
576
576
|
|
|
@@ -2725,3 +2725,157 @@ class ProfileModeTest < UMBaseTest
|
|
|
2725
2725
|
assert_in_range 0.01..0.015, machine.metrics[:time_total_wait]
|
|
2726
2726
|
end
|
|
2727
2727
|
end
|
|
2728
|
+
|
|
2729
|
+
class FileWatchTest < UMBaseTest
|
|
2730
|
+
def setup
|
|
2731
|
+
super
|
|
2732
|
+
@root = "/tmp/um_#{SecureRandom.hex}"
|
|
2733
|
+
make_tmp_file_tree(@root, {
|
|
2734
|
+
'foo.txt': 'foo',
|
|
2735
|
+
'bar.txt': 'bar',
|
|
2736
|
+
'foo': {
|
|
2737
|
+
'baz.txt': 'baz'
|
|
2738
|
+
}
|
|
2739
|
+
})
|
|
2740
|
+
end
|
|
2741
|
+
|
|
2742
|
+
def test_inotify_get_events
|
|
2743
|
+
fd = UM.inotify_init
|
|
2744
|
+
assert_kind_of Integer, fd
|
|
2745
|
+
assert fd > 0
|
|
2746
|
+
|
|
2747
|
+
mask = UM::IN_CREATE | UM::IN_DELETE | UM::IN_CLOSE_WRITE
|
|
2748
|
+
|
|
2749
|
+
assert_raises(Errno::EBADF) { UM.inotify_add_watch(-1, @root, mask) }
|
|
2750
|
+
assert_raises(Errno::EINVAL) { UM.inotify_add_watch(fd, @root, 0) }
|
|
2751
|
+
non_existent = "/tmp/um_#{SecureRandom.hex}"
|
|
2752
|
+
assert_raises(Errno::ENOENT) { UM.inotify_add_watch(fd, non_existent, mask) }
|
|
2753
|
+
|
|
2754
|
+
wd = UM.inotify_add_watch(fd, @root, mask)
|
|
2755
|
+
assert_equal 1, wd
|
|
2756
|
+
|
|
2757
|
+
fn = File.join(@root, 'foo.txt')
|
|
2758
|
+
IO.write(fn, 'foofoo')
|
|
2759
|
+
|
|
2760
|
+
events = machine.inotify_get_events(fd)
|
|
2761
|
+
assert_equal [
|
|
2762
|
+
{
|
|
2763
|
+
wd: wd,
|
|
2764
|
+
mask: UM::IN_CLOSE_WRITE,
|
|
2765
|
+
name: 'foo.txt'
|
|
2766
|
+
}
|
|
2767
|
+
], events
|
|
2768
|
+
end
|
|
2769
|
+
|
|
2770
|
+
def write_file(fn, data)
|
|
2771
|
+
File.open(fn, 'w+') { it.sync = true; it.syswrite('foofoo') }
|
|
2772
|
+
end
|
|
2773
|
+
|
|
2774
|
+
def test_file_watch
|
|
2775
|
+
events = []
|
|
2776
|
+
f = machine.spin do
|
|
2777
|
+
mask = UM::IN_CREATE | UM::IN_DELETE | UM::IN_CLOSE_WRITE
|
|
2778
|
+
machine.file_watch(@root, mask) do |evt|
|
|
2779
|
+
events << evt
|
|
2780
|
+
end
|
|
2781
|
+
rescue => e
|
|
2782
|
+
p e
|
|
2783
|
+
p e.backtrace
|
|
2784
|
+
exit!
|
|
2785
|
+
end
|
|
2786
|
+
|
|
2787
|
+
3.times { machine.snooze }
|
|
2788
|
+
assert_equal [], events
|
|
2789
|
+
|
|
2790
|
+
# modify foo.txt
|
|
2791
|
+
fn = File.join(@root, 'foo.txt')
|
|
2792
|
+
write_file(fn, 'foofoo')
|
|
2793
|
+
machine.sleep(0.05)
|
|
2794
|
+
assert_equal [
|
|
2795
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo.txt') }
|
|
2796
|
+
], events
|
|
2797
|
+
|
|
2798
|
+
# modify foo/baz.txt
|
|
2799
|
+
fn = File.join(@root, 'foo/baz.txt')
|
|
2800
|
+
write_file(fn, 'bazbaz')
|
|
2801
|
+
machine.sleep(0.05)
|
|
2802
|
+
assert_equal [
|
|
2803
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo.txt') },
|
|
2804
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo/baz.txt') }
|
|
2805
|
+
], events
|
|
2806
|
+
|
|
2807
|
+
# create bar dir
|
|
2808
|
+
fn = File.join(@root, 'bar')
|
|
2809
|
+
FileUtils.mkdir(fn)
|
|
2810
|
+
machine.sleep(0.05)
|
|
2811
|
+
assert_equal [
|
|
2812
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo.txt') },
|
|
2813
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo/baz.txt') },
|
|
2814
|
+
{ mask: UM::IN_CREATE | UM::IN_ISDIR, fn: File.join(@root, 'bar') }
|
|
2815
|
+
], events
|
|
2816
|
+
|
|
2817
|
+
# create bar/baz.txt
|
|
2818
|
+
fn = File.join(@root, 'bar/baz.txt')
|
|
2819
|
+
write_file(fn, 'bazbaz')
|
|
2820
|
+
machine.sleep(0.05)
|
|
2821
|
+
assert_equal [
|
|
2822
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo.txt') },
|
|
2823
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo/baz.txt') },
|
|
2824
|
+
{ mask: UM::IN_CREATE | UM::IN_ISDIR, fn: File.join(@root, 'bar') },
|
|
2825
|
+
{ mask: UM::IN_CREATE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2826
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2827
|
+
], events
|
|
2828
|
+
|
|
2829
|
+
# delete foo/baz.txt
|
|
2830
|
+
fn = File.join(@root, 'foo/baz.txt')
|
|
2831
|
+
FileUtils.rm(fn)
|
|
2832
|
+
machine.sleep(0.05)
|
|
2833
|
+
assert_equal [
|
|
2834
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo.txt') },
|
|
2835
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo/baz.txt') },
|
|
2836
|
+
{ mask: UM::IN_CREATE | UM::IN_ISDIR, fn: File.join(@root, 'bar') },
|
|
2837
|
+
{ mask: UM::IN_CREATE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2838
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2839
|
+
{ mask: UM::IN_DELETE, fn: File.join(@root, 'foo/baz.txt') }
|
|
2840
|
+
], events
|
|
2841
|
+
|
|
2842
|
+
# delete bar
|
|
2843
|
+
fn = File.join(@root, 'bar')
|
|
2844
|
+
FileUtils.rm_rf(fn)
|
|
2845
|
+
machine.sleep(0.05)
|
|
2846
|
+
assert_equal [
|
|
2847
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo.txt') },
|
|
2848
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo/baz.txt') },
|
|
2849
|
+
{ mask: UM::IN_CREATE | UM::IN_ISDIR, fn: File.join(@root, 'bar') },
|
|
2850
|
+
{ mask: UM::IN_CREATE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2851
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2852
|
+
{ mask: UM::IN_DELETE, fn: File.join(@root, 'foo/baz.txt') },
|
|
2853
|
+
{ mask: UM::IN_DELETE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2854
|
+
{ mask: UM::IN_DELETE | UM::IN_ISDIR, fn: File.join(@root, 'bar') }
|
|
2855
|
+
], events
|
|
2856
|
+
|
|
2857
|
+
# recreate bar, bar/baz.txt
|
|
2858
|
+
fn = File.join(@root, 'bar')
|
|
2859
|
+
FileUtils.mkdir(fn)
|
|
2860
|
+
machine.sleep(0.05)
|
|
2861
|
+
fn = File.join(@root, 'bar/baz.txt')
|
|
2862
|
+
write_file(fn, 'bazbaz')
|
|
2863
|
+
machine.sleep(0.05)
|
|
2864
|
+
assert_equal [
|
|
2865
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo.txt') },
|
|
2866
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'foo/baz.txt') },
|
|
2867
|
+
{ mask: UM::IN_CREATE | UM::IN_ISDIR, fn: File.join(@root, 'bar') },
|
|
2868
|
+
{ mask: UM::IN_CREATE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2869
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2870
|
+
{ mask: UM::IN_DELETE, fn: File.join(@root, 'foo/baz.txt') },
|
|
2871
|
+
{ mask: UM::IN_DELETE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2872
|
+
{ mask: UM::IN_DELETE | UM::IN_ISDIR, fn: File.join(@root, 'bar') },
|
|
2873
|
+
{ mask: UM::IN_CREATE | UM::IN_ISDIR, fn: File.join(@root, 'bar') },
|
|
2874
|
+
{ mask: UM::IN_CREATE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2875
|
+
{ mask: UM::IN_CLOSE_WRITE, fn: File.join(@root, 'bar/baz.txt') },
|
|
2876
|
+
], events
|
|
2877
|
+
ensure
|
|
2878
|
+
machine.schedule(f, UM::Terminate.new)
|
|
2879
|
+
machine.join(f)
|
|
2880
|
+
end
|
|
2881
|
+
end
|
data/uringmachine.gemspec
CHANGED
|
@@ -15,14 +15,8 @@ Gem::Specification.new do |s|
|
|
|
15
15
|
"changelog_uri" => "https://github.com/digital-fabric/uringmachine/blob/master/CHANGELOG.md"
|
|
16
16
|
}
|
|
17
17
|
s.rdoc_options = ["--title", "UringMachine", "--main", "README.md"]
|
|
18
|
-
s.extra_rdoc_files =
|
|
18
|
+
s.extra_rdoc_files = `git ls-files -z *.rdoc *.md lib/*.rb lib/**/*.rb ext/um/*.c ext/um/*.h benchmark/*.md benchmark/*.png`.split("\x0")
|
|
19
19
|
s.extensions = ["ext/um/extconf.rb"]
|
|
20
20
|
s.require_paths = ["lib"]
|
|
21
21
|
s.required_ruby_version = '>= 3.5'
|
|
22
|
-
|
|
23
|
-
s.add_development_dependency 'rake-compiler', '~>1.3.0'
|
|
24
|
-
s.add_development_dependency 'minitest', '~>5.26.2'
|
|
25
|
-
s.add_development_dependency 'benchmark'
|
|
26
|
-
s.add_development_dependency 'benchmark-ips'
|
|
27
|
-
s.add_development_dependency 'http_parser.rb', '~>0.8.0'
|
|
28
22
|
end
|