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_class.c
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#include <sys/syscall.h>
|
|
5
5
|
#include <unistd.h>
|
|
6
6
|
#include <sys/socket.h>
|
|
7
|
+
#include <sys/inotify.h>
|
|
7
8
|
|
|
8
9
|
VALUE cUM;
|
|
9
10
|
VALUE eUMError;
|
|
@@ -20,6 +21,10 @@ VALUE SYM_ops_transient;
|
|
|
20
21
|
VALUE SYM_time_total_cpu;
|
|
21
22
|
VALUE SYM_time_total_wait;
|
|
22
23
|
|
|
24
|
+
VALUE SYM_wd;
|
|
25
|
+
VALUE SYM_mask;
|
|
26
|
+
VALUE SYM_name;
|
|
27
|
+
|
|
23
28
|
static ID id_fileno;
|
|
24
29
|
|
|
25
30
|
static void UM_mark(void *ptr) {
|
|
@@ -86,6 +91,14 @@ static inline uint get_sqpoll_timeout_msec(VALUE sqpoll_timeout) {
|
|
|
86
91
|
}
|
|
87
92
|
}
|
|
88
93
|
|
|
94
|
+
/* Initializes a new UringMachine instance with the given options.
|
|
95
|
+
*
|
|
96
|
+
* @overload initialize(size: 4096, sqpoll: false, sidecar: false)
|
|
97
|
+
* @param size [Integer] SQ size (default: 4096)
|
|
98
|
+
* @param sqpoll [bool, Number] Set SQPOLL mode, SQPOLL timeout
|
|
99
|
+
* @param sidecar [bool] Set sidecar mode
|
|
100
|
+
* @return [void]
|
|
101
|
+
*/
|
|
89
102
|
VALUE UM_initialize(int argc, VALUE *argv, VALUE self) {
|
|
90
103
|
static ID kwargs_ids[3];
|
|
91
104
|
struct um *machine = RTYPEDDATA_DATA(self);
|
|
@@ -108,38 +121,68 @@ VALUE UM_initialize(int argc, VALUE *argv, VALUE self) {
|
|
|
108
121
|
return self;
|
|
109
122
|
}
|
|
110
123
|
|
|
124
|
+
/* Creates a buffer group (buffer ring) with the given buffer size and buffer count.
|
|
125
|
+
*
|
|
126
|
+
* @param size [Integer] buffer size in bytes
|
|
127
|
+
* @param count [Integer] number of buffers in group
|
|
128
|
+
* @return [Integer] buffer group id
|
|
129
|
+
*/
|
|
111
130
|
VALUE UM_setup_buffer_ring(VALUE self, VALUE size, VALUE count) {
|
|
112
131
|
struct um *machine = um_get_machine(self);
|
|
113
132
|
int bgid = um_setup_buffer_ring(machine, NUM2UINT(size), NUM2UINT(count));
|
|
114
133
|
return INT2NUM(bgid);
|
|
115
134
|
}
|
|
116
135
|
|
|
136
|
+
/* Returns the SQ (submission queue) size.
|
|
137
|
+
*
|
|
138
|
+
* @return [Integer] SQ size
|
|
139
|
+
*/
|
|
117
140
|
VALUE UM_size(VALUE self) {
|
|
118
141
|
struct um *machine = um_get_machine(self);
|
|
119
142
|
return UINT2NUM(machine->size);
|
|
120
143
|
}
|
|
121
144
|
|
|
145
|
+
/* :nodoc:
|
|
146
|
+
*/
|
|
122
147
|
VALUE UM_mark_m(VALUE self, VALUE mark) {
|
|
123
148
|
struct um *machine = um_get_machine(self);
|
|
124
149
|
machine->mark = NUM2UINT(mark);
|
|
125
150
|
return self;
|
|
126
151
|
}
|
|
127
152
|
|
|
153
|
+
/* Returns a hash with different metrics about the functioning of the
|
|
154
|
+
* UringMachine instance.
|
|
155
|
+
*
|
|
156
|
+
* @return [Hash] metrics hash
|
|
157
|
+
*/
|
|
128
158
|
VALUE UM_metrics(VALUE self) {
|
|
129
159
|
struct um *machine = um_get_machine(self);
|
|
130
160
|
return um_metrics(machine, &machine->metrics);
|
|
131
161
|
}
|
|
132
162
|
|
|
163
|
+
/* Returns the profile mode state.
|
|
164
|
+
*
|
|
165
|
+
* @return [bool] profile mode on/off
|
|
166
|
+
*/
|
|
133
167
|
VALUE UM_profile_mode_p(VALUE self) {
|
|
134
168
|
struct um *machine = um_get_machine(self);
|
|
135
169
|
return machine->profile_mode ? Qtrue : Qfalse;
|
|
136
170
|
}
|
|
137
171
|
|
|
172
|
+
/* Returns the SQPOLL mode state.
|
|
173
|
+
*
|
|
174
|
+
* @return [bool] SQPOLL mode on/off
|
|
175
|
+
*/
|
|
138
176
|
VALUE UM_sqpoll_mode_p(VALUE self) {
|
|
139
177
|
struct um *machine = um_get_machine(self);
|
|
140
178
|
return machine->sqpoll_mode ? Qtrue : Qfalse;
|
|
141
179
|
}
|
|
142
180
|
|
|
181
|
+
/* Sets/resets profile mode.
|
|
182
|
+
*
|
|
183
|
+
* @param value [bool] profile mode on/off
|
|
184
|
+
* @return [bool] profile mode on/off
|
|
185
|
+
*/
|
|
143
186
|
VALUE UM_profile_mode_set(VALUE self, VALUE value) {
|
|
144
187
|
struct um *machine = um_get_machine(self);
|
|
145
188
|
machine->profile_mode = RTEST(value);
|
|
@@ -150,29 +193,52 @@ VALUE UM_profile_mode_set(VALUE self, VALUE value) {
|
|
|
150
193
|
return value;
|
|
151
194
|
}
|
|
152
195
|
|
|
196
|
+
/* Sets/resets test mode.
|
|
197
|
+
*
|
|
198
|
+
* @param value [bool] test mode on/off
|
|
199
|
+
* @return [bool] test mode on/off
|
|
200
|
+
*/
|
|
153
201
|
VALUE UM_test_mode_set(VALUE self, VALUE value) {
|
|
154
202
|
struct um *machine = um_get_machine(self);
|
|
155
203
|
machine->test_mode = RTEST(value);
|
|
156
204
|
return value;
|
|
157
205
|
}
|
|
158
206
|
|
|
207
|
+
/* Returns the sidecar mode state.
|
|
208
|
+
*
|
|
209
|
+
* @return [bool] sidecar mode on/off
|
|
210
|
+
*/
|
|
159
211
|
VALUE UM_sidecar_mode_p(VALUE self) {
|
|
160
212
|
struct um *machine = um_get_machine(self);
|
|
161
213
|
return machine->sidecar_mode ? Qtrue : Qfalse;
|
|
162
214
|
}
|
|
163
215
|
|
|
216
|
+
/* Starts sidecar mode.
|
|
217
|
+
*
|
|
218
|
+
* @return [UringMachine] self
|
|
219
|
+
*/
|
|
164
220
|
VALUE UM_sidecar_start(VALUE self) {
|
|
165
221
|
struct um *machine = um_get_machine(self);
|
|
166
222
|
um_sidecar_setup(machine);
|
|
167
223
|
return self;
|
|
168
224
|
}
|
|
169
225
|
|
|
226
|
+
/* Stops sidecar mode.
|
|
227
|
+
*
|
|
228
|
+
* @return [UringMachine] self
|
|
229
|
+
*/
|
|
170
230
|
VALUE UM_sidecar_stop(VALUE self) {
|
|
171
231
|
struct um *machine = um_get_machine(self);
|
|
172
232
|
um_sidecar_teardown(machine);
|
|
173
233
|
return self;
|
|
174
234
|
}
|
|
175
235
|
|
|
236
|
+
/* Adds the current fiber to the end of the runqueue and yields control to the
|
|
237
|
+
* next fiber in the runqueue. This method is usually used to yield control
|
|
238
|
+
* while performing CPU-intensive work in order not starve other fibers.
|
|
239
|
+
*
|
|
240
|
+
* @return [UringMachine] self
|
|
241
|
+
*/
|
|
176
242
|
VALUE UM_snooze(VALUE self) {
|
|
177
243
|
struct um *machine = um_get_machine(self);
|
|
178
244
|
um_schedule(machine, rb_fiber_current(), Qnil);
|
|
@@ -184,6 +250,13 @@ VALUE UM_snooze(VALUE self) {
|
|
|
184
250
|
return ret;
|
|
185
251
|
}
|
|
186
252
|
|
|
253
|
+
/* Yields control to the next fiber in the runqueue. The current fiber will not
|
|
254
|
+
* be resumed unless it is scheduled again by some other fiber. The call to
|
|
255
|
+
* `#yield` will return the value with which the current fiber will be
|
|
256
|
+
* eventually scheduled.
|
|
257
|
+
*
|
|
258
|
+
* @return [any] resume value
|
|
259
|
+
*/
|
|
187
260
|
VALUE UM_yield(VALUE self) {
|
|
188
261
|
struct um *machine = um_get_machine(self);
|
|
189
262
|
|
|
@@ -192,6 +265,14 @@ VALUE UM_yield(VALUE self) {
|
|
|
192
265
|
return ret;
|
|
193
266
|
}
|
|
194
267
|
|
|
268
|
+
/* Yields control to the next fiber in the runqueue. The current fiber will not
|
|
269
|
+
* be resumed unless it is scheduled again by some other fiber. The call to
|
|
270
|
+
* `#yield` will return the value with which the current fiber will be
|
|
271
|
+
* eventually scheduled. If resumed with an exception, that exception will be
|
|
272
|
+
* raised when the fiber is resumed.
|
|
273
|
+
*
|
|
274
|
+
* @return [any] resume value
|
|
275
|
+
*/
|
|
195
276
|
VALUE UM_switch(VALUE self) {
|
|
196
277
|
struct um *machine = um_get_machine(self);
|
|
197
278
|
|
|
@@ -200,43 +281,100 @@ VALUE UM_switch(VALUE self) {
|
|
|
200
281
|
return ret;
|
|
201
282
|
}
|
|
202
283
|
|
|
284
|
+
/* Wakes up the machine in order to start processing its runqueue again. This
|
|
285
|
+
* method is normally called from another thread in order to resume processing
|
|
286
|
+
* of the runqueue when a machine is waiting for I/O completions.
|
|
287
|
+
*
|
|
288
|
+
* @return [void]
|
|
289
|
+
*/
|
|
203
290
|
VALUE UM_wakeup(VALUE self) {
|
|
204
291
|
struct um *machine = um_get_machine(self);
|
|
205
292
|
return um_wakeup(machine);
|
|
206
293
|
}
|
|
207
294
|
|
|
295
|
+
/* Submits any pending I/O operations that are not yet submitted.
|
|
296
|
+
*
|
|
297
|
+
* @return [Integer] number of I/O operations submitted
|
|
298
|
+
*/
|
|
208
299
|
VALUE UM_submit(VALUE self) {
|
|
209
300
|
struct um *machine = um_get_machine(self);
|
|
210
301
|
uint ret = um_submit(machine);
|
|
211
302
|
return UINT2NUM(ret);
|
|
212
303
|
}
|
|
213
304
|
|
|
305
|
+
/* Returns a set containing all fibers in pending state (i.e. waiting for an
|
|
306
|
+
* operation to complete.)
|
|
307
|
+
*
|
|
308
|
+
* @return [Set] set of pending fibers
|
|
309
|
+
*/
|
|
214
310
|
VALUE UM_pending_fibers(VALUE self) {
|
|
215
311
|
struct um *machine = um_get_machine(self);
|
|
216
312
|
return machine->pending_fibers;
|
|
217
313
|
}
|
|
218
314
|
|
|
315
|
+
/* Schedules the given fiber by adding it to the runqueue. The fiber will be
|
|
316
|
+
* resumed with the given value.
|
|
317
|
+
*
|
|
318
|
+
* @param fiber [Fiber] fiber to schedule
|
|
319
|
+
* @param value [any] resume value
|
|
320
|
+
* @return [UringMachine] self
|
|
321
|
+
*/
|
|
219
322
|
VALUE UM_schedule(VALUE self, VALUE fiber, VALUE value) {
|
|
220
323
|
struct um *machine = um_get_machine(self);
|
|
221
324
|
um_schedule(machine, fiber, value);
|
|
222
325
|
return self;
|
|
223
326
|
}
|
|
224
327
|
|
|
225
|
-
|
|
328
|
+
/* Runs the given block, interrupting its execution if its runtime exceeds the
|
|
329
|
+
* given timeout interval (in seconds).
|
|
330
|
+
*
|
|
331
|
+
* @param interval [Number] timeout interval in seconds
|
|
332
|
+
* @param exception_class [any] timeout exception class
|
|
333
|
+
* @return [any] block's return value
|
|
334
|
+
*/
|
|
335
|
+
VALUE UM_timeout(VALUE self, VALUE interval, VALUE exception_class) {
|
|
226
336
|
struct um *machine = um_get_machine(self);
|
|
227
|
-
return um_timeout(machine, interval,
|
|
337
|
+
return um_timeout(machine, interval, exception_class);
|
|
228
338
|
}
|
|
229
339
|
|
|
340
|
+
/* Puts the current fiber to sleep for the given time duration (in seconds),
|
|
341
|
+
* yielding control to the next fiber in the runqueue.
|
|
342
|
+
*
|
|
343
|
+
* @param duration [Number] sleep duration in seconds
|
|
344
|
+
* @return [void]
|
|
345
|
+
*/
|
|
230
346
|
VALUE UM_sleep(VALUE self, VALUE duration) {
|
|
231
347
|
struct um *machine = um_get_machine(self);
|
|
232
348
|
return um_sleep(machine, NUM2DBL(duration));
|
|
233
349
|
}
|
|
234
350
|
|
|
351
|
+
/* Runs the given block at regular time intervals in an infinite loop.
|
|
352
|
+
*
|
|
353
|
+
* @param interval [Number] time interval (in seconds) between consecutive invocations
|
|
354
|
+
* @return [void]
|
|
355
|
+
*/
|
|
235
356
|
VALUE UM_periodically(VALUE self, VALUE interval) {
|
|
236
357
|
struct um *machine = um_get_machine(self);
|
|
237
358
|
return um_periodically(machine, NUM2DBL(interval));
|
|
238
359
|
}
|
|
239
360
|
|
|
361
|
+
/* call-seq:
|
|
362
|
+
* machine.read(fd, buffer, maxlen[, buffer_offset[, file_offset]]) -> bytes_read
|
|
363
|
+
*
|
|
364
|
+
* Reads up to `maxlen` bytes from the given `fd` into the given buffer. The
|
|
365
|
+
* optional `buffer_offset` parameter determines the position in the buffer into
|
|
366
|
+
* which the data will be read. A negative `buffer_offset` denotes a position
|
|
367
|
+
* relative to the end of the buffer, e.g. a value of `-1` means the data will
|
|
368
|
+
* be appended to the buffer.
|
|
369
|
+
*
|
|
370
|
+
* @overload read(fd, buffer, maxlen, buffer_offset: nil, file_offset: nil)
|
|
371
|
+
* @param fd [Integer] file descriptor
|
|
372
|
+
* @param buffer [String, IO::Buffer] buffer
|
|
373
|
+
* @param maxlen [Integer] maximum number of bytes to read
|
|
374
|
+
* @param buffer_offset [Integer] optional buffer offset to read into
|
|
375
|
+
* @param file_offset [Integer] optional file offset to read from
|
|
376
|
+
* @return [Integer] number of bytes read
|
|
377
|
+
*/
|
|
240
378
|
VALUE UM_read(int argc, VALUE *argv, VALUE self) {
|
|
241
379
|
struct um *machine = um_get_machine(self);
|
|
242
380
|
VALUE fd;
|
|
@@ -244,7 +382,7 @@ VALUE UM_read(int argc, VALUE *argv, VALUE self) {
|
|
|
244
382
|
VALUE maxlen;
|
|
245
383
|
VALUE buffer_offset;
|
|
246
384
|
VALUE file_offset;
|
|
247
|
-
rb_scan_args(argc, argv, "
|
|
385
|
+
rb_scan_args(argc, argv, "32", &fd, &buffer, &maxlen, &buffer_offset, &file_offset);
|
|
248
386
|
|
|
249
387
|
ssize_t maxlen_i = NIL_P(maxlen) ? -1 : NUM2INT(maxlen);
|
|
250
388
|
ssize_t buffer_offset_i = NIL_P(buffer_offset) ? 0 : NUM2INT(buffer_offset);
|
|
@@ -253,11 +391,35 @@ VALUE UM_read(int argc, VALUE *argv, VALUE self) {
|
|
|
253
391
|
return um_read(machine, NUM2INT(fd), buffer, maxlen_i, buffer_offset_i, file_offset_i);
|
|
254
392
|
}
|
|
255
393
|
|
|
394
|
+
/* call-seq:
|
|
395
|
+
* machine.read_each(fd, bgid) { |data| }
|
|
396
|
+
*
|
|
397
|
+
* Reads repeatedly from the given `fd` using the given buffer group id. The
|
|
398
|
+
* buffer group should have been previously setup using `#setup_buffer_ring`.
|
|
399
|
+
* Read data is yielded in an infinite loop to the given block.
|
|
400
|
+
*
|
|
401
|
+
* @param fd [Integer] file descriptor
|
|
402
|
+
* @param bgid [Integer] buffer group id
|
|
403
|
+
* @return [void]
|
|
404
|
+
*/
|
|
256
405
|
VALUE UM_read_each(VALUE self, VALUE fd, VALUE bgid) {
|
|
257
406
|
struct um *machine = um_get_machine(self);
|
|
258
407
|
return um_read_each(machine, NUM2INT(fd), NUM2INT(bgid));
|
|
259
408
|
}
|
|
260
409
|
|
|
410
|
+
/* call-seq:
|
|
411
|
+
* machine.write(fd, buffer[, len[, file_offset]]) -> bytes_written
|
|
412
|
+
*
|
|
413
|
+
* Writes up to `len` bytes from the given buffer to the given `fd`. If `len`,
|
|
414
|
+
* is not given, the entire buffer length is used.
|
|
415
|
+
*
|
|
416
|
+
* @overload write(fd, buffer, len: nil, file_offset: nil)
|
|
417
|
+
* @param fd [Integer] file descriptor
|
|
418
|
+
* @param buffer [String, IO::Buffer] buffer
|
|
419
|
+
* @param len [Integer] maximum number of bytes to write
|
|
420
|
+
* @param file_offset [Integer] optional file offset to write to
|
|
421
|
+
* @return [Integer] number of bytes written
|
|
422
|
+
*/
|
|
261
423
|
VALUE UM_write(int argc, VALUE *argv, VALUE self) {
|
|
262
424
|
struct um *machine = um_get_machine(self);
|
|
263
425
|
VALUE fd;
|
|
@@ -272,6 +434,21 @@ VALUE UM_write(int argc, VALUE *argv, VALUE self) {
|
|
|
272
434
|
return um_write(machine, NUM2INT(fd), buffer, len_i, file_offset_i);
|
|
273
435
|
}
|
|
274
436
|
|
|
437
|
+
/* call-seq:
|
|
438
|
+
* machine.writev(fd, *buffers[, file_offset]) -> bytes_written
|
|
439
|
+
*
|
|
440
|
+
* Writes from the given buffers into the given fd. This method does not
|
|
441
|
+
* guarantee that all data will be written. The application code should check
|
|
442
|
+
* the return value which indicates the number of bytes written and potentially
|
|
443
|
+
* repeat the operation after adjusting the buffers accordingly. See also
|
|
444
|
+
* `#sendv`.
|
|
445
|
+
*
|
|
446
|
+
* @overload writev(fd, *buffers, file_offset: nil)
|
|
447
|
+
* @param fd [Integer] file descriptor
|
|
448
|
+
* @param *buffers [Array<String, IO::Buffer>] data buffers
|
|
449
|
+
* @param file_offset [Integer] optional file offset to write to
|
|
450
|
+
* @return [Integer] number of bytes written
|
|
451
|
+
*/
|
|
275
452
|
VALUE UM_writev(int argc, VALUE *argv, VALUE self) {
|
|
276
453
|
struct um *machine = um_get_machine(self);
|
|
277
454
|
if (argc < 1)
|
|
@@ -282,6 +459,22 @@ VALUE UM_writev(int argc, VALUE *argv, VALUE self) {
|
|
|
282
459
|
return um_writev(machine, fd, argc - 1, argv + 1);
|
|
283
460
|
}
|
|
284
461
|
|
|
462
|
+
/* call-seq:
|
|
463
|
+
* machine.write_async(fd, buffer[, len[, file_offset]]) -> buffer
|
|
464
|
+
*
|
|
465
|
+
* Writes up to `len` bytes from the given buffer to the given `fd`. If `len`,
|
|
466
|
+
* is not given, the entire buffer length is used. This method submits the
|
|
467
|
+
* operation but does not wait for it to complete. This method may be used to
|
|
468
|
+
* improve performance in situations where the application does not care about
|
|
469
|
+
* whether the I/O operation succeeds or not.
|
|
470
|
+
*
|
|
471
|
+
* @overload write_async(fd, buffer, len: nil, file_offset: nil)
|
|
472
|
+
* @param fd [Integer] file descriptor
|
|
473
|
+
* @param buffer [String, IO::Buffer] buffer
|
|
474
|
+
* @param len [Integer] maximum number of bytes to write
|
|
475
|
+
* @param file_offset [Integer] optional file offset to write to
|
|
476
|
+
* @return [String, IO::Buffer] buffer
|
|
477
|
+
*/
|
|
285
478
|
VALUE UM_write_async(int argc, VALUE *argv, VALUE self) {
|
|
286
479
|
struct um *machine = um_get_machine(self);
|
|
287
480
|
VALUE fd;
|
|
@@ -296,51 +489,150 @@ VALUE UM_write_async(int argc, VALUE *argv, VALUE self) {
|
|
|
296
489
|
return um_write_async(machine, NUM2INT(fd), buffer, len_i, file_offset_i);
|
|
297
490
|
}
|
|
298
491
|
|
|
492
|
+
/* call-seq:
|
|
493
|
+
* machine.statx(fd, nil, flags, mask) -> hash
|
|
494
|
+
* machine.statx(dirfd, path, flags, mask) -> hash
|
|
495
|
+
* machine.statx(UM::AT_FDCWD, path, flags, mask) -> hash
|
|
496
|
+
*
|
|
497
|
+
* Returns information about a file.
|
|
498
|
+
*
|
|
499
|
+
* @param dirfd [Integer] file or directory descriptor
|
|
500
|
+
* @param path [String, nil] file path
|
|
501
|
+
* @param flags [Integer] flags
|
|
502
|
+
* @param mask [Integer] mask of information to return
|
|
503
|
+
* @return [hash] hash containing file information
|
|
504
|
+
*/
|
|
299
505
|
VALUE UM_statx(VALUE self, VALUE dirfd, VALUE path, VALUE flags, VALUE mask) {
|
|
300
506
|
struct um *machine = um_get_machine(self);
|
|
301
507
|
return um_statx(machine, NUM2INT(dirfd), path, NUM2INT(flags), NUM2UINT(mask));
|
|
302
508
|
}
|
|
303
509
|
|
|
510
|
+
/* call-seq:
|
|
511
|
+
* machine.close(fd) -> 0
|
|
512
|
+
*
|
|
513
|
+
* Closes the given file descriptor.
|
|
514
|
+
*
|
|
515
|
+
* @param fd [Integer] file descriptor
|
|
516
|
+
* @return [0] success
|
|
517
|
+
*/
|
|
304
518
|
VALUE UM_close(VALUE self, VALUE fd) {
|
|
305
519
|
struct um *machine = um_get_machine(self);
|
|
306
520
|
return um_close(machine, NUM2INT(fd));
|
|
307
521
|
}
|
|
308
522
|
|
|
523
|
+
/* call-seq:
|
|
524
|
+
* machine.close_async(fd) -> hash
|
|
525
|
+
*
|
|
526
|
+
* Closes the given file descriptor. This method submits the operation but does
|
|
527
|
+
* not wait for it to complete. This method may be used to improve performance
|
|
528
|
+
* in cases where the application des not care whether it succeeds or not.
|
|
529
|
+
*
|
|
530
|
+
* @param fd [Integer] file descriptor
|
|
531
|
+
* @return [Integer] file descriptor
|
|
532
|
+
*/
|
|
309
533
|
VALUE UM_close_async(VALUE self, VALUE fd) {
|
|
310
534
|
struct um *machine = um_get_machine(self);
|
|
311
535
|
return um_close_async(machine, NUM2INT(fd));
|
|
312
536
|
}
|
|
313
537
|
|
|
314
|
-
|
|
538
|
+
/* call-seq:
|
|
539
|
+
* machine.accept(server_fd) -> connection_fd
|
|
540
|
+
*
|
|
541
|
+
* Accepts an incoming TCP connection.
|
|
542
|
+
*
|
|
543
|
+
* @param server_fd [Integer] listening socket file descriptor
|
|
544
|
+
* @return [Integer] connection file descriptor
|
|
545
|
+
*/
|
|
546
|
+
VALUE UM_accept(VALUE self, VALUE server_fd) {
|
|
315
547
|
struct um *machine = um_get_machine(self);
|
|
316
|
-
return um_accept(machine, NUM2INT(
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
|
|
548
|
+
return um_accept(machine, NUM2INT(server_fd));
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/* call-seq:
|
|
552
|
+
* machine.accept_each(server_fd) { |connection_fd| ... }
|
|
553
|
+
*
|
|
554
|
+
* Repeatedly accepts incoming TCP connections in a loop, yielding the
|
|
555
|
+
* connection file descriptors to the given block.
|
|
556
|
+
*
|
|
557
|
+
* @param server_fd [Integer] listening socket file descriptor
|
|
558
|
+
* @return [void]
|
|
559
|
+
*/
|
|
560
|
+
VALUE UM_accept_each(VALUE self, VALUE server_fd) {
|
|
320
561
|
struct um *machine = um_get_machine(self);
|
|
321
|
-
return um_accept_each(machine, NUM2INT(
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
562
|
+
return um_accept_each(machine, NUM2INT(server_fd));
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/* call-seq:
|
|
566
|
+
* machine.accept_each(server_fd, queue)
|
|
567
|
+
*
|
|
568
|
+
* Repeatedly accepts incoming TCP connections in a loop, pushing the connection
|
|
569
|
+
* file descriptors into the given queue.
|
|
570
|
+
*
|
|
571
|
+
* @param server_fd [Integer] listening socket file descriptor
|
|
572
|
+
* @param queue [UM::Queue] connection queue
|
|
573
|
+
* @return [void]
|
|
574
|
+
*/
|
|
575
|
+
VALUE UM_accept_into_queue(VALUE self, VALUE server_fd, VALUE queue) {
|
|
325
576
|
struct um *machine = um_get_machine(self);
|
|
326
|
-
return um_accept_into_queue(machine, NUM2INT(
|
|
327
|
-
}
|
|
328
|
-
|
|
577
|
+
return um_accept_into_queue(machine, NUM2INT(server_fd), queue);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/* call-seq:
|
|
581
|
+
* machine.socket(domain, type, protocol, flags) -> fd
|
|
582
|
+
*
|
|
583
|
+
* Creates a socket.
|
|
584
|
+
*
|
|
585
|
+
* @param domain [Integer] socket domain
|
|
586
|
+
* @param type [Integer] socket type
|
|
587
|
+
* @param protocol [Integer] socket protocol
|
|
588
|
+
* @param flags [Integer] flags
|
|
589
|
+
* @return [Integer] file descriptor
|
|
590
|
+
*/
|
|
329
591
|
VALUE UM_socket(VALUE self, VALUE domain, VALUE type, VALUE protocol, VALUE flags) {
|
|
330
592
|
struct um *machine = um_get_machine(self);
|
|
331
593
|
return um_socket(machine, NUM2INT(domain), NUM2INT(type), NUM2INT(protocol), NUM2UINT(flags));
|
|
332
594
|
}
|
|
333
595
|
|
|
596
|
+
/* call-seq:
|
|
597
|
+
* machine.shutdown(fd, how) -> 0
|
|
598
|
+
*
|
|
599
|
+
* Shuts down a socket for sending and/or receiving.
|
|
600
|
+
*
|
|
601
|
+
* @param fd [Integer] file descriptor
|
|
602
|
+
* @param how [Integer] how the socket should be shutdown
|
|
603
|
+
* @return [0] success
|
|
604
|
+
*/
|
|
334
605
|
VALUE UM_shutdown(VALUE self, VALUE fd, VALUE how) {
|
|
335
606
|
struct um *machine = um_get_machine(self);
|
|
336
607
|
return um_shutdown(machine, NUM2INT(fd), NUM2INT(how));
|
|
337
608
|
}
|
|
338
609
|
|
|
610
|
+
/* call-seq:
|
|
611
|
+
* machine.shutdown_async(fd, how) -> 0
|
|
612
|
+
*
|
|
613
|
+
* Shuts down a socket for sending and/or receiving. This method may be used to
|
|
614
|
+
* improve performance in situations where the application does not care about
|
|
615
|
+
* whether the operation succeeds or not.
|
|
616
|
+
*
|
|
617
|
+
* @param fd [Integer] file descriptor
|
|
618
|
+
* @param how [Integer] how the socket should be shutdown
|
|
619
|
+
* @return [0] success
|
|
620
|
+
*/
|
|
339
621
|
VALUE UM_shutdown_async(VALUE self, VALUE fd, VALUE how) {
|
|
340
622
|
struct um *machine = um_get_machine(self);
|
|
341
623
|
return um_shutdown_async(machine, NUM2INT(fd), NUM2INT(how));
|
|
342
624
|
}
|
|
343
625
|
|
|
626
|
+
/* call-seq:
|
|
627
|
+
* machine.connect(fd, host, port) -> 0
|
|
628
|
+
*
|
|
629
|
+
* Connects the given socket to the given host and port.
|
|
630
|
+
*
|
|
631
|
+
* @param fd [Integer] file descriptor
|
|
632
|
+
* @param host [String] hostname or IP address
|
|
633
|
+
* @param port [Integer] port number
|
|
634
|
+
* @return [0] success
|
|
635
|
+
*/
|
|
344
636
|
VALUE UM_connect(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
|
345
637
|
struct um *machine = um_get_machine(self);
|
|
346
638
|
|
|
@@ -353,12 +645,37 @@ VALUE UM_connect(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
|
|
353
645
|
return um_connect(machine, NUM2INT(fd), (struct sockaddr *)&addr, sizeof(addr));
|
|
354
646
|
}
|
|
355
647
|
|
|
648
|
+
/* call-seq:
|
|
649
|
+
* machine.send(fd, buffer, len, flags) -> bytes_sent
|
|
650
|
+
*
|
|
651
|
+
* Sends data on the given socket. This method is not guaranteed to send all of
|
|
652
|
+
* the data in the buffer, unless `UM::MSG_WAITALL` is specified in the flags
|
|
653
|
+
* mask.
|
|
654
|
+
*
|
|
655
|
+
* @param fd [Integer] file descriptor
|
|
656
|
+
* @param buffer [String, IO::Buffer] buffer
|
|
657
|
+
* @param len [Integer] number of bytes to send
|
|
658
|
+
* @param flags [Integer] flags mask
|
|
659
|
+
* @return [Integer] number of bytes sent
|
|
660
|
+
*/
|
|
356
661
|
VALUE UM_send(VALUE self, VALUE fd, VALUE buffer, VALUE len, VALUE flags) {
|
|
357
662
|
struct um *machine = um_get_machine(self);
|
|
358
663
|
return um_send(machine, NUM2INT(fd), buffer, NUM2INT(len), NUM2INT(flags));
|
|
359
664
|
}
|
|
360
665
|
|
|
361
666
|
#ifdef HAVE_IO_URING_SEND_VECTORIZED
|
|
667
|
+
|
|
668
|
+
/* call-seq:
|
|
669
|
+
* machine.sendv(fd, *buffers) -> bytes_sent
|
|
670
|
+
*
|
|
671
|
+
* Sends data on the given socket from the given buffers. This method is only
|
|
672
|
+
* available on Linux kernel >= 6.17. This method is guaranteed to send
|
|
673
|
+
*
|
|
674
|
+
* @overload sendv(fd, *buffers)
|
|
675
|
+
* @param fd [Integer] file descriptor
|
|
676
|
+
* @param *buffers [Array<String, IO::Buffer>] buffers
|
|
677
|
+
* @return [Integer] number of bytes sent
|
|
678
|
+
*/
|
|
362
679
|
VALUE UM_sendv(int argc, VALUE *argv, VALUE self) {
|
|
363
680
|
struct um *machine = um_get_machine(self);
|
|
364
681
|
if (argc < 1)
|
|
@@ -368,8 +685,22 @@ VALUE UM_sendv(int argc, VALUE *argv, VALUE self) {
|
|
|
368
685
|
|
|
369
686
|
return um_sendv(machine, fd, argc - 1, argv + 1);
|
|
370
687
|
}
|
|
688
|
+
|
|
371
689
|
#endif
|
|
372
690
|
|
|
691
|
+
/* call-seq:
|
|
692
|
+
* machine.send_bundle(fd, bgid, *buffers) -> bytes_sent
|
|
693
|
+
*
|
|
694
|
+
* Sends data on the given socket from the given buffers using a registered
|
|
695
|
+
* buffer group. The buffer group should have been previously registered using
|
|
696
|
+
* `#setup_buffer_ring`.
|
|
697
|
+
*
|
|
698
|
+
* @overload send_bundle(fd, bgid, *buffers)
|
|
699
|
+
* @param fd [Integer] file descriptor
|
|
700
|
+
* @param bgid [Integer] buffer group id
|
|
701
|
+
* @param *buffers [Array<String, IO::Buffer>] buffers
|
|
702
|
+
* @return [Integer] number of bytes sent
|
|
703
|
+
*/
|
|
373
704
|
VALUE UM_send_bundle(int argc, VALUE *argv, VALUE self) {
|
|
374
705
|
struct um *machine = um_get_machine(self);
|
|
375
706
|
VALUE fd;
|
|
@@ -386,16 +717,49 @@ VALUE UM_send_bundle(int argc, VALUE *argv, VALUE self) {
|
|
|
386
717
|
return um_send_bundle(machine, NUM2INT(fd), NUM2INT(bgid), strings);
|
|
387
718
|
}
|
|
388
719
|
|
|
720
|
+
/* call-seq:
|
|
721
|
+
* machine.recv(fd, buffer, maxlen, flags) -> bytes_received
|
|
722
|
+
*
|
|
723
|
+
* Receives data from the given socket.
|
|
724
|
+
*
|
|
725
|
+
* @param fd [Integer] file descriptor
|
|
726
|
+
* @param buffer [String, IO::Buffer] buffer
|
|
727
|
+
* @param maxlen [Integer] maximum number of bytes to receive
|
|
728
|
+
* @param flags [Integer] flags mask
|
|
729
|
+
* @return [Integer] number of bytes received
|
|
730
|
+
*/
|
|
389
731
|
VALUE UM_recv(VALUE self, VALUE fd, VALUE buffer, VALUE maxlen, VALUE flags) {
|
|
390
732
|
struct um *machine = um_get_machine(self);
|
|
391
733
|
return um_recv(machine, NUM2INT(fd), buffer, NUM2INT(maxlen), NUM2INT(flags));
|
|
392
734
|
}
|
|
393
735
|
|
|
736
|
+
/* call-seq:
|
|
737
|
+
* machine.recv_each(fd, bgid, flags) { |data| ... }
|
|
738
|
+
*
|
|
739
|
+
* Repeatedlty receives data from the given socket in an infinite loop using the
|
|
740
|
+
* given buffer group id. The buffer group should have been previously setup
|
|
741
|
+
* using `#setup_buffer_ring`.
|
|
742
|
+
*
|
|
743
|
+
* @param fd [Integer] file descriptor
|
|
744
|
+
* @param bgid [Integer] buffer group id
|
|
745
|
+
* @param flags [Integer] flags mask
|
|
746
|
+
* @return [void]
|
|
747
|
+
*/
|
|
394
748
|
VALUE UM_recv_each(VALUE self, VALUE fd, VALUE bgid, VALUE flags) {
|
|
395
749
|
struct um *machine = um_get_machine(self);
|
|
396
750
|
return um_recv_each(machine, NUM2INT(fd), NUM2INT(bgid), NUM2INT(flags));
|
|
397
751
|
}
|
|
398
752
|
|
|
753
|
+
/* call-seq:
|
|
754
|
+
* machine.bind(fd, host, port) -> 0
|
|
755
|
+
*
|
|
756
|
+
* Binds the given socket to the given host and port.
|
|
757
|
+
*
|
|
758
|
+
* @param fd [Integer] file descriptor
|
|
759
|
+
* @param host [String] hostname or IP address
|
|
760
|
+
* @param port [Integer] port number
|
|
761
|
+
* @return [0] success
|
|
762
|
+
*/
|
|
399
763
|
VALUE UM_bind(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
|
400
764
|
struct sockaddr_in addr;
|
|
401
765
|
memset(&addr, 0, sizeof(addr));
|
|
@@ -414,6 +778,15 @@ VALUE UM_bind(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
|
|
414
778
|
#endif
|
|
415
779
|
}
|
|
416
780
|
|
|
781
|
+
/* call-seq:
|
|
782
|
+
* machine.listen(fd, backlog) -> 0
|
|
783
|
+
*
|
|
784
|
+
* Starts listening for incoming connections on the given socket.
|
|
785
|
+
*
|
|
786
|
+
* @param fd [Integer] file descriptor
|
|
787
|
+
* @param backlog [String] pending connection queue length
|
|
788
|
+
* @return [0] success
|
|
789
|
+
*/
|
|
417
790
|
VALUE UM_listen(VALUE self, VALUE fd, VALUE backlog) {
|
|
418
791
|
#ifdef HAVE_IO_URING_PREP_LISTEN
|
|
419
792
|
struct um *machine = um_get_machine(self);
|
|
@@ -437,40 +810,104 @@ static inline int numeric_value(VALUE value) {
|
|
|
437
810
|
}
|
|
438
811
|
}
|
|
439
812
|
|
|
813
|
+
/* call-seq:
|
|
814
|
+
* machine.getsockopt(fd, level, opt) -> value
|
|
815
|
+
*
|
|
816
|
+
* Returns the value of a socket option.
|
|
817
|
+
*
|
|
818
|
+
* @param fd [Integer] file descriptor
|
|
819
|
+
* @param level [Integer] level
|
|
820
|
+
* @param opt [Integer] level
|
|
821
|
+
* @return [Integer] option value
|
|
822
|
+
*/
|
|
440
823
|
VALUE UM_getsockopt(VALUE self, VALUE fd, VALUE level, VALUE opt) {
|
|
441
824
|
struct um *machine = um_get_machine(self);
|
|
442
825
|
return um_getsockopt(machine, NUM2INT(fd), NUM2INT(level), NUM2INT(opt));
|
|
443
826
|
}
|
|
444
827
|
|
|
828
|
+
/* call-seq:
|
|
829
|
+
* machine.getsockopt(fd, level, opt, value) -> 0
|
|
830
|
+
*
|
|
831
|
+
* Sets the value of a socket option.
|
|
832
|
+
*
|
|
833
|
+
* @param fd [Integer] file descriptor
|
|
834
|
+
* @param level [Integer] level
|
|
835
|
+
* @param opt [Integer] level
|
|
836
|
+
* @param value [Integer] option value
|
|
837
|
+
* @return [0] success
|
|
838
|
+
*/
|
|
445
839
|
VALUE UM_setsockopt(VALUE self, VALUE fd, VALUE level, VALUE opt, VALUE value) {
|
|
446
840
|
struct um *machine = um_get_machine(self);
|
|
447
841
|
return um_setsockopt(machine, NUM2INT(fd), NUM2INT(level), NUM2INT(opt), numeric_value(value));
|
|
448
842
|
}
|
|
449
843
|
|
|
844
|
+
/* call-seq:
|
|
845
|
+
* machine.synchronize(mutex) { }
|
|
846
|
+
*
|
|
847
|
+
* Synchronizes access to the given mutex. The mutex is locked, the given block
|
|
848
|
+
* is executed and finally the mutex is unlocked.
|
|
849
|
+
*
|
|
850
|
+
* @param mutex [UM::Mutex] mutex
|
|
851
|
+
* @return [any] block return value
|
|
852
|
+
*/
|
|
450
853
|
VALUE UM_mutex_synchronize(VALUE self, VALUE mutex) {
|
|
451
854
|
struct um *machine = um_get_machine(self);
|
|
452
855
|
struct um_mutex *mutex_data = Mutex_data(mutex);
|
|
453
856
|
return um_mutex_synchronize(machine, mutex_data);
|
|
454
857
|
}
|
|
455
858
|
|
|
859
|
+
/* call-seq:
|
|
860
|
+
* machine.push(queue, value) -> queue
|
|
861
|
+
*
|
|
862
|
+
* Pushes a value to the tail of the given queue.
|
|
863
|
+
*
|
|
864
|
+
* @param queue [UM::Queue] queue
|
|
865
|
+
* @param value [any] value
|
|
866
|
+
* @return [UM::Queue] queue
|
|
867
|
+
*/
|
|
456
868
|
VALUE UM_queue_push(VALUE self, VALUE queue, VALUE value) {
|
|
457
869
|
struct um *machine = um_get_machine(self);
|
|
458
870
|
struct um_queue *que = Queue_data(queue);
|
|
459
871
|
return um_queue_push(machine, que, value);
|
|
460
872
|
}
|
|
461
873
|
|
|
874
|
+
/* call-seq:
|
|
875
|
+
* machine.pop(queue) -> value
|
|
876
|
+
*
|
|
877
|
+
* removes a value from the tail of the given queue.
|
|
878
|
+
*
|
|
879
|
+
* @param queue [UM::Queue] queue
|
|
880
|
+
* @return [any] value
|
|
881
|
+
*/
|
|
462
882
|
VALUE UM_queue_pop(VALUE self, VALUE queue) {
|
|
463
883
|
struct um *machine = um_get_machine(self);
|
|
464
884
|
struct um_queue *que = Queue_data(queue);
|
|
465
885
|
return um_queue_pop(machine, que);
|
|
466
886
|
}
|
|
467
887
|
|
|
888
|
+
/* call-seq:
|
|
889
|
+
* machine.unshift(queue, value) -> queue
|
|
890
|
+
*
|
|
891
|
+
* Pushes a value to the head of the given queue.
|
|
892
|
+
*
|
|
893
|
+
* @param queue [UM::Queue] queue
|
|
894
|
+
* @param value [any] value
|
|
895
|
+
* @return [UM::Queue] queue
|
|
896
|
+
*/
|
|
468
897
|
VALUE UM_queue_unshift(VALUE self, VALUE queue, VALUE value) {
|
|
469
898
|
struct um *machine = um_get_machine(self);
|
|
470
899
|
struct um_queue *que = Queue_data(queue);
|
|
471
900
|
return um_queue_unshift(machine, que, value);
|
|
472
901
|
}
|
|
473
902
|
|
|
903
|
+
/* call-seq:
|
|
904
|
+
* machine.pop(queue) -> value
|
|
905
|
+
*
|
|
906
|
+
* removes a value from the head of the given queue.
|
|
907
|
+
*
|
|
908
|
+
* @param queue [UM::Queue] queue
|
|
909
|
+
* @return [any] value
|
|
910
|
+
*/
|
|
474
911
|
VALUE UM_queue_shift(VALUE self, VALUE queue) {
|
|
475
912
|
struct um *machine = um_get_machine(self);
|
|
476
913
|
struct um_queue *que = Queue_data(queue);
|
|
@@ -488,6 +925,18 @@ VALUE UM_open_complete(VALUE arg) {
|
|
|
488
925
|
return ctx->self;
|
|
489
926
|
}
|
|
490
927
|
|
|
928
|
+
/* call-seq:
|
|
929
|
+
* machine.open(pathname, flags) -> fd
|
|
930
|
+
* machine.open(pathname, flags) { |fd| ... }
|
|
931
|
+
*
|
|
932
|
+
* Opens a file using the given pathname and flags. If a block is given, the
|
|
933
|
+
* file descriptor is passed to the block, and the file is automatically closed
|
|
934
|
+
* when the block returns.
|
|
935
|
+
*
|
|
936
|
+
* @param pathname [String] file path
|
|
937
|
+
* @param flags [Integer] flags mask
|
|
938
|
+
* @return [Integer] fd
|
|
939
|
+
*/
|
|
491
940
|
VALUE UM_open(VALUE self, VALUE pathname, VALUE flags) {
|
|
492
941
|
struct um *machine = um_get_machine(self);
|
|
493
942
|
// TODO: take optional perm (mode) arg
|
|
@@ -500,33 +949,136 @@ VALUE UM_open(VALUE self, VALUE pathname, VALUE flags) {
|
|
|
500
949
|
return fd;
|
|
501
950
|
}
|
|
502
951
|
|
|
952
|
+
/* call-seq:
|
|
953
|
+
* machine.poll(fd, mask) -> fd
|
|
954
|
+
*
|
|
955
|
+
* Waits for readiness of the given file descriptor according to the given event
|
|
956
|
+
* mask.
|
|
957
|
+
*
|
|
958
|
+
* @param fd [Integer] file descriptor
|
|
959
|
+
* @param mask [Integer] events mask
|
|
960
|
+
* @return [Integer] fd
|
|
961
|
+
*/
|
|
503
962
|
VALUE UM_poll(VALUE self, VALUE fd, VALUE mask) {
|
|
504
963
|
struct um *machine = um_get_machine(self);
|
|
505
964
|
return um_poll(machine, NUM2INT(fd), NUM2UINT(mask));
|
|
506
965
|
}
|
|
507
966
|
|
|
508
|
-
|
|
967
|
+
/* call-seq:
|
|
968
|
+
* machine.select(read_fds, write_fds, except_fds) -> [read_ready_fds, write_read_fds, except_ready_fds]
|
|
969
|
+
*
|
|
970
|
+
* Waits for readyness of at least one fd for read, write or exception condition
|
|
971
|
+
* from the given fds. This method provides a similar interface to `IO#select`.
|
|
972
|
+
*
|
|
973
|
+
* @param read_fds [Array<Integer>] file descriptors for reading
|
|
974
|
+
* @param write_fds [Array<Integer>] file descriptors for writing
|
|
975
|
+
* @param except_fds [Array<Integer>] file descriptors for exception
|
|
976
|
+
* @return [Array<Array<Integer>>] read-ready, write-ready, and exception-ready fds
|
|
977
|
+
*/
|
|
978
|
+
VALUE UM_select(VALUE self, VALUE read_fds, VALUE write_fds, VALUE except_fds) {
|
|
509
979
|
struct um *machine = um_get_machine(self);
|
|
510
|
-
return um_select(machine,
|
|
511
|
-
}
|
|
512
|
-
|
|
980
|
+
return um_select(machine, read_fds, write_fds, except_fds);
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
/* call-seq:
|
|
984
|
+
* machine.waitid(idtype, id, options) -> [pid, status, code)]
|
|
985
|
+
*
|
|
986
|
+
* Waits for a process to change state. The process to wait for can be specified
|
|
987
|
+
* as a pid or as a pidfd, according to the given `idtype` and `id`.
|
|
988
|
+
*
|
|
989
|
+
* @param idtype [Integer] id type
|
|
990
|
+
* @param id [Integer] id
|
|
991
|
+
* @param options [Integer] options
|
|
992
|
+
* @return [Array<Integer>] pid status
|
|
993
|
+
*/
|
|
513
994
|
VALUE UM_waitid(VALUE self, VALUE idtype, VALUE id, VALUE options) {
|
|
514
995
|
struct um *machine = um_get_machine(self);
|
|
515
996
|
return um_waitid(machine, NUM2INT(idtype), NUM2INT(id), NUM2INT(options));
|
|
516
997
|
}
|
|
517
998
|
|
|
518
999
|
#ifdef HAVE_RB_PROCESS_STATUS_NEW
|
|
1000
|
+
|
|
1001
|
+
/* :nodoc:
|
|
1002
|
+
*
|
|
1003
|
+
* This method depends on the availability of `rb_process_status_new`. See:
|
|
1004
|
+
* https://github.com/ruby/ruby/pull/15213
|
|
1005
|
+
*
|
|
1006
|
+
*/
|
|
519
1007
|
VALUE UM_waitid_status(VALUE self, VALUE idtype, VALUE id, VALUE options) {
|
|
520
1008
|
struct um *machine = um_get_machine(self);
|
|
521
1009
|
return um_waitid_status(machine, NUM2INT(idtype), NUM2INT(id), NUM2INT(options));
|
|
522
1010
|
}
|
|
1011
|
+
|
|
523
1012
|
#endif
|
|
524
1013
|
|
|
1014
|
+
/* call-seq:
|
|
1015
|
+
* machine.prep_timeout(interval) -> timeout
|
|
1016
|
+
*
|
|
1017
|
+
* Prepares an asynchronous timeout instance.
|
|
1018
|
+
*
|
|
1019
|
+
* @param interval [Integer] timeout interval in seconds
|
|
1020
|
+
* @return [UM::AsyncOp] async operation instance
|
|
1021
|
+
*/
|
|
525
1022
|
VALUE UM_prep_timeout(VALUE self, VALUE interval) {
|
|
526
1023
|
struct um *machine = um_get_machine(self);
|
|
527
1024
|
return um_prep_timeout(machine, NUM2DBL(interval));
|
|
528
1025
|
}
|
|
529
1026
|
|
|
1027
|
+
/* call-seq:
|
|
1028
|
+
* machine.ssl_set_bio(ssl) -> machine
|
|
1029
|
+
*
|
|
1030
|
+
* Sets up the given ssl socket to use the machine for sending and receiving.
|
|
1031
|
+
*
|
|
1032
|
+
* @param ssl [OpenSSL::SSL::SSLSocket] ssl socket
|
|
1033
|
+
* @return [UringMachine] machine
|
|
1034
|
+
*/
|
|
1035
|
+
VALUE UM_ssl_set_bio(VALUE self, VALUE ssl) {
|
|
1036
|
+
struct um *machine = um_get_machine(self);
|
|
1037
|
+
um_ssl_set_bio(machine, ssl);
|
|
1038
|
+
return self;
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
/* call-seq:
|
|
1042
|
+
* machine.ssl_read(ssl, buf, maxlen) -> bytes_read
|
|
1043
|
+
*
|
|
1044
|
+
* Reads from the given SSL socket. This method should be used after first
|
|
1045
|
+
* having called `#ssl_set_bio`.
|
|
1046
|
+
*
|
|
1047
|
+
* @param ssl [OpenSSL::SSL::SSLSocket] ssl socket
|
|
1048
|
+
* @param buf [String, IO::Buffer] buffer
|
|
1049
|
+
* @param maxlen [Integer] maximum number of bytes to read
|
|
1050
|
+
* @return [Integer] number of bytes read
|
|
1051
|
+
*/
|
|
1052
|
+
VALUE UM_ssl_read(VALUE self, VALUE ssl, VALUE buf, VALUE maxlen) {
|
|
1053
|
+
struct um *machine = um_get_machine(self);
|
|
1054
|
+
int ret = um_ssl_read(machine, ssl, buf, NUM2INT(maxlen));
|
|
1055
|
+
return INT2NUM(ret);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
/* call-seq:
|
|
1059
|
+
* machine.ssl_write(ssl, buf, len) -> bytes_written
|
|
1060
|
+
*
|
|
1061
|
+
* Writes to the given SSL socket. This method should be used after first
|
|
1062
|
+
* having called `#ssl_set_bio`.
|
|
1063
|
+
*
|
|
1064
|
+
* @param ssl [OpenSSL::SSL::SSLSocket] ssl socket
|
|
1065
|
+
* @param buf [String, IO::Buffer] buffer
|
|
1066
|
+
* @param len [Integer] number of bytes to write
|
|
1067
|
+
* @return [Integer] number of bytes written
|
|
1068
|
+
*/
|
|
1069
|
+
VALUE UM_ssl_write(VALUE self, VALUE ssl, VALUE buf, VALUE len) {
|
|
1070
|
+
struct um *machine = um_get_machine(self);
|
|
1071
|
+
int ret = um_ssl_write(machine, ssl, buf, NUM2INT(len));
|
|
1072
|
+
return INT2NUM(ret);
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
/* call-seq:
|
|
1076
|
+
* UringMachine.pipe -> [read_fd, write_fd]
|
|
1077
|
+
*
|
|
1078
|
+
* Creates a pipe, returning the file descriptors for the read and write ends.
|
|
1079
|
+
*
|
|
1080
|
+
* @return [Array<Integer>] array containing the read and write file descriptors
|
|
1081
|
+
*/
|
|
530
1082
|
VALUE UM_pipe(VALUE self) {
|
|
531
1083
|
int fds[2];
|
|
532
1084
|
int ret = pipe(fds);
|
|
@@ -538,6 +1090,16 @@ VALUE UM_pipe(VALUE self) {
|
|
|
538
1090
|
return rb_ary_new_from_args(2, INT2NUM(fds[0]), INT2NUM(fds[1]));
|
|
539
1091
|
}
|
|
540
1092
|
|
|
1093
|
+
/* call-seq:
|
|
1094
|
+
* UringMachine.socketpair(domain, type, protocol) -> [s1_fd, s2_fd]
|
|
1095
|
+
*
|
|
1096
|
+
* Creates a pair of connected sockets, returning the two file descriptors.
|
|
1097
|
+
*
|
|
1098
|
+
* @param domain [Integer] domain
|
|
1099
|
+
* @param type [Integer] type
|
|
1100
|
+
* @param protocol [Integer] protocol
|
|
1101
|
+
* @return [Array<Integer>] array containing the two file descriptors
|
|
1102
|
+
*/
|
|
541
1103
|
VALUE UM_socketpair(VALUE self, VALUE domain, VALUE type, VALUE protocol) {
|
|
542
1104
|
int fds[2];
|
|
543
1105
|
int ret = socketpair(NUM2INT(domain), NUM2INT(type), NUM2INT(protocol), fds);
|
|
@@ -549,6 +1111,15 @@ VALUE UM_socketpair(VALUE self, VALUE domain, VALUE type, VALUE protocol) {
|
|
|
549
1111
|
return rb_ary_new_from_args(2, INT2NUM(fds[0]), INT2NUM(fds[1]));
|
|
550
1112
|
}
|
|
551
1113
|
|
|
1114
|
+
/* call-seq:
|
|
1115
|
+
* UringMachine.pidfd_open(pid) -> fd
|
|
1116
|
+
*
|
|
1117
|
+
* Creates a file descriptor representing the given process pid. The file
|
|
1118
|
+
* descriptor can then be used with methods such as `#waitid` or `.pidfd_open`.
|
|
1119
|
+
*
|
|
1120
|
+
* @param pid [Integer] process pid
|
|
1121
|
+
* @return [Integer] file descriptor
|
|
1122
|
+
*/
|
|
552
1123
|
VALUE UM_pidfd_open(VALUE self, VALUE pid) {
|
|
553
1124
|
int fd = syscall(SYS_pidfd_open, NUM2INT(pid), 0);
|
|
554
1125
|
if (fd == -1) {
|
|
@@ -559,6 +1130,15 @@ VALUE UM_pidfd_open(VALUE self, VALUE pid) {
|
|
|
559
1130
|
return INT2NUM(fd);
|
|
560
1131
|
}
|
|
561
1132
|
|
|
1133
|
+
/* call-seq:
|
|
1134
|
+
* UringMachine.pidfd_send_signal(fd, sig) -> fd
|
|
1135
|
+
*
|
|
1136
|
+
* Sends a signal to a pidfd.
|
|
1137
|
+
*
|
|
1138
|
+
* @param fd [Integer] pidfd
|
|
1139
|
+
* @param sig [Integer] signal
|
|
1140
|
+
* @return [Integer] pidfd
|
|
1141
|
+
*/
|
|
562
1142
|
VALUE UM_pidfd_send_signal(VALUE self, VALUE fd, VALUE sig) {
|
|
563
1143
|
int ret = syscall(
|
|
564
1144
|
SYS_pidfd_send_signal, NUM2INT(fd), NUM2INT(sig), NULL, 0
|
|
@@ -571,6 +1151,8 @@ VALUE UM_pidfd_send_signal(VALUE self, VALUE fd, VALUE sig) {
|
|
|
571
1151
|
return fd;
|
|
572
1152
|
}
|
|
573
1153
|
|
|
1154
|
+
/* :nodoc:
|
|
1155
|
+
*/
|
|
574
1156
|
VALUE UM_io_nonblock_p(VALUE self, VALUE io) {
|
|
575
1157
|
int fd = rb_io_descriptor(io);
|
|
576
1158
|
int oflags = fcntl(fd, F_GETFL);
|
|
@@ -579,6 +1161,8 @@ VALUE UM_io_nonblock_p(VALUE self, VALUE io) {
|
|
|
579
1161
|
return (oflags & O_NONBLOCK) ? Qtrue : Qfalse;
|
|
580
1162
|
}
|
|
581
1163
|
|
|
1164
|
+
/* :nodoc:
|
|
1165
|
+
*/
|
|
582
1166
|
VALUE UM_io_set_nonblock(VALUE self, VALUE io, VALUE nonblock) {
|
|
583
1167
|
int fd = rb_io_descriptor(io);
|
|
584
1168
|
int oflags = fcntl(fd, F_GETFL);
|
|
@@ -599,15 +1183,104 @@ VALUE UM_io_set_nonblock(VALUE self, VALUE io, VALUE nonblock) {
|
|
|
599
1183
|
return nonblock;
|
|
600
1184
|
}
|
|
601
1185
|
|
|
1186
|
+
/* call-seq:
|
|
1187
|
+
* UringMachine.kernel_version -> version
|
|
1188
|
+
*
|
|
1189
|
+
* Returns the kernel version.
|
|
1190
|
+
*
|
|
1191
|
+
* @return [Integer] kernel version
|
|
1192
|
+
*/
|
|
602
1193
|
VALUE UM_kernel_version(VALUE self) {
|
|
603
1194
|
return INT2NUM(UM_KERNEL_VERSION);
|
|
604
1195
|
}
|
|
605
1196
|
|
|
1197
|
+
/* call-seq:
|
|
1198
|
+
* UringMachine.debug(str)
|
|
1199
|
+
*
|
|
1200
|
+
* Prints the given string to STDERR.
|
|
1201
|
+
*
|
|
1202
|
+
* @param str [String] debug message
|
|
1203
|
+
* @return [void]
|
|
1204
|
+
*/
|
|
606
1205
|
VALUE UM_debug(VALUE self, VALUE str) {
|
|
607
1206
|
fprintf(stderr, "%s\n", StringValueCStr(str));
|
|
608
1207
|
return Qnil;
|
|
609
1208
|
}
|
|
610
1209
|
|
|
1210
|
+
/* call-seq:
|
|
1211
|
+
* UringMachine.inotify_init -> fd
|
|
1212
|
+
*
|
|
1213
|
+
* Creates an inotify file descriptor.
|
|
1214
|
+
*
|
|
1215
|
+
* @return [Integer] file descriptor
|
|
1216
|
+
*/
|
|
1217
|
+
VALUE UM_inotify_init(VALUE self) {
|
|
1218
|
+
int fd = inotify_init();
|
|
1219
|
+
if (fd == -1) {
|
|
1220
|
+
int e = errno;
|
|
1221
|
+
rb_syserr_fail(e, strerror(e));
|
|
1222
|
+
}
|
|
1223
|
+
return INT2NUM(fd);
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
/* call-seq:
|
|
1227
|
+
* UringMachine.inotify_add_watch(fd, path, mask) -> wd
|
|
1228
|
+
*
|
|
1229
|
+
* Adds a watch on the given inotify file descriptor.
|
|
1230
|
+
*
|
|
1231
|
+
* @param fd [Integer] inotify file descriptor
|
|
1232
|
+
* @param path [String] file/directory path
|
|
1233
|
+
* @param mask [Integer] inotify event mask
|
|
1234
|
+
* @return [Integer] watch descriptor
|
|
1235
|
+
*/
|
|
1236
|
+
VALUE UM_inotify_add_watch(VALUE self, VALUE fd, VALUE path, VALUE mask) {
|
|
1237
|
+
int ret = inotify_add_watch(NUM2INT(fd), StringValueCStr(path), NUM2UINT(mask));
|
|
1238
|
+
if (ret == -1) {
|
|
1239
|
+
int e = errno;
|
|
1240
|
+
rb_syserr_fail(e, strerror(e));
|
|
1241
|
+
}
|
|
1242
|
+
return INT2NUM(ret);
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
static inline VALUE inotify_get_events(char *buf, size_t len) {
|
|
1246
|
+
VALUE array = rb_ary_new();
|
|
1247
|
+
while (len > 0) {
|
|
1248
|
+
struct inotify_event *evt = (struct inotify_event *)buf;
|
|
1249
|
+
size_t evt_len = sizeof(struct inotify_event) + evt->len;
|
|
1250
|
+
|
|
1251
|
+
VALUE hash = rb_hash_new();
|
|
1252
|
+
rb_hash_aset(hash, SYM_wd, INT2NUM(evt->wd));
|
|
1253
|
+
rb_hash_aset(hash, SYM_mask, UINT2NUM(evt->mask));
|
|
1254
|
+
rb_hash_aset(hash, SYM_name, rb_str_new_cstr(evt->name));
|
|
1255
|
+
rb_ary_push(array, hash);
|
|
1256
|
+
RB_GC_GUARD(hash);
|
|
1257
|
+
|
|
1258
|
+
buf += evt_len;
|
|
1259
|
+
len -= evt_len;
|
|
1260
|
+
}
|
|
1261
|
+
RB_GC_GUARD(array);
|
|
1262
|
+
return array;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
/* call-seq:
|
|
1266
|
+
* machine.inotify_get_events(fd) -> events
|
|
1267
|
+
*
|
|
1268
|
+
* Waits for and returns one or more events on the given inotify file
|
|
1269
|
+
* descriptor. Each event is returned as a hash containing the watch descriptor,
|
|
1270
|
+
* the file name, and the event mask.
|
|
1271
|
+
*
|
|
1272
|
+
* @param fd [Integer] inotify file descriptor
|
|
1273
|
+
* @return [Array<Hash>] array of one or more events
|
|
1274
|
+
*/
|
|
1275
|
+
VALUE UM_inotify_get_events(VALUE self, VALUE fd) {
|
|
1276
|
+
struct um *machine = um_get_machine(self);
|
|
1277
|
+
|
|
1278
|
+
char buf[4096] __attribute__ ((aligned(__alignof__(struct inotify_event))));
|
|
1279
|
+
|
|
1280
|
+
size_t ret = um_read_raw(machine, NUM2INT(fd), buf, sizeof(buf));
|
|
1281
|
+
return inotify_get_events(buf, ret);
|
|
1282
|
+
}
|
|
1283
|
+
|
|
611
1284
|
void Init_UM(void) {
|
|
612
1285
|
rb_ext_ractor_safe(true);
|
|
613
1286
|
|
|
@@ -639,6 +1312,9 @@ void Init_UM(void) {
|
|
|
639
1312
|
rb_define_singleton_method(cUM, "kernel_version", UM_kernel_version, 0);
|
|
640
1313
|
rb_define_singleton_method(cUM, "debug", UM_debug, 1);
|
|
641
1314
|
|
|
1315
|
+
rb_define_singleton_method(cUM, "inotify_init", UM_inotify_init, 0);
|
|
1316
|
+
rb_define_singleton_method(cUM, "inotify_add_watch", UM_inotify_add_watch, 3);
|
|
1317
|
+
|
|
642
1318
|
rb_define_method(cUM, "schedule", UM_schedule, 2);
|
|
643
1319
|
rb_define_method(cUM, "snooze", UM_snooze, 0);
|
|
644
1320
|
rb_define_method(cUM, "timeout", UM_timeout, 2);
|
|
@@ -697,6 +1373,12 @@ void Init_UM(void) {
|
|
|
697
1373
|
rb_define_method(cUM, "synchronize", UM_mutex_synchronize, 1);
|
|
698
1374
|
rb_define_method(cUM, "unshift", UM_queue_unshift, 2);
|
|
699
1375
|
|
|
1376
|
+
rb_define_method(cUM, "ssl_set_bio", UM_ssl_set_bio, 1);
|
|
1377
|
+
rb_define_method(cUM, "ssl_read", UM_ssl_read, 3);
|
|
1378
|
+
rb_define_method(cUM, "ssl_write", UM_ssl_write, 3);
|
|
1379
|
+
|
|
1380
|
+
rb_define_method(cUM, "inotify_get_events", UM_inotify_get_events, 1);
|
|
1381
|
+
|
|
700
1382
|
eUMError = rb_define_class_under(cUM, "Error", rb_eStandardError);
|
|
701
1383
|
|
|
702
1384
|
um_define_net_constants(cUM);
|
|
@@ -713,5 +1395,9 @@ void Init_UM(void) {
|
|
|
713
1395
|
SYM_time_total_cpu = ID2SYM(rb_intern("time_total_cpu"));
|
|
714
1396
|
SYM_time_total_wait = ID2SYM(rb_intern("time_total_wait"));
|
|
715
1397
|
|
|
1398
|
+
SYM_wd = ID2SYM(rb_intern("wd"));
|
|
1399
|
+
SYM_mask = ID2SYM(rb_intern("mask"));
|
|
1400
|
+
SYM_name = ID2SYM(rb_intern("name"));
|
|
1401
|
+
|
|
716
1402
|
id_fileno = rb_intern_const("fileno");
|
|
717
1403
|
}
|