uringmachine 0.2 → 0.4
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/CHANGELOG.md +15 -0
- data/README.md +85 -0
- data/TODO.md +5 -0
- data/examples/echo_server.rb +18 -40
- data/examples/inout.rb +19 -0
- data/examples/nc.rb +36 -0
- data/ext/um/extconf.rb +6 -15
- data/ext/um/um.c +340 -53
- data/ext/um/um.h +33 -11
- data/ext/um/um_class.c +101 -119
- data/ext/um/um_const.c +184 -0
- data/ext/um/um_op.c +39 -18
- data/ext/um/um_utils.c +48 -3
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +12 -0
- data/test/helper.rb +13 -12
- data/test/test_um.rb +301 -3
- data/vendor/liburing/.github/workflows/build.yml +29 -1
- data/vendor/liburing/.gitignore +1 -0
- data/vendor/liburing/CHANGELOG +15 -0
- data/vendor/liburing/CONTRIBUTING.md +165 -0
- data/vendor/liburing/configure +32 -0
- data/vendor/liburing/examples/Makefile +8 -1
- data/vendor/liburing/examples/kdigest.c +405 -0
- data/vendor/liburing/examples/proxy.c +75 -8
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/src/Makefile +16 -2
- data/vendor/liburing/src/include/liburing/io_uring.h +31 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
- data/vendor/liburing/src/include/liburing.h +31 -4
- data/vendor/liburing/src/liburing-ffi.map +5 -0
- data/vendor/liburing/src/liburing.map +1 -0
- data/vendor/liburing/src/queue.c +3 -0
- data/vendor/liburing/src/register.c +36 -0
- data/vendor/liburing/src/sanitize.c +176 -0
- data/vendor/liburing/src/setup.c +1 -1
- data/vendor/liburing/test/35fa71a030ca.c +7 -0
- data/vendor/liburing/test/500f9fbadef8.c +2 -0
- data/vendor/liburing/test/7ad0e4b2f83c.c +0 -25
- data/vendor/liburing/test/917257daa0fe.c +7 -0
- data/vendor/liburing/test/Makefile +31 -4
- data/vendor/liburing/test/a0908ae19763.c +7 -0
- data/vendor/liburing/test/a4c0b3decb33.c +7 -0
- data/vendor/liburing/test/accept.c +14 -4
- data/vendor/liburing/test/b19062a56726.c +7 -0
- data/vendor/liburing/test/bind-listen.c +2 -2
- data/vendor/liburing/test/buf-ring-nommap.c +10 -3
- data/vendor/liburing/test/buf-ring.c +2 -0
- data/vendor/liburing/test/coredump.c +7 -0
- data/vendor/liburing/test/cq-overflow.c +13 -1
- data/vendor/liburing/test/d4ae271dfaae.c +11 -3
- data/vendor/liburing/test/defer-taskrun.c +2 -2
- data/vendor/liburing/test/defer-tw-timeout.c +4 -1
- data/vendor/liburing/test/defer.c +2 -2
- data/vendor/liburing/test/double-poll-crash.c +1 -1
- data/vendor/liburing/test/eeed8b54e0df.c +2 -0
- data/vendor/liburing/test/eventfd.c +0 -1
- data/vendor/liburing/test/exit-no-cleanup.c +11 -0
- data/vendor/liburing/test/fadvise.c +9 -26
- data/vendor/liburing/test/fdinfo.c +9 -1
- data/vendor/liburing/test/file-register.c +14 -2
- data/vendor/liburing/test/file-update.c +1 -1
- data/vendor/liburing/test/file-verify.c +27 -16
- data/vendor/liburing/test/files-exit-hang-timeout.c +1 -2
- data/vendor/liburing/test/fixed-buf-iter.c +3 -1
- data/vendor/liburing/test/fixed-hugepage.c +12 -1
- data/vendor/liburing/test/fsnotify.c +1 -0
- data/vendor/liburing/test/futex.c +16 -4
- data/vendor/liburing/test/helpers.c +47 -0
- data/vendor/liburing/test/helpers.h +6 -0
- data/vendor/liburing/test/init-mem.c +5 -3
- data/vendor/liburing/test/io-cancel.c +0 -24
- data/vendor/liburing/test/io_uring_passthrough.c +2 -0
- data/vendor/liburing/test/io_uring_register.c +25 -6
- data/vendor/liburing/test/iopoll-leak.c +4 -0
- data/vendor/liburing/test/iopoll-overflow.c +1 -1
- data/vendor/liburing/test/iopoll.c +3 -3
- data/vendor/liburing/test/kallsyms.c +203 -0
- data/vendor/liburing/test/link-timeout.c +159 -0
- data/vendor/liburing/test/linked-defer-close.c +224 -0
- data/vendor/liburing/test/madvise.c +12 -25
- data/vendor/liburing/test/min-timeout-wait.c +0 -25
- data/vendor/liburing/test/min-timeout.c +0 -25
- data/vendor/liburing/test/mkdir.c +6 -0
- data/vendor/liburing/test/msg-ring.c +8 -2
- data/vendor/liburing/test/napi-test.c +15 -2
- data/vendor/liburing/test/no-mmap-inval.c +2 -0
- data/vendor/liburing/test/nop.c +44 -0
- data/vendor/liburing/test/ooo-file-unreg.c +1 -1
- data/vendor/liburing/test/open-close.c +40 -0
- data/vendor/liburing/test/openat2.c +37 -14
- data/vendor/liburing/test/poll-many.c +13 -7
- data/vendor/liburing/test/poll-mshot-update.c +17 -10
- data/vendor/liburing/test/poll-v-poll.c +6 -3
- data/vendor/liburing/test/pollfree.c +148 -0
- data/vendor/liburing/test/read-mshot-empty.c +156 -153
- data/vendor/liburing/test/read-mshot.c +276 -27
- data/vendor/liburing/test/read-write.c +78 -13
- data/vendor/liburing/test/recv-msgall-stream.c +3 -0
- data/vendor/liburing/test/recv-msgall.c +5 -0
- data/vendor/liburing/test/recvsend_bundle-inc.c +680 -0
- data/vendor/liburing/test/recvsend_bundle.c +92 -29
- data/vendor/liburing/test/reg-fd-only.c +14 -4
- data/vendor/liburing/test/regbuf-clone.c +187 -0
- data/vendor/liburing/test/regbuf-merge.c +7 -0
- data/vendor/liburing/test/register-restrictions.c +86 -85
- data/vendor/liburing/test/rename.c +59 -1
- data/vendor/liburing/test/ringbuf-read.c +5 -0
- data/vendor/liburing/test/ringbuf-status.c +5 -1
- data/vendor/liburing/test/runtests.sh +16 -1
- data/vendor/liburing/test/send-zerocopy.c +59 -0
- data/vendor/liburing/test/short-read.c +1 -0
- data/vendor/liburing/test/socket.c +43 -0
- data/vendor/liburing/test/splice.c +3 -1
- data/vendor/liburing/test/sq-poll-dup.c +1 -1
- data/vendor/liburing/test/sq-poll-share.c +2 -0
- data/vendor/liburing/test/sqpoll-disable-exit.c +8 -0
- data/vendor/liburing/test/sqpoll-exit-hang.c +1 -25
- data/vendor/liburing/test/sqpoll-sleep.c +1 -25
- data/vendor/liburing/test/statx.c +89 -0
- data/vendor/liburing/test/stdout.c +2 -0
- data/vendor/liburing/test/submit-and-wait.c +1 -25
- data/vendor/liburing/test/submit-reuse.c +4 -26
- data/vendor/liburing/test/symlink.c +12 -1
- data/vendor/liburing/test/sync-cancel.c +48 -21
- data/vendor/liburing/test/thread-exit.c +5 -0
- data/vendor/liburing/test/timeout-new.c +1 -26
- data/vendor/liburing/test/timeout.c +12 -26
- data/vendor/liburing/test/unlink.c +94 -1
- data/vendor/liburing/test/uring_cmd_ublk.c +1252 -0
- data/vendor/liburing/test/waitid.c +62 -8
- data/vendor/liburing/test/wq-aff.c +35 -0
- data/vendor/liburing/test/xfail_prep_link_timeout_out_of_scope.c +46 -0
- data/vendor/liburing/test/xfail_register_buffers_out_of_scope.c +51 -0
- metadata +17 -4
- data/examples/event_loop.rb +0 -69
- data/examples/fibers.rb +0 -105
data/ext/um/um_class.c
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#include "um.h"
|
|
2
|
-
#include <
|
|
2
|
+
#include <arpa/inet.h>
|
|
3
3
|
|
|
4
4
|
VALUE cUM;
|
|
5
5
|
|
|
@@ -14,7 +14,7 @@ static void UM_compact(void *ptr) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
static void UM_free(void *ptr) {
|
|
17
|
-
|
|
17
|
+
um_teardown((struct um *)ptr);
|
|
18
18
|
free(ptr);
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -43,90 +43,16 @@ inline struct um *get_machine(VALUE self) {
|
|
|
43
43
|
|
|
44
44
|
VALUE UM_initialize(VALUE self) {
|
|
45
45
|
struct um *machine = RTYPEDDATA_DATA(self);
|
|
46
|
-
|
|
47
|
-
machine->ring_initialized = 0;
|
|
48
|
-
machine->unsubmitted_count = 0;
|
|
49
|
-
machine->buffer_ring_count = 0;
|
|
50
|
-
machine->pending_count = 0;
|
|
51
|
-
machine->runqueue_head = NULL;
|
|
52
|
-
machine->runqueue_tail = NULL;
|
|
53
|
-
machine->freelist_head = NULL;
|
|
54
|
-
|
|
55
|
-
unsigned prepared_limit = 4096;
|
|
56
|
-
int flags = 0;
|
|
57
|
-
#ifdef HAVE_IORING_SETUP_SUBMIT_ALL
|
|
58
|
-
flags |= IORING_SETUP_SUBMIT_ALL;
|
|
59
|
-
#endif
|
|
60
|
-
#ifdef HAVE_IORING_SETUP_COOP_TASKRUN
|
|
61
|
-
flags |= IORING_SETUP_COOP_TASKRUN;
|
|
62
|
-
#endif
|
|
63
|
-
|
|
64
|
-
while (1) {
|
|
65
|
-
int ret = io_uring_queue_init(prepared_limit, &machine->ring, flags);
|
|
66
|
-
if (likely(!ret)) break;
|
|
67
|
-
|
|
68
|
-
// if ENOMEM is returned, try with half as much entries
|
|
69
|
-
if (unlikely(ret == -ENOMEM && prepared_limit > 64))
|
|
70
|
-
prepared_limit = prepared_limit / 2;
|
|
71
|
-
else
|
|
72
|
-
rb_syserr_fail(-ret, strerror(-ret));
|
|
73
|
-
}
|
|
74
|
-
machine->ring_initialized = 1;
|
|
75
|
-
|
|
46
|
+
um_setup(machine);
|
|
76
47
|
return self;
|
|
77
48
|
}
|
|
78
49
|
|
|
79
50
|
VALUE UM_setup_buffer_ring(VALUE self, VALUE size, VALUE count) {
|
|
80
51
|
struct um *machine = get_machine(self);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
rb_raise(rb_eRuntimeError, "Cannot setup more than BUFFER_RING_MAX_COUNT buffer rings");
|
|
84
|
-
|
|
85
|
-
struct buf_ring_descriptor *desc = machine->buffer_rings + machine->buffer_ring_count;
|
|
86
|
-
desc->buf_count = NUM2UINT(count);
|
|
87
|
-
desc->buf_size = NUM2UINT(size);
|
|
88
|
-
|
|
89
|
-
desc->br_size = sizeof(struct io_uring_buf) * desc->buf_count;
|
|
90
|
-
void *mapped = mmap(
|
|
91
|
-
NULL, desc->br_size, PROT_READ | PROT_WRITE,
|
|
92
|
-
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0
|
|
93
|
-
);
|
|
94
|
-
if (mapped == MAP_FAILED)
|
|
95
|
-
rb_raise(rb_eRuntimeError, "Failed to allocate buffer ring");
|
|
96
|
-
|
|
97
|
-
desc->br = (struct io_uring_buf_ring *)mapped;
|
|
98
|
-
io_uring_buf_ring_init(desc->br);
|
|
99
|
-
|
|
100
|
-
unsigned bg_id = machine->buffer_ring_count;
|
|
101
|
-
struct io_uring_buf_reg reg = {
|
|
102
|
-
.ring_addr = (unsigned long)desc->br,
|
|
103
|
-
.ring_entries = desc->buf_count,
|
|
104
|
-
.bgid = bg_id
|
|
105
|
-
};
|
|
106
|
-
int ret = io_uring_register_buf_ring(&machine->ring, ®, 0);
|
|
107
|
-
if (ret) {
|
|
108
|
-
munmap(desc->br, desc->br_size);
|
|
109
|
-
rb_syserr_fail(-ret, strerror(-ret));
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
desc->buf_base = malloc(desc->buf_count * desc->buf_size);
|
|
113
|
-
if (!desc->buf_base) {
|
|
114
|
-
io_uring_free_buf_ring(&machine->ring, desc->br, desc->buf_count, bg_id);
|
|
115
|
-
rb_raise(rb_eRuntimeError, "Failed to allocate buffers");
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
int mask = io_uring_buf_ring_mask(desc->buf_count);
|
|
119
|
-
for (unsigned i = 0; i < desc->buf_count; i++) {
|
|
120
|
-
io_uring_buf_ring_add(
|
|
121
|
-
desc->br, desc->buf_base + i * desc->buf_size, desc->buf_size,
|
|
122
|
-
i, mask, i);
|
|
123
|
-
}
|
|
124
|
-
io_uring_buf_ring_advance(desc->br, desc->buf_count);
|
|
125
|
-
machine->buffer_ring_count++;
|
|
126
|
-
return UINT2NUM(bg_id);
|
|
52
|
+
int bgid = um_setup_buffer_ring(machine, NUM2UINT(size), NUM2UINT(count));
|
|
53
|
+
return INT2NUM(bgid);
|
|
127
54
|
}
|
|
128
55
|
|
|
129
|
-
|
|
130
56
|
VALUE UM_pending_count(VALUE self) {
|
|
131
57
|
struct um *machine = get_machine(self);
|
|
132
58
|
return INT2FIX(machine->pending_count);
|
|
@@ -185,6 +111,89 @@ VALUE UM_read_each(VALUE self, VALUE fd, VALUE bgid) {
|
|
|
185
111
|
return um_read_each(machine, NUM2INT(fd), NUM2INT(bgid));
|
|
186
112
|
}
|
|
187
113
|
|
|
114
|
+
VALUE UM_write(int argc, VALUE *argv, VALUE self) {
|
|
115
|
+
struct um *machine = get_machine(self);
|
|
116
|
+
VALUE fd;
|
|
117
|
+
VALUE buffer;
|
|
118
|
+
VALUE len;
|
|
119
|
+
rb_scan_args(argc, argv, "21", &fd, &buffer, &len);
|
|
120
|
+
|
|
121
|
+
int bytes = NIL_P(len) ? RSTRING_LEN(buffer) : NUM2INT(len);
|
|
122
|
+
return um_write(machine, NUM2INT(fd), buffer, bytes);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
VALUE UM_close(VALUE self, VALUE fd) {
|
|
126
|
+
struct um *machine = get_machine(self);
|
|
127
|
+
return um_close(machine, NUM2INT(fd));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
VALUE UM_accept(VALUE self, VALUE fd) {
|
|
131
|
+
struct um *machine = get_machine(self);
|
|
132
|
+
return um_accept(machine, NUM2INT(fd));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
VALUE UM_accept_each(VALUE self, VALUE fd) {
|
|
136
|
+
struct um *machine = get_machine(self);
|
|
137
|
+
return um_accept_each(machine, NUM2INT(fd));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
VALUE UM_socket(VALUE self, VALUE domain, VALUE type, VALUE protocol, VALUE flags) {
|
|
141
|
+
struct um *machine = get_machine(self);
|
|
142
|
+
return um_socket(machine, NUM2INT(domain), NUM2INT(type), NUM2INT(protocol), NUM2UINT(flags));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
VALUE UM_connect(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
|
146
|
+
struct um *machine = get_machine(self);
|
|
147
|
+
|
|
148
|
+
struct sockaddr_in addr;
|
|
149
|
+
memset(&addr, 0, sizeof(addr));
|
|
150
|
+
addr.sin_family = AF_INET;
|
|
151
|
+
addr.sin_addr.s_addr = inet_addr(StringValueCStr(host));
|
|
152
|
+
addr.sin_port = htons(NUM2INT(port));
|
|
153
|
+
|
|
154
|
+
return um_connect(machine, NUM2INT(fd), (struct sockaddr *)&addr, sizeof(addr));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
VALUE UM_send(VALUE self, VALUE fd, VALUE buffer, VALUE len, VALUE flags) {
|
|
158
|
+
struct um *machine = get_machine(self);
|
|
159
|
+
return um_send(machine, NUM2INT(fd), buffer, NUM2INT(len), NUM2INT(flags));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
VALUE UM_recv(VALUE self, VALUE fd, VALUE buffer, VALUE maxlen, VALUE flags) {
|
|
163
|
+
struct um *machine = get_machine(self);
|
|
164
|
+
return um_recv(machine, NUM2INT(fd), buffer, NUM2INT(maxlen), NUM2INT(flags));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
VALUE UM_bind(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
|
168
|
+
struct sockaddr_in addr;
|
|
169
|
+
memset(&addr, 0, sizeof(addr));
|
|
170
|
+
addr.sin_family = AF_INET;
|
|
171
|
+
addr.sin_addr.s_addr = inet_addr(StringValueCStr(host));
|
|
172
|
+
addr.sin_port = htons(NUM2INT(port));
|
|
173
|
+
|
|
174
|
+
#ifdef HAVE_IO_URING_PREP_BIND
|
|
175
|
+
struct um *machine = get_machine(self);
|
|
176
|
+
return um_bind(machine, NUM2INT(fd), (struct sockaddr *)&addr, sizeof(addr));
|
|
177
|
+
#else
|
|
178
|
+
int res = bind(NUM2INT(fd), (struct sockaddr *)&addr, sizeof(addr));
|
|
179
|
+
if (res)
|
|
180
|
+
rb_syserr_fail(errno, strerror(errno));
|
|
181
|
+
return INT2NUM(0);
|
|
182
|
+
#endif
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
VALUE UM_listen(VALUE self, VALUE fd, VALUE backlog) {
|
|
186
|
+
#ifdef HAVE_IO_URING_PREP_LISTEN
|
|
187
|
+
struct um *machine = get_machine(self);
|
|
188
|
+
return um_listen(machine, NUM2INT(fd), NUM2INT(backlog));
|
|
189
|
+
#else
|
|
190
|
+
int res = listen(NUM2INT(fd), NUM2INT(backlog));
|
|
191
|
+
if (res)
|
|
192
|
+
rb_syserr_fail(errno, strerror(errno));
|
|
193
|
+
return INT2NUM(0);
|
|
194
|
+
#endif
|
|
195
|
+
}
|
|
196
|
+
|
|
188
197
|
void Init_UM(void) {
|
|
189
198
|
rb_ext_ractor_safe(true);
|
|
190
199
|
|
|
@@ -204,44 +213,17 @@ void Init_UM(void) {
|
|
|
204
213
|
rb_define_method(cUM, "sleep", UM_sleep, 1);
|
|
205
214
|
rb_define_method(cUM, "read", UM_read, -1);
|
|
206
215
|
rb_define_method(cUM, "read_each", UM_read_each, 2);
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// rb_define_method(cUM, "process_completions", UM_process_completions, -1);
|
|
221
|
-
// rb_define_method(cUM, "process_completions_loop", UM_process_completions_loop, 0);
|
|
222
|
-
|
|
223
|
-
// SYM_accept = MAKE_SYM("accept");
|
|
224
|
-
// SYM_block = MAKE_SYM("block");
|
|
225
|
-
// SYM_buffer = MAKE_SYM("buffer");
|
|
226
|
-
// SYM_buffer_group = MAKE_SYM("buffer_group");
|
|
227
|
-
// SYM_buffer_offset = MAKE_SYM("buffer_offset");
|
|
228
|
-
// SYM_close = MAKE_SYM("close");
|
|
229
|
-
// SYM_count = MAKE_SYM("count");
|
|
230
|
-
// SYM_emit = MAKE_SYM("emit");
|
|
231
|
-
// SYM_fd = MAKE_SYM("fd");
|
|
232
|
-
// SYM_id = MAKE_SYM("id");
|
|
233
|
-
// SYM_interval = MAKE_SYM("interval");
|
|
234
|
-
// SYM_len = MAKE_SYM("len");
|
|
235
|
-
// SYM_link = MAKE_SYM("link");
|
|
236
|
-
// SYM_multishot = MAKE_SYM("multishot");
|
|
237
|
-
// SYM_op = MAKE_SYM("op");
|
|
238
|
-
// SYM_read = MAKE_SYM("read");
|
|
239
|
-
// SYM_result = MAKE_SYM("result");
|
|
240
|
-
// SYM_signal = MAKE_SYM("signal");
|
|
241
|
-
// SYM_size = MAKE_SYM("size");
|
|
242
|
-
// SYM_spec_data = MAKE_SYM("spec_data");
|
|
243
|
-
// SYM_stop = MAKE_SYM("stop");
|
|
244
|
-
// SYM_timeout = MAKE_SYM("timeout");
|
|
245
|
-
// SYM_utf8 = MAKE_SYM("utf8");
|
|
246
|
-
// SYM_write = MAKE_SYM("write");
|
|
216
|
+
rb_define_method(cUM, "write", UM_write, -1);
|
|
217
|
+
rb_define_method(cUM, "close", UM_close, 1);
|
|
218
|
+
|
|
219
|
+
rb_define_method(cUM, "accept", UM_accept, 1);
|
|
220
|
+
rb_define_method(cUM, "accept_each", UM_accept_each, 1);
|
|
221
|
+
rb_define_method(cUM, "socket", UM_socket, 4);
|
|
222
|
+
rb_define_method(cUM, "connect", UM_connect, 3);
|
|
223
|
+
rb_define_method(cUM, "send", UM_send, 4);
|
|
224
|
+
rb_define_method(cUM, "recv", UM_recv, 4);
|
|
225
|
+
rb_define_method(cUM, "bind", UM_bind, 3);
|
|
226
|
+
rb_define_method(cUM, "listen", UM_listen, 2);
|
|
227
|
+
|
|
228
|
+
um_define_net_constants(cUM);
|
|
247
229
|
}
|
data/ext/um/um_const.c
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#include "ruby.h"
|
|
2
|
+
#include <arpa/inet.h>
|
|
3
|
+
#include <sys/types.h>
|
|
4
|
+
#include <sys/socket.h>
|
|
5
|
+
#include <netinet/in.h>
|
|
6
|
+
#include <netinet/tcp.h>
|
|
7
|
+
#include <netinet/udp.h>
|
|
8
|
+
#include <netdb.h>
|
|
9
|
+
#include <net/if.h>
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
#define DEF_CONST_INT(mod, v) rb_define_const(mod, #v, INT2NUM(v))
|
|
13
|
+
|
|
14
|
+
void um_define_net_constants(VALUE mod) {
|
|
15
|
+
DEF_CONST_INT(mod, SOCK_STREAM);
|
|
16
|
+
DEF_CONST_INT(mod, SOCK_DGRAM);
|
|
17
|
+
DEF_CONST_INT(mod, SOCK_RAW);
|
|
18
|
+
DEF_CONST_INT(mod, SOCK_RDM);
|
|
19
|
+
DEF_CONST_INT(mod, SOCK_SEQPACKET);
|
|
20
|
+
DEF_CONST_INT(mod, SOCK_PACKET);
|
|
21
|
+
DEF_CONST_INT(mod, SOCK_CLOEXEC);
|
|
22
|
+
|
|
23
|
+
DEF_CONST_INT(mod, AF_UNSPEC);
|
|
24
|
+
DEF_CONST_INT(mod, PF_UNSPEC);
|
|
25
|
+
DEF_CONST_INT(mod, AF_INET);
|
|
26
|
+
DEF_CONST_INT(mod, PF_INET);
|
|
27
|
+
DEF_CONST_INT(mod, AF_INET6);
|
|
28
|
+
DEF_CONST_INT(mod, PF_INET6);
|
|
29
|
+
DEF_CONST_INT(mod, AF_UNIX);
|
|
30
|
+
DEF_CONST_INT(mod, PF_UNIX);
|
|
31
|
+
DEF_CONST_INT(mod, AF_LOCAL);
|
|
32
|
+
DEF_CONST_INT(mod, PF_LOCAL);
|
|
33
|
+
DEF_CONST_INT(mod, AF_ROUTE);
|
|
34
|
+
DEF_CONST_INT(mod, PF_ROUTE);
|
|
35
|
+
DEF_CONST_INT(mod, AF_MAX);
|
|
36
|
+
DEF_CONST_INT(mod, PF_MAX);
|
|
37
|
+
|
|
38
|
+
DEF_CONST_INT(mod, MSG_OOB);
|
|
39
|
+
DEF_CONST_INT(mod, MSG_PEEK);
|
|
40
|
+
DEF_CONST_INT(mod, MSG_DONTROUTE);
|
|
41
|
+
DEF_CONST_INT(mod, MSG_WAITALL);
|
|
42
|
+
DEF_CONST_INT(mod, MSG_DONTWAIT);
|
|
43
|
+
DEF_CONST_INT(mod, MSG_MORE);
|
|
44
|
+
|
|
45
|
+
DEF_CONST_INT(mod, SOL_SOCKET);
|
|
46
|
+
DEF_CONST_INT(mod, SOL_IP);
|
|
47
|
+
|
|
48
|
+
DEF_CONST_INT(mod, IPPROTO_IP);
|
|
49
|
+
DEF_CONST_INT(mod, IPPROTO_ICMP);
|
|
50
|
+
DEF_CONST_INT(mod, IPPROTO_IGMP);
|
|
51
|
+
DEF_CONST_INT(mod, IPPROTO_TCP);
|
|
52
|
+
DEF_CONST_INT(mod, IPPROTO_EGP);
|
|
53
|
+
DEF_CONST_INT(mod, IPPROTO_PUP);
|
|
54
|
+
DEF_CONST_INT(mod, IPPROTO_UDP);
|
|
55
|
+
DEF_CONST_INT(mod, IPPROTO_IDP);
|
|
56
|
+
DEF_CONST_INT(mod, IPPROTO_IPV6);
|
|
57
|
+
DEF_CONST_INT(mod, IPPROTO_NONE);
|
|
58
|
+
DEF_CONST_INT(mod, IPPROTO_ROUTING);
|
|
59
|
+
DEF_CONST_INT(mod, IPPROTO_RAW);
|
|
60
|
+
DEF_CONST_INT(mod, IPPROTO_MAX);
|
|
61
|
+
|
|
62
|
+
DEF_CONST_INT(mod, INADDR_ANY);
|
|
63
|
+
DEF_CONST_INT(mod, INADDR_BROADCAST);
|
|
64
|
+
DEF_CONST_INT(mod, INADDR_LOOPBACK);
|
|
65
|
+
DEF_CONST_INT(mod, INADDR_NONE);
|
|
66
|
+
|
|
67
|
+
DEF_CONST_INT(mod, IP_OPTIONS);
|
|
68
|
+
DEF_CONST_INT(mod, IP_HDRINCL);
|
|
69
|
+
DEF_CONST_INT(mod, IP_TOS);
|
|
70
|
+
DEF_CONST_INT(mod, IP_TTL);
|
|
71
|
+
DEF_CONST_INT(mod, IP_RECVOPTS);
|
|
72
|
+
DEF_CONST_INT(mod, IP_MINTTL);
|
|
73
|
+
DEF_CONST_INT(mod, IP_RECVTTL);
|
|
74
|
+
|
|
75
|
+
DEF_CONST_INT(mod, SO_DEBUG);
|
|
76
|
+
DEF_CONST_INT(mod, SO_REUSEADDR);
|
|
77
|
+
DEF_CONST_INT(mod, SO_REUSEPORT);
|
|
78
|
+
DEF_CONST_INT(mod, SO_TYPE);
|
|
79
|
+
DEF_CONST_INT(mod, SO_ERROR);
|
|
80
|
+
DEF_CONST_INT(mod, SO_DONTROUTE);
|
|
81
|
+
DEF_CONST_INT(mod, SO_BROADCAST);
|
|
82
|
+
DEF_CONST_INT(mod, SO_SNDBUF);
|
|
83
|
+
DEF_CONST_INT(mod, SO_RCVBUF);
|
|
84
|
+
DEF_CONST_INT(mod, SO_SNDBUFFORCE);
|
|
85
|
+
DEF_CONST_INT(mod, SO_RCVBUFFORCE);
|
|
86
|
+
DEF_CONST_INT(mod, SO_KEEPALIVE);
|
|
87
|
+
DEF_CONST_INT(mod, SO_OOBINLINE);
|
|
88
|
+
DEF_CONST_INT(mod, SO_PRIORITY);
|
|
89
|
+
DEF_CONST_INT(mod, SO_LINGER);
|
|
90
|
+
DEF_CONST_INT(mod, SO_PASSCRED);
|
|
91
|
+
DEF_CONST_INT(mod, SO_PEERCRED);
|
|
92
|
+
DEF_CONST_INT(mod, SO_RCVLOWAT);
|
|
93
|
+
DEF_CONST_INT(mod, SO_SNDLOWAT);
|
|
94
|
+
DEF_CONST_INT(mod, SO_RCVTIMEO);
|
|
95
|
+
DEF_CONST_INT(mod, SO_SNDTIMEO);
|
|
96
|
+
DEF_CONST_INT(mod, SO_ACCEPTCONN);
|
|
97
|
+
DEF_CONST_INT(mod, SO_PEERNAME);
|
|
98
|
+
DEF_CONST_INT(mod, SO_TIMESTAMP);
|
|
99
|
+
DEF_CONST_INT(mod, SO_MARK);
|
|
100
|
+
DEF_CONST_INT(mod, SO_PROTOCOL);
|
|
101
|
+
DEF_CONST_INT(mod, SO_DOMAIN);
|
|
102
|
+
DEF_CONST_INT(mod, SO_PEEK_OFF);
|
|
103
|
+
DEF_CONST_INT(mod, SO_BUSY_POLL);
|
|
104
|
+
|
|
105
|
+
DEF_CONST_INT(mod, TCP_NODELAY);
|
|
106
|
+
DEF_CONST_INT(mod, TCP_MAXSEG);
|
|
107
|
+
DEF_CONST_INT(mod, TCP_CORK);
|
|
108
|
+
DEF_CONST_INT(mod, TCP_DEFER_ACCEPT);
|
|
109
|
+
DEF_CONST_INT(mod, TCP_INFO);
|
|
110
|
+
DEF_CONST_INT(mod, TCP_KEEPCNT);
|
|
111
|
+
DEF_CONST_INT(mod, TCP_KEEPIDLE);
|
|
112
|
+
DEF_CONST_INT(mod, TCP_KEEPINTVL);
|
|
113
|
+
DEF_CONST_INT(mod, TCP_LINGER2);
|
|
114
|
+
DEF_CONST_INT(mod, TCP_MD5SIG);
|
|
115
|
+
DEF_CONST_INT(mod, TCP_QUICKACK);
|
|
116
|
+
DEF_CONST_INT(mod, TCP_SYNCNT);
|
|
117
|
+
DEF_CONST_INT(mod, TCP_WINDOW_CLAMP);
|
|
118
|
+
DEF_CONST_INT(mod, TCP_FASTOPEN);
|
|
119
|
+
DEF_CONST_INT(mod, TCP_CONGESTION);
|
|
120
|
+
DEF_CONST_INT(mod, TCP_COOKIE_TRANSACTIONS);
|
|
121
|
+
DEF_CONST_INT(mod, TCP_QUEUE_SEQ);
|
|
122
|
+
DEF_CONST_INT(mod, TCP_REPAIR);
|
|
123
|
+
DEF_CONST_INT(mod, TCP_REPAIR_OPTIONS);
|
|
124
|
+
DEF_CONST_INT(mod, TCP_REPAIR_QUEUE);
|
|
125
|
+
DEF_CONST_INT(mod, TCP_THIN_LINEAR_TIMEOUTS);
|
|
126
|
+
DEF_CONST_INT(mod, TCP_TIMESTAMP);
|
|
127
|
+
DEF_CONST_INT(mod, TCP_USER_TIMEOUT);
|
|
128
|
+
|
|
129
|
+
DEF_CONST_INT(mod, UDP_CORK);
|
|
130
|
+
|
|
131
|
+
DEF_CONST_INT(mod, AI_PASSIVE);
|
|
132
|
+
DEF_CONST_INT(mod, AI_CANONNAME);
|
|
133
|
+
DEF_CONST_INT(mod, AI_NUMERICHOST);
|
|
134
|
+
DEF_CONST_INT(mod, AI_NUMERICSERV);
|
|
135
|
+
DEF_CONST_INT(mod, AI_ALL);
|
|
136
|
+
DEF_CONST_INT(mod, AI_ADDRCONFIG);
|
|
137
|
+
DEF_CONST_INT(mod, AI_V4MAPPED);
|
|
138
|
+
|
|
139
|
+
DEF_CONST_INT(mod, NI_MAXHOST);
|
|
140
|
+
DEF_CONST_INT(mod, NI_MAXSERV);
|
|
141
|
+
DEF_CONST_INT(mod, NI_NOFQDN);
|
|
142
|
+
DEF_CONST_INT(mod, NI_NUMERICHOST);
|
|
143
|
+
DEF_CONST_INT(mod, NI_NAMEREQD);
|
|
144
|
+
DEF_CONST_INT(mod, NI_NUMERICSERV);
|
|
145
|
+
DEF_CONST_INT(mod, NI_DGRAM);
|
|
146
|
+
|
|
147
|
+
DEF_CONST_INT(mod, SHUT_RD);
|
|
148
|
+
DEF_CONST_INT(mod, SHUT_WR);
|
|
149
|
+
DEF_CONST_INT(mod, SHUT_RDWR);
|
|
150
|
+
|
|
151
|
+
DEF_CONST_INT(mod, IPV6_JOIN_GROUP);
|
|
152
|
+
DEF_CONST_INT(mod, IPV6_LEAVE_GROUP);
|
|
153
|
+
DEF_CONST_INT(mod, IPV6_MULTICAST_HOPS);
|
|
154
|
+
DEF_CONST_INT(mod, IPV6_MULTICAST_IF);
|
|
155
|
+
DEF_CONST_INT(mod, IPV6_MULTICAST_LOOP);
|
|
156
|
+
DEF_CONST_INT(mod, IPV6_UNICAST_HOPS);
|
|
157
|
+
DEF_CONST_INT(mod, IPV6_V6ONLY);
|
|
158
|
+
DEF_CONST_INT(mod, IPV6_CHECKSUM);
|
|
159
|
+
DEF_CONST_INT(mod, IPV6_DONTFRAG);
|
|
160
|
+
DEF_CONST_INT(mod, IPV6_DSTOPTS);
|
|
161
|
+
DEF_CONST_INT(mod, IPV6_HOPLIMIT);
|
|
162
|
+
DEF_CONST_INT(mod, IPV6_HOPOPTS);
|
|
163
|
+
DEF_CONST_INT(mod, IPV6_NEXTHOP);
|
|
164
|
+
DEF_CONST_INT(mod, IPV6_PATHMTU);
|
|
165
|
+
DEF_CONST_INT(mod, IPV6_PKTINFO);
|
|
166
|
+
DEF_CONST_INT(mod, IPV6_RECVDSTOPTS);
|
|
167
|
+
DEF_CONST_INT(mod, IPV6_RECVHOPLIMIT);
|
|
168
|
+
DEF_CONST_INT(mod, IPV6_RECVHOPOPTS);
|
|
169
|
+
DEF_CONST_INT(mod, IPV6_RECVPKTINFO);
|
|
170
|
+
DEF_CONST_INT(mod, IPV6_RECVRTHDR);
|
|
171
|
+
DEF_CONST_INT(mod, IPV6_RECVTCLASS);
|
|
172
|
+
DEF_CONST_INT(mod, IPV6_RTHDR);
|
|
173
|
+
DEF_CONST_INT(mod, IPV6_RTHDRDSTOPTS);
|
|
174
|
+
DEF_CONST_INT(mod, IPV6_RTHDR_TYPE_0);
|
|
175
|
+
DEF_CONST_INT(mod, IPV6_RECVPATHMTU);
|
|
176
|
+
DEF_CONST_INT(mod, IPV6_TCLASS);
|
|
177
|
+
|
|
178
|
+
DEF_CONST_INT(mod, INET_ADDRSTRLEN);
|
|
179
|
+
DEF_CONST_INT(mod, INET6_ADDRSTRLEN);
|
|
180
|
+
|
|
181
|
+
DEF_CONST_INT(mod, IF_NAMESIZE);
|
|
182
|
+
|
|
183
|
+
DEF_CONST_INT(mod, SOMAXCONN);
|
|
184
|
+
}
|
data/ext/um/um_op.c
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
#include "um.h"
|
|
2
2
|
|
|
3
|
+
inline struct um_result_entry *um_result_checkout(struct um *machine) {
|
|
4
|
+
if (machine->result_freelist) {
|
|
5
|
+
struct um_result_entry *entry = machine->result_freelist;
|
|
6
|
+
machine->result_freelist = entry->next;
|
|
7
|
+
return entry;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
struct um_result_entry *entry = malloc(sizeof(struct um_result_entry));
|
|
11
|
+
return entry;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
inline void um_result_checkin(struct um *machine, struct um_result_entry *entry) {
|
|
15
|
+
entry->next = machine->result_freelist;
|
|
16
|
+
machine->result_freelist = entry;
|
|
17
|
+
}
|
|
18
|
+
|
|
3
19
|
inline void um_op_result_cleanup(struct um *machine, struct um_op *op) {
|
|
4
20
|
struct um_result_entry *entry = op->results_head;
|
|
5
21
|
while (entry) {
|
|
6
22
|
struct um_result_entry *next = entry->next;
|
|
7
|
-
|
|
23
|
+
um_result_checkin(machine, entry);
|
|
8
24
|
entry = next;
|
|
9
25
|
}
|
|
10
26
|
op->results_head = op->results_tail = NULL;
|
|
11
27
|
}
|
|
12
28
|
|
|
13
|
-
inline void um_op_result_push(struct um *machine, struct um_op *op,
|
|
14
|
-
struct um_result_entry *entry =
|
|
29
|
+
inline void um_op_result_push(struct um *machine, struct um_op *op, __s32 result, __u32 flags) {
|
|
30
|
+
struct um_result_entry *entry = um_result_checkout(machine);
|
|
15
31
|
entry->next = 0;
|
|
16
32
|
entry->result = result;
|
|
17
33
|
entry->flags = flags;
|
|
@@ -24,7 +40,7 @@ inline void um_op_result_push(struct um *machine, struct um_op *op, int result,
|
|
|
24
40
|
}
|
|
25
41
|
}
|
|
26
42
|
|
|
27
|
-
inline int um_op_result_shift(struct um *machine, struct um_op *op,
|
|
43
|
+
inline int um_op_result_shift(struct um *machine, struct um_op *op, __s32 *result, __u32 *flags) {
|
|
28
44
|
if (!op->results_head) return 0;
|
|
29
45
|
|
|
30
46
|
struct um_result_entry *entry = op->results_head;
|
|
@@ -33,7 +49,7 @@ inline int um_op_result_shift(struct um *machine, struct um_op *op, int *result,
|
|
|
33
49
|
op->results_head = entry->next;
|
|
34
50
|
if (!op->results_head)
|
|
35
51
|
op->results_tail = NULL;
|
|
36
|
-
|
|
52
|
+
um_result_checkin(machine, entry);
|
|
37
53
|
return 1;
|
|
38
54
|
}
|
|
39
55
|
|
|
@@ -45,25 +61,22 @@ inline void um_op_clear(struct um_op *op) {
|
|
|
45
61
|
inline struct um_op *um_op_checkout(struct um *machine) {
|
|
46
62
|
machine->pending_count++;
|
|
47
63
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
machine->
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
64
|
+
struct um_op *op = machine->op_freelist;
|
|
65
|
+
if (op)
|
|
66
|
+
machine->op_freelist = op->next;
|
|
67
|
+
else
|
|
68
|
+
op = malloc(sizeof(struct um_op));
|
|
54
69
|
|
|
55
|
-
struct um_op *op = malloc(sizeof(struct um_op));
|
|
56
70
|
um_op_clear(op);
|
|
57
71
|
return op;
|
|
58
72
|
}
|
|
59
73
|
|
|
60
74
|
inline void um_op_checkin(struct um *machine, struct um_op *op) {
|
|
61
|
-
um_op_result_cleanup(machine, op);
|
|
62
|
-
|
|
63
75
|
machine->pending_count--;
|
|
64
76
|
|
|
65
|
-
op
|
|
66
|
-
|
|
77
|
+
um_op_result_cleanup(machine, op);
|
|
78
|
+
op->next = machine->op_freelist;
|
|
79
|
+
machine->op_freelist = op;
|
|
67
80
|
}
|
|
68
81
|
|
|
69
82
|
inline struct um_op *um_runqueue_find_by_fiber(struct um *machine, VALUE fiber) {
|
|
@@ -108,7 +121,7 @@ inline struct um_op *um_runqueue_shift(struct um *machine) {
|
|
|
108
121
|
|
|
109
122
|
op->prev = NULL;
|
|
110
123
|
if (!op->next) {
|
|
111
|
-
machine->runqueue_head = machine->runqueue_tail = NULL;
|
|
124
|
+
machine->runqueue_head = machine->runqueue_tail = NULL;
|
|
112
125
|
}
|
|
113
126
|
else {
|
|
114
127
|
machine->runqueue_head = op->next;
|
|
@@ -117,7 +130,7 @@ inline struct um_op *um_runqueue_shift(struct um *machine) {
|
|
|
117
130
|
return op;
|
|
118
131
|
}
|
|
119
132
|
|
|
120
|
-
inline void
|
|
133
|
+
inline void um_free_op_linked_list(struct um *machine, struct um_op *op) {
|
|
121
134
|
while (op) {
|
|
122
135
|
struct um_op *next = op->next;
|
|
123
136
|
um_op_result_cleanup(machine, op);
|
|
@@ -125,3 +138,11 @@ inline void um_free_linked_list(struct um *machine, struct um_op *op) {
|
|
|
125
138
|
op = next;
|
|
126
139
|
}
|
|
127
140
|
}
|
|
141
|
+
|
|
142
|
+
inline void um_free_result_linked_list(struct um *machine, struct um_result_entry *entry) {
|
|
143
|
+
while (entry) {
|
|
144
|
+
struct um_result_entry *next = entry->next;
|
|
145
|
+
free(entry);
|
|
146
|
+
entry = next;
|
|
147
|
+
}
|
|
148
|
+
}
|
data/ext/um/um_utils.c
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#include "um.h"
|
|
2
|
+
#include <sys/mman.h>
|
|
3
|
+
#include <stdlib.h>
|
|
2
4
|
|
|
3
5
|
inline struct __kernel_timespec um_double_to_timespec(double value) {
|
|
4
6
|
double integral;
|
|
@@ -46,13 +48,56 @@ static inline void adjust_read_buffer_len(VALUE buffer, int result, int ofs) {
|
|
|
46
48
|
rb_str_set_len(buffer, len + (unsigned)ofs);
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
inline void um_update_read_buffer(struct um *machine, VALUE buffer, int buffer_offset,
|
|
51
|
+
inline void um_update_read_buffer(struct um *machine, VALUE buffer, int buffer_offset, __s32 result, __u32 flags) {
|
|
50
52
|
if (!result) return;
|
|
51
53
|
|
|
52
54
|
adjust_read_buffer_len(buffer, result, buffer_offset);
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
int um_setup_buffer_ring(struct um *machine, unsigned size, unsigned count) {
|
|
58
|
+
if (machine->buffer_ring_count == BUFFER_RING_MAX_COUNT)
|
|
59
|
+
rb_raise(rb_eRuntimeError, "Cannot setup more than BUFFER_RING_MAX_COUNT buffer rings");
|
|
60
|
+
|
|
61
|
+
struct buf_ring_descriptor *desc = machine->buffer_rings + machine->buffer_ring_count;
|
|
62
|
+
desc->buf_count = count;
|
|
63
|
+
desc->buf_size = size;
|
|
64
|
+
|
|
65
|
+
desc->br_size = sizeof(struct io_uring_buf) * desc->buf_count;
|
|
66
|
+
void *mapped = mmap(
|
|
67
|
+
NULL, desc->br_size, PROT_READ | PROT_WRITE,
|
|
68
|
+
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0
|
|
69
|
+
);
|
|
70
|
+
if (mapped == MAP_FAILED)
|
|
71
|
+
rb_raise(rb_eRuntimeError, "Failed to allocate buffer ring");
|
|
72
|
+
|
|
73
|
+
desc->br = (struct io_uring_buf_ring *)mapped;
|
|
74
|
+
io_uring_buf_ring_init(desc->br);
|
|
75
|
+
|
|
76
|
+
unsigned bg_id = machine->buffer_ring_count;
|
|
77
|
+
int ret;
|
|
78
|
+
desc->br = io_uring_setup_buf_ring(&machine->ring, count, bg_id, 0, &ret);
|
|
79
|
+
if (!desc->br) {
|
|
80
|
+
munmap(desc->br, desc->br_size);
|
|
81
|
+
rb_syserr_fail(ret, strerror(ret));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (posix_memalign(&desc->buf_base, 4096, desc->buf_count * desc->buf_size)) {
|
|
85
|
+
io_uring_free_buf_ring(&machine->ring, desc->br, desc->buf_count, bg_id);
|
|
86
|
+
rb_raise(rb_eRuntimeError, "Failed to allocate buffers");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
desc->buf_mask = io_uring_buf_ring_mask(desc->buf_count);
|
|
90
|
+
void *ptr = desc->buf_base;
|
|
91
|
+
for (unsigned i = 0; i < desc->buf_count; i++) {
|
|
92
|
+
io_uring_buf_ring_add(desc->br, ptr, desc->buf_size, i, desc->buf_mask, i);
|
|
93
|
+
ptr += desc->buf_size;
|
|
94
|
+
}
|
|
95
|
+
io_uring_buf_ring_advance(desc->br, desc->buf_count);
|
|
96
|
+
machine->buffer_ring_count++;
|
|
97
|
+
return bg_id;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
inline VALUE um_get_string_from_buffer_ring(struct um *machine, int bgid, __s32 result, __u32 flags) {
|
|
56
101
|
if (!result) return Qnil;
|
|
57
102
|
|
|
58
103
|
unsigned buf_idx = flags >> IORING_CQE_BUFFER_SHIFT;
|
|
@@ -64,7 +109,7 @@ inline VALUE get_string_from_buffer_ring(struct um *machine, int bgid, int resul
|
|
|
64
109
|
|
|
65
110
|
// add buffer back to buffer ring
|
|
66
111
|
io_uring_buf_ring_add(
|
|
67
|
-
desc->br, src, desc->buf_size, buf_idx,
|
|
112
|
+
desc->br, src, desc->buf_size, buf_idx, desc->buf_mask, 0
|
|
68
113
|
);
|
|
69
114
|
io_uring_buf_ring_advance(desc->br, 1);
|
|
70
115
|
|
data/lib/uringmachine/version.rb
CHANGED
data/lib/uringmachine.rb
CHANGED
|
@@ -3,3 +3,15 @@
|
|
|
3
3
|
require_relative './um_ext'
|
|
4
4
|
|
|
5
5
|
UM = UringMachine
|
|
6
|
+
|
|
7
|
+
class UringMachine
|
|
8
|
+
def spin(value = nil, &block)
|
|
9
|
+
Fiber.new do |resume_value|
|
|
10
|
+
block.(resume_value)
|
|
11
|
+
rescue Exception => e
|
|
12
|
+
raise RuntimeError, "Unhandled fiber exception: #{e.inspect}"
|
|
13
|
+
ensure
|
|
14
|
+
self.yield
|
|
15
|
+
end.tap { |f| schedule(f, value) }
|
|
16
|
+
end
|
|
17
|
+
end
|