uringmachine 0.1 → 0.3
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 +12 -0
- data/Rakefile +1 -1
- data/ext/um/um.c +228 -38
- data/ext/um/um.h +36 -8
- data/ext/um/um_class.c +98 -31
- data/ext/um/um_ext.c +0 -6
- data/ext/um/um_op.c +70 -6
- data/ext/um/um_utils.c +51 -1
- data/lib/uringmachine/version.rb +3 -1
- data/lib/uringmachine.rb +0 -3
- data/test/helper.rb +5 -12
- data/test/test_um.rb +259 -13
- data/uringmachine.gemspec +1 -1
- metadata +2 -6
- data/ext/um/iou.h +0 -101
- data/ext/um/op_ctx.c +0 -138
- data/ext/um/ring.c +0 -755
- data/test/test_iou.rb +0 -876
data/ext/um/um_op.c
CHANGED
@@ -1,5 +1,58 @@
|
|
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
|
+
|
19
|
+
inline void um_op_result_cleanup(struct um *machine, struct um_op *op) {
|
20
|
+
struct um_result_entry *entry = op->results_head;
|
21
|
+
while (entry) {
|
22
|
+
struct um_result_entry *next = entry->next;
|
23
|
+
um_result_checkin(machine, entry);
|
24
|
+
entry = next;
|
25
|
+
}
|
26
|
+
op->results_head = op->results_tail = NULL;
|
27
|
+
}
|
28
|
+
|
29
|
+
inline void um_op_result_push(struct um *machine, struct um_op *op, int result, int flags) {
|
30
|
+
struct um_result_entry *entry = um_result_checkout(machine);
|
31
|
+
entry->next = 0;
|
32
|
+
entry->result = result;
|
33
|
+
entry->flags = flags;
|
34
|
+
if (op->results_tail) {
|
35
|
+
op->results_tail->next = entry;
|
36
|
+
op->results_tail = entry;
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
op->results_head = op->results_tail = entry;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
inline int um_op_result_shift(struct um *machine, struct um_op *op, int *result, int *flags) {
|
44
|
+
if (!op->results_head) return 0;
|
45
|
+
|
46
|
+
struct um_result_entry *entry = op->results_head;
|
47
|
+
*result = entry->result;
|
48
|
+
*flags = entry->flags;
|
49
|
+
op->results_head = entry->next;
|
50
|
+
if (!op->results_head)
|
51
|
+
op->results_tail = NULL;
|
52
|
+
um_result_checkin(machine, entry);
|
53
|
+
return 1;
|
54
|
+
}
|
55
|
+
|
3
56
|
inline void um_op_clear(struct um_op *op) {
|
4
57
|
memset(op, 0, sizeof(struct um_op));
|
5
58
|
op->fiber = op->resume_value = Qnil;
|
@@ -8,9 +61,9 @@ inline void um_op_clear(struct um_op *op) {
|
|
8
61
|
inline struct um_op *um_op_checkout(struct um *machine) {
|
9
62
|
machine->pending_count++;
|
10
63
|
|
11
|
-
if (machine->
|
12
|
-
struct um_op *op = machine->
|
13
|
-
machine->
|
64
|
+
if (machine->op_freelist) {
|
65
|
+
struct um_op *op = machine->op_freelist;
|
66
|
+
machine->op_freelist = op->next;
|
14
67
|
um_op_clear(op);
|
15
68
|
return op;
|
16
69
|
}
|
@@ -21,10 +74,12 @@ inline struct um_op *um_op_checkout(struct um *machine) {
|
|
21
74
|
}
|
22
75
|
|
23
76
|
inline void um_op_checkin(struct um *machine, struct um_op *op) {
|
77
|
+
um_op_result_cleanup(machine, op);
|
78
|
+
|
24
79
|
machine->pending_count--;
|
25
80
|
|
26
|
-
op->next = machine->
|
27
|
-
machine->
|
81
|
+
op->next = machine->op_freelist;
|
82
|
+
machine->op_freelist = op;
|
28
83
|
}
|
29
84
|
|
30
85
|
inline struct um_op *um_runqueue_find_by_fiber(struct um *machine, VALUE fiber) {
|
@@ -78,10 +133,19 @@ inline struct um_op *um_runqueue_shift(struct um *machine) {
|
|
78
133
|
return op;
|
79
134
|
}
|
80
135
|
|
81
|
-
inline void
|
136
|
+
inline void um_free_op_linked_list(struct um *machine, struct um_op *op) {
|
82
137
|
while (op) {
|
83
138
|
struct um_op *next = op->next;
|
139
|
+
um_op_result_cleanup(machine, op);
|
84
140
|
free(op);
|
85
141
|
op = next;
|
86
142
|
}
|
87
143
|
}
|
144
|
+
|
145
|
+
inline void um_free_result_linked_list(struct um *machine, struct um_result_entry *entry) {
|
146
|
+
while (entry) {
|
147
|
+
struct um_result_entry *next = entry->next;
|
148
|
+
free(entry);
|
149
|
+
entry = next;
|
150
|
+
}
|
151
|
+
}
|
data/ext/um/um_utils.c
CHANGED
@@ -15,9 +15,59 @@ inline int um_value_is_exception_p(VALUE v) {
|
|
15
15
|
return rb_obj_is_kind_of(v, rb_eException) == Qtrue;
|
16
16
|
}
|
17
17
|
|
18
|
-
VALUE um_raise_exception(VALUE e) {
|
18
|
+
inline VALUE um_raise_exception(VALUE e) {
|
19
19
|
static ID ID_raise = 0;
|
20
20
|
if (!ID_raise) ID_raise = rb_intern("raise");
|
21
21
|
|
22
22
|
return rb_funcall(rb_mKernel, ID_raise, 1, e);
|
23
23
|
}
|
24
|
+
|
25
|
+
inline void um_raise_on_system_error(int result) {
|
26
|
+
if (unlikely(result < 0)) rb_syserr_fail(-result, strerror(-result));
|
27
|
+
}
|
28
|
+
|
29
|
+
inline void * um_prepare_read_buffer(VALUE buffer, unsigned len, int ofs) {
|
30
|
+
unsigned current_len = RSTRING_LEN(buffer);
|
31
|
+
if (ofs < 0) ofs = current_len + ofs + 1;
|
32
|
+
unsigned new_len = len + (unsigned)ofs;
|
33
|
+
|
34
|
+
if (current_len < new_len)
|
35
|
+
rb_str_modify_expand(buffer, new_len);
|
36
|
+
else
|
37
|
+
rb_str_modify(buffer);
|
38
|
+
return RSTRING_PTR(buffer) + ofs;
|
39
|
+
}
|
40
|
+
|
41
|
+
static inline void adjust_read_buffer_len(VALUE buffer, int result, int ofs) {
|
42
|
+
rb_str_modify(buffer);
|
43
|
+
unsigned len = result > 0 ? (unsigned)result : 0;
|
44
|
+
unsigned current_len = RSTRING_LEN(buffer);
|
45
|
+
if (ofs < 0) ofs = current_len + ofs + 1;
|
46
|
+
rb_str_set_len(buffer, len + (unsigned)ofs);
|
47
|
+
}
|
48
|
+
|
49
|
+
inline void um_update_read_buffer(struct um *machine, VALUE buffer, int buffer_offset, int result, int flags) {
|
50
|
+
if (!result) return;
|
51
|
+
|
52
|
+
adjust_read_buffer_len(buffer, result, buffer_offset);
|
53
|
+
}
|
54
|
+
|
55
|
+
inline VALUE get_string_from_buffer_ring(struct um *machine, int bgid, int result, int flags) {
|
56
|
+
if (!result) return Qnil;
|
57
|
+
|
58
|
+
unsigned buf_idx = flags >> IORING_CQE_BUFFER_SHIFT;
|
59
|
+
struct buf_ring_descriptor *desc = machine->buffer_rings + bgid;
|
60
|
+
char *src = desc->buf_base + desc->buf_size * buf_idx;
|
61
|
+
// TODO: add support for UTF8
|
62
|
+
// buf = rd->utf8_encoding ? rb_utf8_str_new(src, cqe->res) : rb_str_new(src, cqe->res);
|
63
|
+
VALUE buf = rb_str_new(src, result);
|
64
|
+
|
65
|
+
// add buffer back to buffer ring
|
66
|
+
io_uring_buf_ring_add(
|
67
|
+
desc->br, src, desc->buf_size, buf_idx, io_uring_buf_ring_mask(desc->buf_count), 0
|
68
|
+
);
|
69
|
+
io_uring_buf_ring_advance(desc->br, 1);
|
70
|
+
|
71
|
+
RB_GC_GUARD(buf);
|
72
|
+
return buf;
|
73
|
+
}
|
data/lib/uringmachine/version.rb
CHANGED
data/lib/uringmachine.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -3,8 +3,12 @@
|
|
3
3
|
require 'bundler/setup'
|
4
4
|
require_relative './coverage' if ENV['COVERAGE']
|
5
5
|
require 'uringmachine'
|
6
|
+
require 'socket'
|
6
7
|
require 'minitest/autorun'
|
7
8
|
|
9
|
+
STDOUT.sync = true
|
10
|
+
STDERR.sync = true
|
11
|
+
|
8
12
|
module ::Kernel
|
9
13
|
def debug(**h)
|
10
14
|
k, v = h.first
|
@@ -46,18 +50,6 @@ module Minitest::Assertions
|
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
49
|
-
class IOURingBaseTest < Minitest::Test
|
50
|
-
attr_accessor :ring
|
51
|
-
|
52
|
-
def setup
|
53
|
-
@ring = IOU::Ring.new
|
54
|
-
end
|
55
|
-
|
56
|
-
def teardown
|
57
|
-
ring.close
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
53
|
class UMBaseTest < Minitest::Test
|
62
54
|
attr_accessor :machine
|
63
55
|
|
@@ -66,5 +58,6 @@ class UMBaseTest < Minitest::Test
|
|
66
58
|
end
|
67
59
|
|
68
60
|
def teardown
|
61
|
+
# @machine&.cleanup
|
69
62
|
end
|
70
63
|
end
|
data/test/test_um.rb
CHANGED
@@ -3,16 +3,6 @@
|
|
3
3
|
require_relative 'helper'
|
4
4
|
require 'socket'
|
5
5
|
|
6
|
-
class SleepTest < UMBaseTest
|
7
|
-
def test_sleep
|
8
|
-
t0 = monotonic_clock
|
9
|
-
res = machine.sleep(0.1)
|
10
|
-
t1 = monotonic_clock
|
11
|
-
assert_in_range 0.09..0.13, t1 - t0
|
12
|
-
assert_equal 0.1, res
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
6
|
class SchedulingTest < UMBaseTest
|
17
7
|
def test_schedule_and_yield
|
18
8
|
buf = []
|
@@ -119,8 +109,8 @@ class SchedulingTest < UMBaseTest
|
|
119
109
|
|
120
110
|
def test_timeout_with_raising_block
|
121
111
|
e = nil
|
122
|
-
|
123
|
-
machine.timeout(0.
|
112
|
+
begin
|
113
|
+
machine.timeout(0.1, TOError) do
|
124
114
|
raise 'hi'
|
125
115
|
end
|
126
116
|
rescue => e
|
@@ -135,7 +125,7 @@ class SchedulingTest < UMBaseTest
|
|
135
125
|
end
|
136
126
|
|
137
127
|
def test_timeout_with_nothing_blocking
|
138
|
-
v = machine.timeout(0.
|
128
|
+
v = machine.timeout(0.1, TOError) { 42 }
|
139
129
|
|
140
130
|
assert_equal 42, v
|
141
131
|
|
@@ -166,3 +156,259 @@ class SchedulingTest < UMBaseTest
|
|
166
156
|
assert_equal [3], buf
|
167
157
|
end
|
168
158
|
end
|
159
|
+
|
160
|
+
class SleepTest < UMBaseTest
|
161
|
+
def test_sleep
|
162
|
+
t0 = monotonic_clock
|
163
|
+
res = machine.sleep(0.1)
|
164
|
+
t1 = monotonic_clock
|
165
|
+
assert_in_range 0.09..0.13, t1 - t0
|
166
|
+
assert_equal 0.1, res
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
class ReadTest < UMBaseTest
|
171
|
+
def test_read
|
172
|
+
r, w = IO.pipe
|
173
|
+
w << 'foobar'
|
174
|
+
|
175
|
+
buf = +''
|
176
|
+
res = machine.read(r.fileno, buf, 3)
|
177
|
+
assert_equal 3, res
|
178
|
+
assert_equal 'foo', buf
|
179
|
+
|
180
|
+
buf = +''
|
181
|
+
res = machine.read(r.fileno, buf, 128)
|
182
|
+
assert_equal 3, res
|
183
|
+
assert_equal 'bar', buf
|
184
|
+
|
185
|
+
w.close
|
186
|
+
buf = +''
|
187
|
+
res = machine.read(r.fileno, buf, 128)
|
188
|
+
assert_equal 0, res
|
189
|
+
assert_equal '', buf
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_read_bad_fd
|
193
|
+
_r, w = IO.pipe
|
194
|
+
|
195
|
+
assert_raises(Errno::EBADF) do
|
196
|
+
machine.read(w.fileno, +'', 8192)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_read_with_buffer_offset
|
201
|
+
buffer = +'foo'
|
202
|
+
r, w = IO.pipe
|
203
|
+
w << 'bar'
|
204
|
+
|
205
|
+
result = machine.read(r.fileno, buffer, 100, buffer.bytesize)
|
206
|
+
assert_equal 3, result
|
207
|
+
assert_equal 'foobar', buffer
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_read_with_negative_buffer_offset
|
211
|
+
buffer = +'foo'
|
212
|
+
|
213
|
+
r, w = IO.pipe
|
214
|
+
w << 'bar'
|
215
|
+
|
216
|
+
result = machine.read(r.fileno, buffer, 100, -1)
|
217
|
+
assert_equal 3, result
|
218
|
+
assert_equal 'foobar', buffer
|
219
|
+
|
220
|
+
buffer = +'foogrr'
|
221
|
+
|
222
|
+
r, w = IO.pipe
|
223
|
+
w << 'bar'
|
224
|
+
|
225
|
+
result = machine.read(r.fileno, buffer, 100, -4)
|
226
|
+
assert_equal 3, result
|
227
|
+
assert_equal 'foobar', buffer
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
class ReadEachTest < UMBaseTest
|
232
|
+
def test_read_each
|
233
|
+
r, w = IO.pipe
|
234
|
+
bufs = []
|
235
|
+
|
236
|
+
bgid = machine.setup_buffer_ring(4096, 1024)
|
237
|
+
assert_equal 0, bgid
|
238
|
+
|
239
|
+
f = Fiber.new do
|
240
|
+
w << 'foo'
|
241
|
+
machine.snooze
|
242
|
+
w << 'bar'
|
243
|
+
machine.snooze
|
244
|
+
w << 'baz'
|
245
|
+
machine.snooze
|
246
|
+
w.close
|
247
|
+
machine.yield
|
248
|
+
end
|
249
|
+
machine.schedule(f, nil)
|
250
|
+
|
251
|
+
machine.read_each(r.fileno, bgid) do |buf|
|
252
|
+
bufs << buf
|
253
|
+
end
|
254
|
+
|
255
|
+
assert_equal ['foo', 'bar', 'baz'], bufs
|
256
|
+
assert_equal 0, machine.pending_count
|
257
|
+
end
|
258
|
+
|
259
|
+
# send once and close write fd
|
260
|
+
def test_read_each_raising_1
|
261
|
+
r, w = IO.pipe
|
262
|
+
|
263
|
+
bgid = machine.setup_buffer_ring(4096, 1024)
|
264
|
+
assert_equal 0, bgid
|
265
|
+
|
266
|
+
w << 'foo'
|
267
|
+
w.close
|
268
|
+
|
269
|
+
e = nil
|
270
|
+
begin
|
271
|
+
machine.read_each(r.fileno, bgid) do |buf|
|
272
|
+
raise 'hi'
|
273
|
+
end
|
274
|
+
rescue => e
|
275
|
+
end
|
276
|
+
|
277
|
+
assert_kind_of RuntimeError, e
|
278
|
+
assert_equal 'hi', e.message
|
279
|
+
assert_equal 0, machine.pending_count
|
280
|
+
end
|
281
|
+
|
282
|
+
# send once and leave write fd open
|
283
|
+
def test_read_each_raising_2
|
284
|
+
r, w = IO.pipe
|
285
|
+
|
286
|
+
bgid = machine.setup_buffer_ring(4096, 1024)
|
287
|
+
assert_equal 0, bgid
|
288
|
+
|
289
|
+
w << 'foo'
|
290
|
+
|
291
|
+
e = nil
|
292
|
+
begin
|
293
|
+
machine.read_each(r.fileno, bgid) do |buf|
|
294
|
+
raise 'hi'
|
295
|
+
end
|
296
|
+
rescue => e
|
297
|
+
end
|
298
|
+
|
299
|
+
assert_kind_of RuntimeError, e
|
300
|
+
assert_equal 'hi', e.message
|
301
|
+
|
302
|
+
# since the write fd is still open, the read_each impl is supposed to cancel
|
303
|
+
# the op, which is done asynchronously.
|
304
|
+
assert_equal 1, machine.pending_count
|
305
|
+
machine.snooze
|
306
|
+
assert_equal 0, machine.pending_count
|
307
|
+
end
|
308
|
+
|
309
|
+
# send twice
|
310
|
+
def test_read_each_raising_3
|
311
|
+
r, w = IO.pipe
|
312
|
+
|
313
|
+
bgid = machine.setup_buffer_ring(4096, 1024)
|
314
|
+
assert_equal 0, bgid
|
315
|
+
|
316
|
+
w << 'foo'
|
317
|
+
w << 'bar'
|
318
|
+
|
319
|
+
e = nil
|
320
|
+
begin
|
321
|
+
machine.read_each(r.fileno, bgid) do |buf|
|
322
|
+
raise 'hi'
|
323
|
+
end
|
324
|
+
rescue => e
|
325
|
+
end
|
326
|
+
|
327
|
+
assert_kind_of RuntimeError, e
|
328
|
+
assert_equal 'hi', e.message
|
329
|
+
|
330
|
+
# since the write fd is still open, the read_each impl is supposed to cancel
|
331
|
+
# the op, which is done asynchronously.
|
332
|
+
assert_equal 1, machine.pending_count
|
333
|
+
machine.snooze
|
334
|
+
assert_equal 0, machine.pending_count
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
class WriteTest < UMBaseTest
|
339
|
+
def test_write
|
340
|
+
r, w = IO.pipe
|
341
|
+
|
342
|
+
machine.write(w.fileno, 'foo')
|
343
|
+
assert_equal 'foo', r.readpartial(3)
|
344
|
+
|
345
|
+
machine.write(w.fileno, 'bar', 2)
|
346
|
+
assert_equal 'ba', r.readpartial(3)
|
347
|
+
end
|
348
|
+
|
349
|
+
def test_write_bad_fd
|
350
|
+
r, _w = IO.pipe
|
351
|
+
|
352
|
+
assert_raises(Errno::EBADF) do
|
353
|
+
machine.write(r.fileno, 'foo')
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
class AcceptTest < UMBaseTest
|
359
|
+
def setup
|
360
|
+
super
|
361
|
+
@port = 9000 + rand(1000)
|
362
|
+
@server = TCPServer.open('127.0.0.1', @port)
|
363
|
+
end
|
364
|
+
|
365
|
+
def teardown
|
366
|
+
@server&.close
|
367
|
+
super
|
368
|
+
end
|
369
|
+
|
370
|
+
def test_accept
|
371
|
+
conn = TCPSocket.new('127.0.0.1', @port)
|
372
|
+
|
373
|
+
fd = machine.accept(@server.fileno)
|
374
|
+
assert_kind_of Integer, fd
|
375
|
+
assert fd > 0
|
376
|
+
|
377
|
+
machine.write(fd, 'foo')
|
378
|
+
buf = conn.readpartial(3)
|
379
|
+
|
380
|
+
assert_equal 'foo', buf
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
class AcceptEachTest < UMBaseTest
|
385
|
+
def setup
|
386
|
+
super
|
387
|
+
@port = 9000 + rand(1000)
|
388
|
+
@server = TCPServer.open('127.0.0.1', @port)
|
389
|
+
end
|
390
|
+
|
391
|
+
def teardown
|
392
|
+
@server&.close
|
393
|
+
super
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_accept_each
|
397
|
+
conns = 3.times.map { TCPSocket.new('127.0.0.1', @port) }
|
398
|
+
|
399
|
+
count = 0
|
400
|
+
machine.accept_each(@server.fileno) do |fd|
|
401
|
+
machine.write(fd, (count += 1).to_s)
|
402
|
+
break if count == 3
|
403
|
+
end
|
404
|
+
|
405
|
+
assert_equal 3, count
|
406
|
+
assert_equal 1, machine.pending_count
|
407
|
+
machine.snooze
|
408
|
+
assert_equal 0, machine.pending_count
|
409
|
+
|
410
|
+
assert_equal '1', conns[0].readpartial(3)
|
411
|
+
assert_equal '2', conns[1].readpartial(3)
|
412
|
+
assert_equal '3', conns[2].readpartial(3)
|
413
|
+
end
|
414
|
+
end
|
data/uringmachine.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uringmachine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-10-
|
11
|
+
date: 2024-10-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -91,9 +91,6 @@ files:
|
|
91
91
|
- examples/http_server_multishot.rb
|
92
92
|
- examples/http_server_simpler.rb
|
93
93
|
- ext/um/extconf.rb
|
94
|
-
- ext/um/iou.h
|
95
|
-
- ext/um/op_ctx.c
|
96
|
-
- ext/um/ring.c
|
97
94
|
- ext/um/um.c
|
98
95
|
- ext/um/um.h
|
99
96
|
- ext/um/um_class.c
|
@@ -103,7 +100,6 @@ files:
|
|
103
100
|
- lib/uringmachine.rb
|
104
101
|
- lib/uringmachine/version.rb
|
105
102
|
- test/helper.rb
|
106
|
-
- test/test_iou.rb
|
107
103
|
- test/test_um.rb
|
108
104
|
- uringmachine.gemspec
|
109
105
|
- vendor/liburing/.github/actions/codespell/stopwords
|
data/ext/um/iou.h
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
#ifndef IOU_H
|
2
|
-
#define IOU_H
|
3
|
-
|
4
|
-
#include "ruby.h"
|
5
|
-
#include <liburing.h>
|
6
|
-
|
7
|
-
// debugging
|
8
|
-
#define OBJ_ID(obj) (NUM2LONG(rb_funcall(obj, rb_intern("object_id"), 0)))
|
9
|
-
#define INSPECT(str, obj) { printf(str); VALUE s = rb_funcall(obj, rb_intern("inspect"), 0); printf(": %s\n", StringValueCStr(s)); }
|
10
|
-
#define CALLER() rb_funcall(rb_mKernel, rb_intern("caller"), 0)
|
11
|
-
#define TRACE_CALLER() INSPECT("caller: ", CALLER())
|
12
|
-
#define TRACE_FREE(ptr) //printf("Free %p %s:%d\n", ptr, __FILE__, __LINE__)
|
13
|
-
|
14
|
-
// branching
|
15
|
-
#ifndef unlikely
|
16
|
-
#define unlikely(cond) __builtin_expect(!!(cond), 0)
|
17
|
-
#endif
|
18
|
-
|
19
|
-
#ifndef likely
|
20
|
-
#define likely(cond) __builtin_expect(!!(cond), 1)
|
21
|
-
#endif
|
22
|
-
|
23
|
-
struct buf_ring_descriptor {
|
24
|
-
struct io_uring_buf_ring *br;
|
25
|
-
size_t br_size;
|
26
|
-
// struct io_uring_buf_ring *buf_ring;
|
27
|
-
unsigned buf_count;
|
28
|
-
unsigned buf_size;
|
29
|
-
char *buf_base;
|
30
|
-
// size_t buf_ring_size;
|
31
|
-
};
|
32
|
-
|
33
|
-
#define BUFFER_RING_MAX_COUNT 10
|
34
|
-
|
35
|
-
typedef struct IOURing_t {
|
36
|
-
struct io_uring ring;
|
37
|
-
unsigned int ring_initialized;
|
38
|
-
unsigned int op_counter;
|
39
|
-
unsigned int unsubmitted_sqes;
|
40
|
-
VALUE pending_ops;
|
41
|
-
|
42
|
-
struct buf_ring_descriptor brs[BUFFER_RING_MAX_COUNT];
|
43
|
-
unsigned int br_counter;
|
44
|
-
} IOURing_t;
|
45
|
-
|
46
|
-
struct sa_data {
|
47
|
-
struct sockaddr addr;
|
48
|
-
socklen_t len;
|
49
|
-
};
|
50
|
-
|
51
|
-
struct read_data {
|
52
|
-
VALUE buffer;
|
53
|
-
int buffer_offset;
|
54
|
-
unsigned bg_id;
|
55
|
-
int utf8_encoding;
|
56
|
-
};
|
57
|
-
|
58
|
-
enum op_type {
|
59
|
-
OP_accept,
|
60
|
-
OP_cancel,
|
61
|
-
OP_close,
|
62
|
-
OP_emit,
|
63
|
-
OP_nop,
|
64
|
-
OP_read,
|
65
|
-
OP_timeout,
|
66
|
-
OP_write
|
67
|
-
};
|
68
|
-
|
69
|
-
typedef struct OpCtx_t {
|
70
|
-
enum op_type type;
|
71
|
-
VALUE spec;
|
72
|
-
VALUE proc;
|
73
|
-
union {
|
74
|
-
struct __kernel_timespec ts;
|
75
|
-
struct sa_data sa;
|
76
|
-
struct read_data rd;
|
77
|
-
} data;
|
78
|
-
int stop_signal;
|
79
|
-
} OpCtx_t;
|
80
|
-
|
81
|
-
extern VALUE mIOU;
|
82
|
-
extern VALUE cOpCtx;
|
83
|
-
|
84
|
-
enum op_type OpCtx_type_get(VALUE self);
|
85
|
-
void OpCtx_type_set(VALUE self, enum op_type type);
|
86
|
-
|
87
|
-
VALUE OpCtx_spec_get(VALUE self);
|
88
|
-
VALUE OpCtx_proc_get(VALUE self);
|
89
|
-
|
90
|
-
struct __kernel_timespec *OpCtx_ts_get(VALUE self);
|
91
|
-
void OpCtx_ts_set(VALUE self, VALUE value);
|
92
|
-
|
93
|
-
struct sa_data *OpCtx_sa_get(VALUE self);
|
94
|
-
|
95
|
-
struct read_data *OpCtx_rd_get(VALUE self);
|
96
|
-
void OpCtx_rd_set(VALUE self, VALUE buffer, int buffer_offset, unsigned bg_id, int utf8_encoding);
|
97
|
-
|
98
|
-
int OpCtx_stop_signal_p(VALUE self);
|
99
|
-
void OpCtx_stop_signal_set(VALUE self);
|
100
|
-
|
101
|
-
#endif // IOU_H
|