uringmachine 0.3 → 0.5
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/.github/workflows/test.yml +2 -1
- data/CHANGELOG.md +23 -0
- data/README.md +128 -0
- data/TODO.md +14 -0
- data/examples/bm_snooze.rb +89 -0
- data/examples/bm_write.rb +56 -0
- data/examples/dns_client.rb +12 -0
- data/examples/echo_server.rb +18 -40
- data/examples/http_server.rb +42 -43
- data/examples/inout.rb +19 -0
- data/examples/nc.rb +36 -0
- data/examples/server_client.rb +64 -0
- data/examples/snooze.rb +44 -0
- data/examples/write_dev_null.rb +16 -0
- data/ext/um/extconf.rb +24 -23
- data/ext/um/um.c +524 -278
- data/ext/um/um.h +146 -44
- data/ext/um/um_buffer.c +49 -0
- data/ext/um/um_class.c +217 -106
- data/ext/um/um_const.c +213 -0
- data/ext/um/um_ext.c +4 -0
- data/ext/um/um_mutex_class.c +47 -0
- data/ext/um/um_op.c +86 -114
- data/ext/um/um_queue_class.c +58 -0
- data/ext/um/um_sync.c +273 -0
- data/ext/um/um_utils.c +49 -4
- data/lib/uringmachine/dns_resolver.rb +84 -0
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +28 -0
- data/supressions/ruby.supp +71 -0
- data/test/helper.rb +8 -0
- data/test/test_um.rb +685 -46
- data/vendor/liburing/.github/workflows/build.yml +29 -1
- data/vendor/liburing/.gitignore +6 -0
- data/vendor/liburing/CHANGELOG +16 -0
- data/vendor/liburing/CONTRIBUTING.md +165 -0
- data/vendor/liburing/configure +64 -0
- data/vendor/liburing/examples/Makefile +9 -1
- data/vendor/liburing/examples/kdigest.c +405 -0
- data/vendor/liburing/examples/proxy.c +75 -8
- data/vendor/liburing/examples/reg-wait.c +159 -0
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/Makefile +16 -2
- data/vendor/liburing/src/include/liburing/io_uring.h +77 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
- data/vendor/liburing/src/include/liburing.h +59 -6
- data/vendor/liburing/src/int_flags.h +10 -3
- data/vendor/liburing/src/liburing-ffi.map +16 -0
- data/vendor/liburing/src/liburing.map +10 -0
- data/vendor/liburing/src/queue.c +28 -16
- data/vendor/liburing/src/register.c +106 -1
- data/vendor/liburing/src/sanitize.c +176 -0
- data/vendor/liburing/src/setup.c +47 -19
- data/vendor/liburing/src/setup.h +6 -0
- 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 +38 -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/cmd-discard.c +427 -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/fifo-nonblock-read.c +69 -0
- data/vendor/liburing/test/file-exit-unreg.c +48 -0
- 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 +4 -0
- data/vendor/liburing/test/io_uring_register.c +38 -8
- 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 +16 -3
- data/vendor/liburing/test/no-mmap-inval.c +3 -1
- 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 +158 -153
- data/vendor/liburing/test/read-mshot-stdin.c +121 -0
- data/vendor/liburing/test/read-mshot.c +282 -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 +94 -31
- data/vendor/liburing/test/reg-fd-only.c +15 -5
- data/vendor/liburing/test/reg-wait.c +251 -0
- data/vendor/liburing/test/regbuf-clone.c +645 -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/resize-rings.c +643 -0
- data/vendor/liburing/test/ringbuf-read.c +5 -0
- data/vendor/liburing/test/ringbuf-status.c +5 -1
- data/vendor/liburing/test/rsrc_tags.c +1 -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 +40 -33
- data/vendor/liburing/test/sqwait.c +136 -0
- 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 +56 -22
- data/vendor/liburing/test/thread-exit.c +5 -0
- data/vendor/liburing/test/timeout-new.c +1 -26
- data/vendor/liburing/test/timeout.c +25 -34
- 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 +37 -6
- data/examples/event_loop.rb +0 -69
- data/examples/fibers.rb +0 -105
- data/examples/http_server_multishot.rb +0 -57
- data/examples/http_server_simpler.rb +0 -34
data/ext/um/um_class.c
CHANGED
@@ -1,16 +1,23 @@
|
|
1
1
|
#include "um.h"
|
2
|
-
#include <
|
2
|
+
#include <arpa/inet.h>
|
3
3
|
|
4
4
|
VALUE cUM;
|
5
5
|
|
6
6
|
static void UM_mark(void *ptr) {
|
7
|
-
|
8
|
-
|
7
|
+
struct um *machine = ptr;
|
8
|
+
rb_gc_mark_movable(machine->self);
|
9
|
+
|
10
|
+
um_op_list_mark(machine, machine->transient_head);
|
11
|
+
um_op_list_mark(machine, machine->runqueue_head);
|
9
12
|
}
|
10
13
|
|
11
14
|
static void UM_compact(void *ptr) {
|
12
|
-
|
13
|
-
|
15
|
+
struct um *machine = ptr;
|
16
|
+
machine->self = rb_gc_location(machine->self);
|
17
|
+
machine->poll_fiber = rb_gc_location(machine->poll_fiber);
|
18
|
+
|
19
|
+
um_op_list_compact(machine, machine->transient_head);
|
20
|
+
um_op_list_compact(machine, machine->runqueue_head);
|
14
21
|
}
|
15
22
|
|
16
23
|
static void UM_free(void *ptr) {
|
@@ -43,63 +50,19 @@ inline struct um *get_machine(VALUE self) {
|
|
43
50
|
|
44
51
|
VALUE UM_initialize(VALUE self) {
|
45
52
|
struct um *machine = RTYPEDDATA_DATA(self);
|
46
|
-
um_setup(machine);
|
53
|
+
um_setup(self, machine);
|
47
54
|
return self;
|
48
55
|
}
|
49
56
|
|
50
57
|
VALUE UM_setup_buffer_ring(VALUE self, VALUE size, VALUE count) {
|
51
58
|
struct um *machine = get_machine(self);
|
52
|
-
|
53
|
-
|
54
|
-
rb_raise(rb_eRuntimeError, "Cannot setup more than BUFFER_RING_MAX_COUNT buffer rings");
|
55
|
-
|
56
|
-
struct buf_ring_descriptor *desc = machine->buffer_rings + machine->buffer_ring_count;
|
57
|
-
desc->buf_count = NUM2UINT(count);
|
58
|
-
desc->buf_size = NUM2UINT(size);
|
59
|
-
|
60
|
-
desc->br_size = sizeof(struct io_uring_buf) * desc->buf_count;
|
61
|
-
void *mapped = mmap(
|
62
|
-
NULL, desc->br_size, PROT_READ | PROT_WRITE,
|
63
|
-
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0
|
64
|
-
);
|
65
|
-
if (mapped == MAP_FAILED)
|
66
|
-
rb_raise(rb_eRuntimeError, "Failed to allocate buffer ring");
|
67
|
-
|
68
|
-
desc->br = (struct io_uring_buf_ring *)mapped;
|
69
|
-
io_uring_buf_ring_init(desc->br);
|
70
|
-
|
71
|
-
unsigned bg_id = machine->buffer_ring_count;
|
72
|
-
struct io_uring_buf_reg reg = {
|
73
|
-
.ring_addr = (unsigned long)desc->br,
|
74
|
-
.ring_entries = desc->buf_count,
|
75
|
-
.bgid = bg_id
|
76
|
-
};
|
77
|
-
int ret = io_uring_register_buf_ring(&machine->ring, ®, 0);
|
78
|
-
if (ret) {
|
79
|
-
munmap(desc->br, desc->br_size);
|
80
|
-
rb_syserr_fail(-ret, strerror(-ret));
|
81
|
-
}
|
82
|
-
|
83
|
-
desc->buf_base = malloc(desc->buf_count * desc->buf_size);
|
84
|
-
if (!desc->buf_base) {
|
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
|
-
int mask = io_uring_buf_ring_mask(desc->buf_count);
|
90
|
-
for (unsigned i = 0; i < desc->buf_count; i++) {
|
91
|
-
io_uring_buf_ring_add(
|
92
|
-
desc->br, desc->buf_base + i * desc->buf_size, desc->buf_size,
|
93
|
-
i, mask, i);
|
94
|
-
}
|
95
|
-
io_uring_buf_ring_advance(desc->br, desc->buf_count);
|
96
|
-
machine->buffer_ring_count++;
|
97
|
-
return UINT2NUM(bg_id);
|
59
|
+
int bgid = um_setup_buffer_ring(machine, NUM2UINT(size), NUM2UINT(count));
|
60
|
+
return INT2NUM(bgid);
|
98
61
|
}
|
99
62
|
|
100
63
|
VALUE UM_pending_count(VALUE self) {
|
101
64
|
struct um *machine = get_machine(self);
|
102
|
-
return
|
65
|
+
return INT2NUM(machine->pending_count);
|
103
66
|
}
|
104
67
|
|
105
68
|
VALUE UM_snooze(VALUE self) {
|
@@ -119,12 +82,6 @@ VALUE UM_schedule(VALUE self, VALUE fiber, VALUE value) {
|
|
119
82
|
return self;
|
120
83
|
}
|
121
84
|
|
122
|
-
VALUE UM_interrupt(VALUE self, VALUE fiber, VALUE value) {
|
123
|
-
struct um *machine = get_machine(self);
|
124
|
-
um_interrupt(machine, fiber, value);
|
125
|
-
return self;
|
126
|
-
}
|
127
|
-
|
128
85
|
VALUE UM_timeout(VALUE self, VALUE interval, VALUE class) {
|
129
86
|
struct um *machine = get_machine(self);
|
130
87
|
return um_timeout(machine, interval, class);
|
@@ -132,8 +89,7 @@ VALUE UM_timeout(VALUE self, VALUE interval, VALUE class) {
|
|
132
89
|
|
133
90
|
VALUE UM_sleep(VALUE self, VALUE duration) {
|
134
91
|
struct um *machine = get_machine(self);
|
135
|
-
um_sleep(machine, NUM2DBL(duration));
|
136
|
-
return duration;
|
92
|
+
return um_sleep(machine, NUM2DBL(duration));
|
137
93
|
}
|
138
94
|
|
139
95
|
VALUE UM_read(int argc, VALUE *argv, VALUE self) {
|
@@ -151,8 +107,12 @@ VALUE UM_read(int argc, VALUE *argv, VALUE self) {
|
|
151
107
|
}
|
152
108
|
|
153
109
|
VALUE UM_read_each(VALUE self, VALUE fd, VALUE bgid) {
|
110
|
+
#ifdef HAVE_IO_URING_PREP_READ_MULTISHOT
|
154
111
|
struct um *machine = get_machine(self);
|
155
112
|
return um_read_each(machine, NUM2INT(fd), NUM2INT(bgid));
|
113
|
+
#else
|
114
|
+
rb_raise(rb_eRuntimeError, "Not supported by kernel");
|
115
|
+
#endif
|
156
116
|
}
|
157
117
|
|
158
118
|
VALUE UM_write(int argc, VALUE *argv, VALUE self) {
|
@@ -166,6 +126,11 @@ VALUE UM_write(int argc, VALUE *argv, VALUE self) {
|
|
166
126
|
return um_write(machine, NUM2INT(fd), buffer, bytes);
|
167
127
|
}
|
168
128
|
|
129
|
+
VALUE UM_close(VALUE self, VALUE fd) {
|
130
|
+
struct um *machine = get_machine(self);
|
131
|
+
return um_close(machine, NUM2INT(fd));
|
132
|
+
}
|
133
|
+
|
169
134
|
VALUE UM_accept(VALUE self, VALUE fd) {
|
170
135
|
struct um *machine = get_machine(self);
|
171
136
|
return um_accept(machine, NUM2INT(fd));
|
@@ -176,6 +141,166 @@ VALUE UM_accept_each(VALUE self, VALUE fd) {
|
|
176
141
|
return um_accept_each(machine, NUM2INT(fd));
|
177
142
|
}
|
178
143
|
|
144
|
+
VALUE UM_socket(VALUE self, VALUE domain, VALUE type, VALUE protocol, VALUE flags) {
|
145
|
+
struct um *machine = get_machine(self);
|
146
|
+
return um_socket(machine, NUM2INT(domain), NUM2INT(type), NUM2INT(protocol), NUM2UINT(flags));
|
147
|
+
}
|
148
|
+
|
149
|
+
VALUE UM_connect(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
150
|
+
struct um *machine = get_machine(self);
|
151
|
+
|
152
|
+
struct sockaddr_in addr;
|
153
|
+
memset(&addr, 0, sizeof(addr));
|
154
|
+
addr.sin_family = AF_INET;
|
155
|
+
addr.sin_addr.s_addr = inet_addr(StringValueCStr(host));
|
156
|
+
addr.sin_port = htons(NUM2INT(port));
|
157
|
+
|
158
|
+
return um_connect(machine, NUM2INT(fd), (struct sockaddr *)&addr, sizeof(addr));
|
159
|
+
}
|
160
|
+
|
161
|
+
VALUE UM_send(VALUE self, VALUE fd, VALUE buffer, VALUE len, VALUE flags) {
|
162
|
+
struct um *machine = get_machine(self);
|
163
|
+
return um_send(machine, NUM2INT(fd), buffer, NUM2INT(len), NUM2INT(flags));
|
164
|
+
}
|
165
|
+
|
166
|
+
VALUE UM_recv(VALUE self, VALUE fd, VALUE buffer, VALUE maxlen, VALUE flags) {
|
167
|
+
struct um *machine = get_machine(self);
|
168
|
+
return um_recv(machine, NUM2INT(fd), buffer, NUM2INT(maxlen), NUM2INT(flags));
|
169
|
+
}
|
170
|
+
|
171
|
+
VALUE UM_recv_each(VALUE self, VALUE fd, VALUE bgid, VALUE flags) {
|
172
|
+
struct um *machine = get_machine(self);
|
173
|
+
return um_recv_each(machine, NUM2INT(fd), NUM2INT(bgid), NUM2INT(flags));
|
174
|
+
}
|
175
|
+
|
176
|
+
VALUE UM_bind(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
177
|
+
struct sockaddr_in addr;
|
178
|
+
memset(&addr, 0, sizeof(addr));
|
179
|
+
addr.sin_family = AF_INET;
|
180
|
+
addr.sin_addr.s_addr = inet_addr(StringValueCStr(host));
|
181
|
+
addr.sin_port = htons(NUM2INT(port));
|
182
|
+
|
183
|
+
#ifdef HAVE_IO_URING_PREP_BIND
|
184
|
+
struct um *machine = get_machine(self);
|
185
|
+
return um_bind(machine, NUM2INT(fd), (struct sockaddr *)&addr, sizeof(addr));
|
186
|
+
#else
|
187
|
+
int res = bind(NUM2INT(fd), (struct sockaddr *)&addr, sizeof(addr));
|
188
|
+
if (res)
|
189
|
+
rb_syserr_fail(errno, strerror(errno));
|
190
|
+
return INT2NUM(0);
|
191
|
+
#endif
|
192
|
+
}
|
193
|
+
|
194
|
+
VALUE UM_listen(VALUE self, VALUE fd, VALUE backlog) {
|
195
|
+
#ifdef HAVE_IO_URING_PREP_LISTEN
|
196
|
+
struct um *machine = get_machine(self);
|
197
|
+
return um_listen(machine, NUM2INT(fd), NUM2INT(backlog));
|
198
|
+
#else
|
199
|
+
int res = listen(NUM2INT(fd), NUM2INT(backlog));
|
200
|
+
if (res)
|
201
|
+
rb_syserr_fail(errno, strerror(errno));
|
202
|
+
return INT2NUM(0);
|
203
|
+
#endif
|
204
|
+
}
|
205
|
+
|
206
|
+
static inline int numeric_value(VALUE value) {
|
207
|
+
switch (TYPE(value)) {
|
208
|
+
case T_TRUE:
|
209
|
+
return 1;
|
210
|
+
case T_FALSE:
|
211
|
+
return 0;
|
212
|
+
default:
|
213
|
+
return NUM2INT(value);
|
214
|
+
}
|
215
|
+
}
|
216
|
+
|
217
|
+
VALUE UM_getsockopt(VALUE self, VALUE fd, VALUE level, VALUE opt) {
|
218
|
+
struct um *machine = get_machine(self);
|
219
|
+
return um_getsockopt(machine, NUM2INT(fd), NUM2INT(level), NUM2INT(opt));
|
220
|
+
}
|
221
|
+
|
222
|
+
VALUE UM_setsockopt(VALUE self, VALUE fd, VALUE level, VALUE opt, VALUE value) {
|
223
|
+
struct um *machine = get_machine(self);
|
224
|
+
return um_setsockopt(machine, NUM2INT(fd), NUM2INT(level), NUM2INT(opt), numeric_value(value));
|
225
|
+
}
|
226
|
+
|
227
|
+
#ifdef HAVE_IO_URING_PREP_FUTEX
|
228
|
+
|
229
|
+
VALUE UM_mutex_synchronize(VALUE self, VALUE mutex) {
|
230
|
+
struct um *machine = get_machine(self);
|
231
|
+
struct um_mutex *mutex_data = Mutex_data(mutex);
|
232
|
+
return um_mutex_synchronize(machine, &mutex_data->state);
|
233
|
+
}
|
234
|
+
|
235
|
+
VALUE UM_queue_push(VALUE self, VALUE queue, VALUE value) {
|
236
|
+
struct um *machine = get_machine(self);
|
237
|
+
struct um_queue *que = Queue_data(queue);
|
238
|
+
return um_queue_push(machine, que, value);
|
239
|
+
}
|
240
|
+
|
241
|
+
VALUE UM_queue_pop(VALUE self, VALUE queue) {
|
242
|
+
struct um *machine = get_machine(self);
|
243
|
+
struct um_queue *que = Queue_data(queue);
|
244
|
+
return um_queue_pop(machine, que);
|
245
|
+
}
|
246
|
+
|
247
|
+
VALUE UM_queue_unshift(VALUE self, VALUE queue, VALUE value) {
|
248
|
+
struct um *machine = get_machine(self);
|
249
|
+
struct um_queue *que = Queue_data(queue);
|
250
|
+
return um_queue_unshift(machine, que, value);
|
251
|
+
}
|
252
|
+
|
253
|
+
VALUE UM_queue_shift(VALUE self, VALUE queue) {
|
254
|
+
struct um *machine = get_machine(self);
|
255
|
+
struct um_queue *que = Queue_data(queue);
|
256
|
+
return um_queue_shift(machine, que);
|
257
|
+
}
|
258
|
+
|
259
|
+
#endif
|
260
|
+
|
261
|
+
struct um_open_ctx {
|
262
|
+
VALUE self;
|
263
|
+
VALUE fd;
|
264
|
+
};
|
265
|
+
|
266
|
+
VALUE UM_open_ensure(VALUE arg) {
|
267
|
+
struct um_open_ctx *ctx = (struct um_open_ctx *)arg;
|
268
|
+
UM_close(ctx->self, ctx->fd);
|
269
|
+
return ctx->self;
|
270
|
+
}
|
271
|
+
|
272
|
+
VALUE UM_open(VALUE self, VALUE pathname, VALUE flags) {
|
273
|
+
struct um *machine = get_machine(self);
|
274
|
+
// TODO: take optional perm (mode) arg
|
275
|
+
VALUE fd = um_open(machine, pathname, NUM2INT(flags), 0666);
|
276
|
+
if (rb_block_given_p()) {
|
277
|
+
struct um_open_ctx ctx = { self, fd };
|
278
|
+
return rb_ensure(rb_yield, fd, UM_open_ensure, (VALUE)&ctx);
|
279
|
+
}
|
280
|
+
else
|
281
|
+
return fd;
|
282
|
+
}
|
283
|
+
|
284
|
+
VALUE UM_waitpid(VALUE self, VALUE pid, VALUE options) {
|
285
|
+
struct um *machine = get_machine(self);
|
286
|
+
return um_waitpid(machine, NUM2INT(pid), NUM2INT(options));
|
287
|
+
}
|
288
|
+
|
289
|
+
VALUE UM_pipe(VALUE self) {
|
290
|
+
int fds[2];
|
291
|
+
int ret = pipe(fds);
|
292
|
+
if (ret) {
|
293
|
+
int e = errno;
|
294
|
+
rb_syserr_fail(e, strerror(e));
|
295
|
+
}
|
296
|
+
|
297
|
+
return rb_ary_new_from_args(2, INT2NUM(fds[0]), INT2NUM(fds[1]));
|
298
|
+
}
|
299
|
+
|
300
|
+
VALUE UM_kernel_version(VALUE self) {
|
301
|
+
return INT2NUM(UM_KERNEL_VERSION);
|
302
|
+
}
|
303
|
+
|
179
304
|
void Init_UM(void) {
|
180
305
|
rb_ext_ractor_safe(true);
|
181
306
|
|
@@ -183,60 +308,46 @@ void Init_UM(void) {
|
|
183
308
|
rb_define_alloc_func(cUM, UM_allocate);
|
184
309
|
|
185
310
|
rb_define_method(cUM, "initialize", UM_initialize, 0);
|
186
|
-
rb_define_method(cUM, "setup_buffer_ring", UM_setup_buffer_ring, 2);
|
187
311
|
rb_define_method(cUM, "pending_count", UM_pending_count, 0);
|
312
|
+
rb_define_method(cUM, "setup_buffer_ring", UM_setup_buffer_ring, 2);
|
313
|
+
|
314
|
+
rb_define_singleton_method(cUM, "pipe", UM_pipe, 0);
|
315
|
+
rb_define_singleton_method(cUM, "kernel_version", UM_kernel_version, 0);
|
316
|
+
|
188
317
|
|
189
|
-
rb_define_method(cUM, "snooze", UM_snooze, 0);
|
190
|
-
rb_define_method(cUM, "yield", UM_yield, 0);
|
191
318
|
rb_define_method(cUM, "schedule", UM_schedule, 2);
|
192
|
-
rb_define_method(cUM, "
|
319
|
+
rb_define_method(cUM, "snooze", UM_snooze, 0);
|
193
320
|
rb_define_method(cUM, "timeout", UM_timeout, 2);
|
321
|
+
rb_define_method(cUM, "yield", UM_yield, 0);
|
194
322
|
|
195
|
-
rb_define_method(cUM, "
|
323
|
+
rb_define_method(cUM, "close", UM_close, 1);
|
324
|
+
rb_define_method(cUM, "open", UM_open, 2);
|
196
325
|
rb_define_method(cUM, "read", UM_read, -1);
|
197
326
|
rb_define_method(cUM, "read_each", UM_read_each, 2);
|
327
|
+
rb_define_method(cUM, "sleep", UM_sleep, 1);
|
198
328
|
rb_define_method(cUM, "write", UM_write, -1);
|
199
329
|
|
330
|
+
rb_define_method(cUM, "waitpid", UM_waitpid, 2);
|
331
|
+
|
200
332
|
rb_define_method(cUM, "accept", UM_accept, 1);
|
201
333
|
rb_define_method(cUM, "accept_each", UM_accept_each, 1);
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
// SYM_buffer_group = MAKE_SYM("buffer_group");
|
222
|
-
// SYM_buffer_offset = MAKE_SYM("buffer_offset");
|
223
|
-
// SYM_close = MAKE_SYM("close");
|
224
|
-
// SYM_count = MAKE_SYM("count");
|
225
|
-
// SYM_emit = MAKE_SYM("emit");
|
226
|
-
// SYM_fd = MAKE_SYM("fd");
|
227
|
-
// SYM_id = MAKE_SYM("id");
|
228
|
-
// SYM_interval = MAKE_SYM("interval");
|
229
|
-
// SYM_len = MAKE_SYM("len");
|
230
|
-
// SYM_link = MAKE_SYM("link");
|
231
|
-
// SYM_multishot = MAKE_SYM("multishot");
|
232
|
-
// SYM_op = MAKE_SYM("op");
|
233
|
-
// SYM_read = MAKE_SYM("read");
|
234
|
-
// SYM_result = MAKE_SYM("result");
|
235
|
-
// SYM_signal = MAKE_SYM("signal");
|
236
|
-
// SYM_size = MAKE_SYM("size");
|
237
|
-
// SYM_spec_data = MAKE_SYM("spec_data");
|
238
|
-
// SYM_stop = MAKE_SYM("stop");
|
239
|
-
// SYM_timeout = MAKE_SYM("timeout");
|
240
|
-
// SYM_utf8 = MAKE_SYM("utf8");
|
241
|
-
// SYM_write = MAKE_SYM("write");
|
334
|
+
rb_define_method(cUM, "bind", UM_bind, 3);
|
335
|
+
rb_define_method(cUM, "connect", UM_connect, 3);
|
336
|
+
rb_define_method(cUM, "getsockopt", UM_getsockopt, 3);
|
337
|
+
rb_define_method(cUM, "listen", UM_listen, 2);
|
338
|
+
rb_define_method(cUM, "recv", UM_recv, 4);
|
339
|
+
rb_define_method(cUM, "recv_each", UM_recv_each, 3);
|
340
|
+
rb_define_method(cUM, "send", UM_send, 4);
|
341
|
+
rb_define_method(cUM, "setsockopt", UM_setsockopt, 4);
|
342
|
+
rb_define_method(cUM, "socket", UM_socket, 4);
|
343
|
+
|
344
|
+
#ifdef HAVE_IO_URING_PREP_FUTEX
|
345
|
+
rb_define_method(cUM, "pop", UM_queue_pop, 1);
|
346
|
+
rb_define_method(cUM, "push", UM_queue_push, 2);
|
347
|
+
rb_define_method(cUM, "shift", UM_queue_shift, 1);
|
348
|
+
rb_define_method(cUM, "synchronize", UM_mutex_synchronize, 1);
|
349
|
+
rb_define_method(cUM, "unshift", UM_queue_unshift, 2);
|
350
|
+
#endif
|
351
|
+
|
352
|
+
um_define_net_constants(cUM);
|
242
353
|
}
|
data/ext/um/um_const.c
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
|
3
|
+
#include <fcntl.h>
|
4
|
+
#include <sys/wait.h>
|
5
|
+
|
6
|
+
#include <arpa/inet.h>
|
7
|
+
#include <sys/types.h>
|
8
|
+
#include <sys/socket.h>
|
9
|
+
#include <netinet/in.h>
|
10
|
+
#include <netinet/tcp.h>
|
11
|
+
#include <netinet/udp.h>
|
12
|
+
#include <netdb.h>
|
13
|
+
#include <net/if.h>
|
14
|
+
|
15
|
+
|
16
|
+
#define DEF_CONST_INT(mod, v) rb_define_const(mod, #v, INT2NUM(v))
|
17
|
+
|
18
|
+
void um_define_net_constants(VALUE mod) {
|
19
|
+
DEF_CONST_INT(mod, O_APPEND);
|
20
|
+
DEF_CONST_INT(mod, O_CLOEXEC);
|
21
|
+
DEF_CONST_INT(mod, O_CREAT);
|
22
|
+
DEF_CONST_INT(mod, O_DIRECT);
|
23
|
+
DEF_CONST_INT(mod, O_DIRECTORY);
|
24
|
+
DEF_CONST_INT(mod, O_DSYNC);
|
25
|
+
DEF_CONST_INT(mod, O_EXCL);
|
26
|
+
DEF_CONST_INT(mod, O_NOCTTY);
|
27
|
+
DEF_CONST_INT(mod, O_NOFOLLOW);
|
28
|
+
DEF_CONST_INT(mod, O_PATH);
|
29
|
+
DEF_CONST_INT(mod, O_RDONLY);
|
30
|
+
DEF_CONST_INT(mod, O_RDWR);
|
31
|
+
DEF_CONST_INT(mod, O_SYNC);
|
32
|
+
DEF_CONST_INT(mod, O_TMPFILE);
|
33
|
+
DEF_CONST_INT(mod, O_TRUNC);
|
34
|
+
DEF_CONST_INT(mod, O_WRONLY);
|
35
|
+
|
36
|
+
DEF_CONST_INT(mod, WNOHANG);
|
37
|
+
DEF_CONST_INT(mod, WUNTRACED);
|
38
|
+
DEF_CONST_INT(mod, WCONTINUED);
|
39
|
+
DEF_CONST_INT(mod, WEXITED);
|
40
|
+
DEF_CONST_INT(mod, WSTOPPED);
|
41
|
+
DEF_CONST_INT(mod, WCONTINUED);
|
42
|
+
DEF_CONST_INT(mod, WNOWAIT);
|
43
|
+
|
44
|
+
DEF_CONST_INT(mod, SOCK_STREAM);
|
45
|
+
DEF_CONST_INT(mod, SOCK_DGRAM);
|
46
|
+
DEF_CONST_INT(mod, SOCK_RAW);
|
47
|
+
DEF_CONST_INT(mod, SOCK_RDM);
|
48
|
+
DEF_CONST_INT(mod, SOCK_SEQPACKET);
|
49
|
+
DEF_CONST_INT(mod, SOCK_PACKET);
|
50
|
+
DEF_CONST_INT(mod, SOCK_CLOEXEC);
|
51
|
+
|
52
|
+
DEF_CONST_INT(mod, AF_UNSPEC);
|
53
|
+
DEF_CONST_INT(mod, PF_UNSPEC);
|
54
|
+
DEF_CONST_INT(mod, AF_INET);
|
55
|
+
DEF_CONST_INT(mod, PF_INET);
|
56
|
+
DEF_CONST_INT(mod, AF_INET6);
|
57
|
+
DEF_CONST_INT(mod, PF_INET6);
|
58
|
+
DEF_CONST_INT(mod, AF_UNIX);
|
59
|
+
DEF_CONST_INT(mod, PF_UNIX);
|
60
|
+
DEF_CONST_INT(mod, AF_LOCAL);
|
61
|
+
DEF_CONST_INT(mod, PF_LOCAL);
|
62
|
+
DEF_CONST_INT(mod, AF_ROUTE);
|
63
|
+
DEF_CONST_INT(mod, PF_ROUTE);
|
64
|
+
DEF_CONST_INT(mod, AF_MAX);
|
65
|
+
DEF_CONST_INT(mod, PF_MAX);
|
66
|
+
|
67
|
+
DEF_CONST_INT(mod, MSG_OOB);
|
68
|
+
DEF_CONST_INT(mod, MSG_PEEK);
|
69
|
+
DEF_CONST_INT(mod, MSG_DONTROUTE);
|
70
|
+
DEF_CONST_INT(mod, MSG_WAITALL);
|
71
|
+
DEF_CONST_INT(mod, MSG_DONTWAIT);
|
72
|
+
DEF_CONST_INT(mod, MSG_MORE);
|
73
|
+
|
74
|
+
DEF_CONST_INT(mod, SOL_SOCKET);
|
75
|
+
DEF_CONST_INT(mod, SOL_IP);
|
76
|
+
|
77
|
+
DEF_CONST_INT(mod, IPPROTO_IP);
|
78
|
+
DEF_CONST_INT(mod, IPPROTO_ICMP);
|
79
|
+
DEF_CONST_INT(mod, IPPROTO_IGMP);
|
80
|
+
DEF_CONST_INT(mod, IPPROTO_TCP);
|
81
|
+
DEF_CONST_INT(mod, IPPROTO_EGP);
|
82
|
+
DEF_CONST_INT(mod, IPPROTO_PUP);
|
83
|
+
DEF_CONST_INT(mod, IPPROTO_UDP);
|
84
|
+
DEF_CONST_INT(mod, IPPROTO_IDP);
|
85
|
+
DEF_CONST_INT(mod, IPPROTO_IPV6);
|
86
|
+
DEF_CONST_INT(mod, IPPROTO_NONE);
|
87
|
+
DEF_CONST_INT(mod, IPPROTO_ROUTING);
|
88
|
+
DEF_CONST_INT(mod, IPPROTO_RAW);
|
89
|
+
DEF_CONST_INT(mod, IPPROTO_MAX);
|
90
|
+
|
91
|
+
DEF_CONST_INT(mod, INADDR_ANY);
|
92
|
+
DEF_CONST_INT(mod, INADDR_BROADCAST);
|
93
|
+
DEF_CONST_INT(mod, INADDR_LOOPBACK);
|
94
|
+
DEF_CONST_INT(mod, INADDR_NONE);
|
95
|
+
|
96
|
+
DEF_CONST_INT(mod, IP_OPTIONS);
|
97
|
+
DEF_CONST_INT(mod, IP_HDRINCL);
|
98
|
+
DEF_CONST_INT(mod, IP_TOS);
|
99
|
+
DEF_CONST_INT(mod, IP_TTL);
|
100
|
+
DEF_CONST_INT(mod, IP_RECVOPTS);
|
101
|
+
DEF_CONST_INT(mod, IP_MINTTL);
|
102
|
+
DEF_CONST_INT(mod, IP_RECVTTL);
|
103
|
+
|
104
|
+
DEF_CONST_INT(mod, SO_DEBUG);
|
105
|
+
DEF_CONST_INT(mod, SO_REUSEADDR);
|
106
|
+
DEF_CONST_INT(mod, SO_REUSEPORT);
|
107
|
+
DEF_CONST_INT(mod, SO_TYPE);
|
108
|
+
DEF_CONST_INT(mod, SO_ERROR);
|
109
|
+
DEF_CONST_INT(mod, SO_DONTROUTE);
|
110
|
+
DEF_CONST_INT(mod, SO_BROADCAST);
|
111
|
+
DEF_CONST_INT(mod, SO_SNDBUF);
|
112
|
+
DEF_CONST_INT(mod, SO_RCVBUF);
|
113
|
+
DEF_CONST_INT(mod, SO_SNDBUFFORCE);
|
114
|
+
DEF_CONST_INT(mod, SO_RCVBUFFORCE);
|
115
|
+
DEF_CONST_INT(mod, SO_KEEPALIVE);
|
116
|
+
DEF_CONST_INT(mod, SO_OOBINLINE);
|
117
|
+
DEF_CONST_INT(mod, SO_PRIORITY);
|
118
|
+
DEF_CONST_INT(mod, SO_LINGER);
|
119
|
+
DEF_CONST_INT(mod, SO_PASSCRED);
|
120
|
+
DEF_CONST_INT(mod, SO_PEERCRED);
|
121
|
+
DEF_CONST_INT(mod, SO_RCVLOWAT);
|
122
|
+
DEF_CONST_INT(mod, SO_SNDLOWAT);
|
123
|
+
DEF_CONST_INT(mod, SO_RCVTIMEO);
|
124
|
+
DEF_CONST_INT(mod, SO_SNDTIMEO);
|
125
|
+
DEF_CONST_INT(mod, SO_ACCEPTCONN);
|
126
|
+
DEF_CONST_INT(mod, SO_PEERNAME);
|
127
|
+
DEF_CONST_INT(mod, SO_TIMESTAMP);
|
128
|
+
DEF_CONST_INT(mod, SO_MARK);
|
129
|
+
DEF_CONST_INT(mod, SO_PROTOCOL);
|
130
|
+
DEF_CONST_INT(mod, SO_DOMAIN);
|
131
|
+
DEF_CONST_INT(mod, SO_PEEK_OFF);
|
132
|
+
DEF_CONST_INT(mod, SO_BUSY_POLL);
|
133
|
+
|
134
|
+
DEF_CONST_INT(mod, TCP_NODELAY);
|
135
|
+
DEF_CONST_INT(mod, TCP_MAXSEG);
|
136
|
+
DEF_CONST_INT(mod, TCP_CORK);
|
137
|
+
DEF_CONST_INT(mod, TCP_DEFER_ACCEPT);
|
138
|
+
DEF_CONST_INT(mod, TCP_INFO);
|
139
|
+
DEF_CONST_INT(mod, TCP_KEEPCNT);
|
140
|
+
DEF_CONST_INT(mod, TCP_KEEPIDLE);
|
141
|
+
DEF_CONST_INT(mod, TCP_KEEPINTVL);
|
142
|
+
DEF_CONST_INT(mod, TCP_LINGER2);
|
143
|
+
DEF_CONST_INT(mod, TCP_MD5SIG);
|
144
|
+
DEF_CONST_INT(mod, TCP_QUICKACK);
|
145
|
+
DEF_CONST_INT(mod, TCP_SYNCNT);
|
146
|
+
DEF_CONST_INT(mod, TCP_WINDOW_CLAMP);
|
147
|
+
DEF_CONST_INT(mod, TCP_FASTOPEN);
|
148
|
+
DEF_CONST_INT(mod, TCP_CONGESTION);
|
149
|
+
DEF_CONST_INT(mod, TCP_COOKIE_TRANSACTIONS);
|
150
|
+
DEF_CONST_INT(mod, TCP_QUEUE_SEQ);
|
151
|
+
DEF_CONST_INT(mod, TCP_REPAIR);
|
152
|
+
DEF_CONST_INT(mod, TCP_REPAIR_OPTIONS);
|
153
|
+
DEF_CONST_INT(mod, TCP_REPAIR_QUEUE);
|
154
|
+
DEF_CONST_INT(mod, TCP_THIN_LINEAR_TIMEOUTS);
|
155
|
+
DEF_CONST_INT(mod, TCP_TIMESTAMP);
|
156
|
+
DEF_CONST_INT(mod, TCP_USER_TIMEOUT);
|
157
|
+
|
158
|
+
DEF_CONST_INT(mod, UDP_CORK);
|
159
|
+
|
160
|
+
DEF_CONST_INT(mod, AI_PASSIVE);
|
161
|
+
DEF_CONST_INT(mod, AI_CANONNAME);
|
162
|
+
DEF_CONST_INT(mod, AI_NUMERICHOST);
|
163
|
+
DEF_CONST_INT(mod, AI_NUMERICSERV);
|
164
|
+
DEF_CONST_INT(mod, AI_ALL);
|
165
|
+
DEF_CONST_INT(mod, AI_ADDRCONFIG);
|
166
|
+
DEF_CONST_INT(mod, AI_V4MAPPED);
|
167
|
+
|
168
|
+
DEF_CONST_INT(mod, NI_MAXHOST);
|
169
|
+
DEF_CONST_INT(mod, NI_MAXSERV);
|
170
|
+
DEF_CONST_INT(mod, NI_NOFQDN);
|
171
|
+
DEF_CONST_INT(mod, NI_NUMERICHOST);
|
172
|
+
DEF_CONST_INT(mod, NI_NAMEREQD);
|
173
|
+
DEF_CONST_INT(mod, NI_NUMERICSERV);
|
174
|
+
DEF_CONST_INT(mod, NI_DGRAM);
|
175
|
+
|
176
|
+
DEF_CONST_INT(mod, SHUT_RD);
|
177
|
+
DEF_CONST_INT(mod, SHUT_WR);
|
178
|
+
DEF_CONST_INT(mod, SHUT_RDWR);
|
179
|
+
|
180
|
+
DEF_CONST_INT(mod, IPV6_JOIN_GROUP);
|
181
|
+
DEF_CONST_INT(mod, IPV6_LEAVE_GROUP);
|
182
|
+
DEF_CONST_INT(mod, IPV6_MULTICAST_HOPS);
|
183
|
+
DEF_CONST_INT(mod, IPV6_MULTICAST_IF);
|
184
|
+
DEF_CONST_INT(mod, IPV6_MULTICAST_LOOP);
|
185
|
+
DEF_CONST_INT(mod, IPV6_UNICAST_HOPS);
|
186
|
+
DEF_CONST_INT(mod, IPV6_V6ONLY);
|
187
|
+
DEF_CONST_INT(mod, IPV6_CHECKSUM);
|
188
|
+
DEF_CONST_INT(mod, IPV6_DONTFRAG);
|
189
|
+
DEF_CONST_INT(mod, IPV6_DSTOPTS);
|
190
|
+
DEF_CONST_INT(mod, IPV6_HOPLIMIT);
|
191
|
+
DEF_CONST_INT(mod, IPV6_HOPOPTS);
|
192
|
+
DEF_CONST_INT(mod, IPV6_NEXTHOP);
|
193
|
+
DEF_CONST_INT(mod, IPV6_PATHMTU);
|
194
|
+
DEF_CONST_INT(mod, IPV6_PKTINFO);
|
195
|
+
DEF_CONST_INT(mod, IPV6_RECVDSTOPTS);
|
196
|
+
DEF_CONST_INT(mod, IPV6_RECVHOPLIMIT);
|
197
|
+
DEF_CONST_INT(mod, IPV6_RECVHOPOPTS);
|
198
|
+
DEF_CONST_INT(mod, IPV6_RECVPKTINFO);
|
199
|
+
DEF_CONST_INT(mod, IPV6_RECVRTHDR);
|
200
|
+
DEF_CONST_INT(mod, IPV6_RECVTCLASS);
|
201
|
+
DEF_CONST_INT(mod, IPV6_RTHDR);
|
202
|
+
DEF_CONST_INT(mod, IPV6_RTHDRDSTOPTS);
|
203
|
+
DEF_CONST_INT(mod, IPV6_RTHDR_TYPE_0);
|
204
|
+
DEF_CONST_INT(mod, IPV6_RECVPATHMTU);
|
205
|
+
DEF_CONST_INT(mod, IPV6_TCLASS);
|
206
|
+
|
207
|
+
DEF_CONST_INT(mod, INET_ADDRSTRLEN);
|
208
|
+
DEF_CONST_INT(mod, INET6_ADDRSTRLEN);
|
209
|
+
|
210
|
+
DEF_CONST_INT(mod, IF_NAMESIZE);
|
211
|
+
|
212
|
+
DEF_CONST_INT(mod, SOMAXCONN);
|
213
|
+
}
|
data/ext/um/um_ext.c
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
#include "um.h"
|
2
|
+
#include <stdlib.h>
|
3
|
+
|
4
|
+
VALUE cMutex;
|
5
|
+
|
6
|
+
static void Mutex_mark(void *ptr) {
|
7
|
+
struct um_mutex *mutex = ptr;
|
8
|
+
rb_gc_mark_movable(mutex->self);
|
9
|
+
}
|
10
|
+
|
11
|
+
static void Mutex_compact(void *ptr) {
|
12
|
+
struct um_mutex *mutex = ptr;
|
13
|
+
mutex->self = rb_gc_location(mutex->self);
|
14
|
+
}
|
15
|
+
|
16
|
+
static size_t Mutex_size(const void *ptr) {
|
17
|
+
return sizeof(struct um_mutex);
|
18
|
+
}
|
19
|
+
|
20
|
+
static const rb_data_type_t Mutex_type = {
|
21
|
+
"UringMachineMutex",
|
22
|
+
{Mutex_mark, free, Mutex_size, Mutex_compact},
|
23
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
24
|
+
};
|
25
|
+
|
26
|
+
static VALUE Mutex_allocate(VALUE klass) {
|
27
|
+
struct um_mutex *mutex = malloc(sizeof(struct um_mutex));
|
28
|
+
return TypedData_Wrap_Struct(klass, &Mutex_type, mutex);
|
29
|
+
}
|
30
|
+
|
31
|
+
inline struct um_mutex *Mutex_data(VALUE self) {
|
32
|
+
return RTYPEDDATA_DATA(self);
|
33
|
+
}
|
34
|
+
|
35
|
+
VALUE Mutex_initialize(VALUE self) {
|
36
|
+
struct um_mutex *mutex = Mutex_data(self);
|
37
|
+
mutex->self = self;
|
38
|
+
um_mutex_init(mutex);
|
39
|
+
return self;
|
40
|
+
}
|
41
|
+
|
42
|
+
void Init_Mutex(void) {
|
43
|
+
cMutex = rb_define_class_under(cUM, "Mutex", rb_cObject);
|
44
|
+
rb_define_alloc_func(cMutex, Mutex_allocate);
|
45
|
+
|
46
|
+
rb_define_method(cMutex, "initialize", Mutex_initialize, 0);
|
47
|
+
}
|