event 0.5.0 → 0.6.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/ext/event/backend.o +0 -0
- data/ext/event/backend/backend.c +52 -8
- data/ext/event/backend/backend.h +7 -0
- data/ext/event/backend/epoll.c +153 -1
- data/ext/event/backend/kqueue.c +158 -7
- data/ext/event/backend/uring.c +66 -56
- data/ext/event/event.bundle +0 -0
- data/ext/event/extconf.rb +1 -2
- data/ext/event/kqueue.o +0 -0
- data/ext/event/mkmf.log +5 -30
- data/lib/event/backend/select.rb +44 -1
- data/lib/event/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0380b6d95d8bd8f8d378820eefa77e6c6f0f1aaceb2afec54cb4d38f57747cbc'
|
4
|
+
data.tar.gz: 2a0bfede977154f30a402fda4ec445eedc4daf3893bae8760eceaa1e58c999be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d12fab2ce89b8c22d583a7472670f8bdb5b5b3428832938f9c51ce3635f08bfaf7d107b6568f762849a4fa8b32fdb0d79823bbd4ebd795b690e885b0eff52798
|
7
|
+
data.tar.gz: 793cf18caeb1457cd5499ee3d0fd2108dbf46e953cbc11b80e7c800efeb6beac279395a24da420b4c751a89ee5ecd54ad53a3b3a58d4b07d75e9a89d84a8be4d
|
data/ext/event/backend.o
CHANGED
Binary file
|
data/ext/event/backend/backend.c
CHANGED
@@ -19,12 +19,7 @@
|
|
19
19
|
// THE SOFTWARE.
|
20
20
|
|
21
21
|
#include "backend.h"
|
22
|
-
|
23
|
-
#if HAVE_RB_FIBER_TRANSFER_KW
|
24
|
-
#define HAVE_RB_FIBER_TRANSFER 1
|
25
|
-
#else
|
26
|
-
#define HAVE_RB_FIBER_TRANSFER 0
|
27
|
-
#endif
|
22
|
+
#include <fcntl.h>
|
28
23
|
|
29
24
|
static ID id_transfer, id_wait;
|
30
25
|
static VALUE rb_Process_Status = Qnil;
|
@@ -38,7 +33,7 @@ void Init_Event_Backend(VALUE Event_Backend) {
|
|
38
33
|
|
39
34
|
VALUE
|
40
35
|
Event_Backend_transfer(VALUE fiber) {
|
41
|
-
#
|
36
|
+
#ifdef HAVE__RB_FIBER_TRANSFER
|
42
37
|
return rb_fiber_transfer(fiber, 0, NULL);
|
43
38
|
#else
|
44
39
|
return rb_funcall(fiber, id_transfer, 0);
|
@@ -51,7 +46,7 @@ Event_Backend_transfer_result(VALUE fiber, VALUE result) {
|
|
51
46
|
// return Qnil;
|
52
47
|
// }
|
53
48
|
|
54
|
-
#
|
49
|
+
#ifdef HAVE__RB_FIBER_TRANSFER
|
55
50
|
return rb_fiber_transfer(fiber, 1, &result);
|
56
51
|
#else
|
57
52
|
return rb_funcall(fiber, id_transfer, 1, result);
|
@@ -62,3 +57,52 @@ VALUE Event_Backend_process_status_wait(rb_pid_t pid)
|
|
62
57
|
{
|
63
58
|
return rb_funcall(rb_Process_Status, id_wait, 2, PIDT2NUM(pid), INT2NUM(WNOHANG));
|
64
59
|
}
|
60
|
+
|
61
|
+
char* Event_Backend_verify_size(VALUE buffer, size_t offset, size_t length) {
|
62
|
+
if ((size_t)RSTRING_LEN(buffer) < offset + length) {
|
63
|
+
rb_raise(rb_eRuntimeError, "invalid offset/length exceeds bounds of buffer");
|
64
|
+
}
|
65
|
+
|
66
|
+
return RSTRING_PTR(buffer);
|
67
|
+
}
|
68
|
+
|
69
|
+
char* Event_Backend_resize_to_capacity(VALUE string, size_t offset, size_t length) {
|
70
|
+
size_t current_length = RSTRING_LEN(string);
|
71
|
+
long difference = (long)(offset + length) - (long)current_length;
|
72
|
+
|
73
|
+
difference += 1;
|
74
|
+
|
75
|
+
if (difference > 0) {
|
76
|
+
rb_str_modify_expand(string, difference);
|
77
|
+
} else {
|
78
|
+
rb_str_modify(string);
|
79
|
+
}
|
80
|
+
|
81
|
+
return RSTRING_PTR(string);
|
82
|
+
}
|
83
|
+
|
84
|
+
void Event_Backend_resize_to_fit(VALUE string, size_t offset, size_t length) {
|
85
|
+
size_t current_length = RSTRING_LEN(string);
|
86
|
+
|
87
|
+
if (current_length < (offset + length)) {
|
88
|
+
rb_str_set_len(string, offset + length);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
int Event_Backend_nonblock_set(int file_descriptor)
|
93
|
+
{
|
94
|
+
int flags = fcntl(file_descriptor, F_GETFL, 0);
|
95
|
+
|
96
|
+
if (!(flags & O_NONBLOCK)) {
|
97
|
+
fcntl(file_descriptor, F_SETFL, flags | O_NONBLOCK);
|
98
|
+
}
|
99
|
+
|
100
|
+
return flags;
|
101
|
+
}
|
102
|
+
|
103
|
+
void Event_Backend_nonblock_restore(int file_descriptor, int flags)
|
104
|
+
{
|
105
|
+
if (!(flags & O_NONBLOCK)) {
|
106
|
+
fcntl(file_descriptor, F_SETFL, flags & ~flags);
|
107
|
+
}
|
108
|
+
}
|
data/ext/event/backend/backend.h
CHANGED
@@ -36,3 +36,10 @@ VALUE Event_Backend_transfer(VALUE fiber);
|
|
36
36
|
VALUE Event_Backend_transfer_result(VALUE fiber, VALUE argument);
|
37
37
|
|
38
38
|
VALUE Event_Backend_process_status_wait(rb_pid_t pid);
|
39
|
+
|
40
|
+
char* Event_Backend_verify_size(VALUE buffer, size_t offset, size_t length);
|
41
|
+
char* Event_Backend_resize_to_capacity(VALUE string, size_t offset, size_t length);
|
42
|
+
void Event_Backend_resize_to_fit(VALUE string, size_t offset, size_t length);
|
43
|
+
|
44
|
+
int Event_Backend_nonblock_set(int file_descriptor);
|
45
|
+
void Event_Backend_nonblock_restore(int file_descriptor, int flags);
|
data/ext/event/backend/epoll.c
CHANGED
@@ -264,6 +264,155 @@ VALUE Event_Backend_EPoll_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE event
|
|
264
264
|
return rb_ensure(io_wait_transfer, (VALUE)&io_wait_arguments, io_wait_ensure, (VALUE)&io_wait_arguments);
|
265
265
|
}
|
266
266
|
|
267
|
+
struct io_read_arguments {
|
268
|
+
VALUE self;
|
269
|
+
VALUE fiber;
|
270
|
+
VALUE io;
|
271
|
+
|
272
|
+
int flags;
|
273
|
+
|
274
|
+
int descriptor;
|
275
|
+
|
276
|
+
VALUE buffer;
|
277
|
+
size_t offset;
|
278
|
+
size_t length;
|
279
|
+
};
|
280
|
+
|
281
|
+
static
|
282
|
+
VALUE io_read_loop(VALUE _arguments) {
|
283
|
+
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
284
|
+
|
285
|
+
size_t offset = arguments->offset;
|
286
|
+
size_t length = arguments->length;
|
287
|
+
size_t total = 0;
|
288
|
+
|
289
|
+
while (length > 0) {
|
290
|
+
char *buffer = Event_Backend_resize_to_capacity(arguments->buffer, offset, length);
|
291
|
+
ssize_t result = read(arguments->descriptor, buffer+offset, length);
|
292
|
+
|
293
|
+
if (result >= 0) {
|
294
|
+
offset += result;
|
295
|
+
length -= result;
|
296
|
+
total += result;
|
297
|
+
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
298
|
+
Event_Backend_EPoll_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(READABLE));
|
299
|
+
} else {
|
300
|
+
rb_sys_fail("Event_Backend_EPoll_io_read");
|
301
|
+
}
|
302
|
+
}
|
303
|
+
|
304
|
+
Event_Backend_resize_to_fit(arguments->buffer, arguments->offset, arguments->length);
|
305
|
+
|
306
|
+
return SIZET2NUM(total);
|
307
|
+
}
|
308
|
+
|
309
|
+
static
|
310
|
+
VALUE io_read_ensure(VALUE _arguments) {
|
311
|
+
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
312
|
+
|
313
|
+
Event_Backend_nonblock_restore(arguments->descriptor, arguments->flags);
|
314
|
+
|
315
|
+
return Qnil;
|
316
|
+
}
|
317
|
+
|
318
|
+
VALUE Event_Backend_EPoll_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _offset, VALUE _length) {
|
319
|
+
struct Event_Backend_EPoll *data = NULL;
|
320
|
+
TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
|
321
|
+
|
322
|
+
int descriptor = RB_NUM2INT(rb_funcall(io, id_fileno, 0));
|
323
|
+
|
324
|
+
size_t offset = NUM2SIZET(_offset);
|
325
|
+
size_t length = NUM2SIZET(_length);
|
326
|
+
|
327
|
+
|
328
|
+
struct io_read_arguments io_read_arguments = {
|
329
|
+
.self = self,
|
330
|
+
.fiber = fiber,
|
331
|
+
.io = io,
|
332
|
+
|
333
|
+
.flags = Event_Backend_nonblock_set(descriptor),
|
334
|
+
.descriptor = descriptor,
|
335
|
+
.buffer = buffer,
|
336
|
+
.offset = offset,
|
337
|
+
.length = length,
|
338
|
+
};
|
339
|
+
|
340
|
+
return rb_ensure(io_read_loop, (VALUE)&io_read_arguments, io_read_ensure, (VALUE)&io_read_arguments);
|
341
|
+
}
|
342
|
+
|
343
|
+
struct io_write_arguments {
|
344
|
+
VALUE self;
|
345
|
+
VALUE fiber;
|
346
|
+
VALUE io;
|
347
|
+
|
348
|
+
int flags;
|
349
|
+
|
350
|
+
int descriptor;
|
351
|
+
|
352
|
+
VALUE buffer;
|
353
|
+
size_t offset;
|
354
|
+
size_t length;
|
355
|
+
};
|
356
|
+
|
357
|
+
static
|
358
|
+
VALUE io_write_loop(VALUE _arguments) {
|
359
|
+
struct io_write_arguments *arguments = (struct io_write_arguments *)_arguments;
|
360
|
+
|
361
|
+
size_t offset = arguments->offset;
|
362
|
+
size_t length = arguments->length;
|
363
|
+
size_t total = 0;
|
364
|
+
|
365
|
+
while (length > 0) {
|
366
|
+
char *buffer = Event_Backend_verify_size(arguments->buffer, offset, length);
|
367
|
+
ssize_t result = write(arguments->descriptor, buffer+offset, length);
|
368
|
+
|
369
|
+
if (result >= 0) {
|
370
|
+
length -= result;
|
371
|
+
offset += result;
|
372
|
+
total += result;
|
373
|
+
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
374
|
+
Event_Backend_EPoll_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(WRITABLE));
|
375
|
+
} else {
|
376
|
+
rb_sys_fail("Event_Backend_EPoll_io_write");
|
377
|
+
}
|
378
|
+
}
|
379
|
+
|
380
|
+
return SIZET2NUM(total);
|
381
|
+
};
|
382
|
+
|
383
|
+
static
|
384
|
+
VALUE io_write_ensure(VALUE _arguments) {
|
385
|
+
struct io_write_arguments *arguments = (struct io_write_arguments *)_arguments;
|
386
|
+
|
387
|
+
Event_Backend_nonblock_restore(arguments->descriptor, arguments->flags);
|
388
|
+
|
389
|
+
return Qnil;
|
390
|
+
};
|
391
|
+
|
392
|
+
VALUE Event_Backend_EPoll_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _offset, VALUE _length) {
|
393
|
+
struct Event_Backend_EPoll *data = NULL;
|
394
|
+
TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
|
395
|
+
|
396
|
+
int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
|
397
|
+
|
398
|
+
size_t offset = NUM2SIZET(_offset);
|
399
|
+
size_t length = NUM2SIZET(_length);
|
400
|
+
|
401
|
+
struct io_write_arguments io_write_arguments = {
|
402
|
+
.self = self,
|
403
|
+
.fiber = fiber,
|
404
|
+
.io = io,
|
405
|
+
|
406
|
+
.flags = Event_Backend_nonblock_set(descriptor),
|
407
|
+
.descriptor = descriptor,
|
408
|
+
.buffer = buffer,
|
409
|
+
.offset = offset,
|
410
|
+
.length = length,
|
411
|
+
};
|
412
|
+
|
413
|
+
return rb_ensure(io_write_loop, (VALUE)&io_write_arguments, io_write_ensure, (VALUE)&io_write_arguments);
|
414
|
+
}
|
415
|
+
|
267
416
|
static
|
268
417
|
int make_timeout(VALUE duration) {
|
269
418
|
if (duration == Qnil) {
|
@@ -357,9 +506,12 @@ void Init_Event_Backend_EPoll(VALUE Event_Backend) {
|
|
357
506
|
|
358
507
|
rb_define_alloc_func(Event_Backend_EPoll, Event_Backend_EPoll_allocate);
|
359
508
|
rb_define_method(Event_Backend_EPoll, "initialize", Event_Backend_EPoll_initialize, 1);
|
509
|
+
rb_define_method(Event_Backend_EPoll, "select", Event_Backend_EPoll_select, 1);
|
360
510
|
rb_define_method(Event_Backend_EPoll, "close", Event_Backend_EPoll_close, 0);
|
361
511
|
|
362
512
|
rb_define_method(Event_Backend_EPoll, "io_wait", Event_Backend_EPoll_io_wait, 3);
|
363
|
-
rb_define_method(Event_Backend_EPoll, "
|
513
|
+
rb_define_method(Event_Backend_EPoll, "io_read", Event_Backend_EPoll_io_read, 5);
|
514
|
+
rb_define_method(Event_Backend_EPoll, "io_write", Event_Backend_EPoll_io_write, 5);
|
515
|
+
|
364
516
|
rb_define_method(Event_Backend_EPoll, "process_wait", Event_Backend_EPoll_process_wait, 3);
|
365
517
|
}
|
data/ext/event/backend/kqueue.c
CHANGED
@@ -181,7 +181,7 @@ VALUE Event_Backend_KQueue_process_wait(VALUE self, VALUE fiber, VALUE pid, VALU
|
|
181
181
|
struct process_wait_arguments process_wait_arguments = {
|
182
182
|
.data = data,
|
183
183
|
.pid = NUM2PIDT(pid),
|
184
|
-
.flags =
|
184
|
+
.flags = RB_NUM2INT(flags),
|
185
185
|
};
|
186
186
|
|
187
187
|
int waiting = process_add_filters(data->descriptor, process_wait_arguments.pid, fiber);
|
@@ -267,7 +267,7 @@ VALUE io_wait_rescue(VALUE _arguments, VALUE exception) {
|
|
267
267
|
io_remove_filters(arguments->data->descriptor, arguments->descriptor, arguments->events);
|
268
268
|
|
269
269
|
rb_exc_raise(exception);
|
270
|
-
}
|
270
|
+
}
|
271
271
|
|
272
272
|
static inline
|
273
273
|
int events_from_kqueue_filter(int filter) {
|
@@ -283,17 +283,17 @@ VALUE io_wait_transfer(VALUE _arguments) {
|
|
283
283
|
|
284
284
|
VALUE result = Event_Backend_transfer(arguments->data->loop);
|
285
285
|
|
286
|
-
return INT2NUM(events_from_kqueue_filter(
|
287
|
-
}
|
286
|
+
return INT2NUM(events_from_kqueue_filter(RB_NUM2INT(result)));
|
287
|
+
}
|
288
288
|
|
289
289
|
VALUE Event_Backend_KQueue_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE events) {
|
290
290
|
struct Event_Backend_KQueue *data = NULL;
|
291
291
|
TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
|
292
292
|
|
293
|
-
int descriptor =
|
293
|
+
int descriptor = RB_NUM2INT(rb_funcall(io, id_fileno, 0));
|
294
294
|
|
295
295
|
struct io_wait_arguments io_wait_arguments = {
|
296
|
-
.events = io_add_filters(data->descriptor, descriptor,
|
296
|
+
.events = io_add_filters(data->descriptor, descriptor, RB_NUM2INT(events), fiber),
|
297
297
|
.data = data,
|
298
298
|
.descriptor = descriptor,
|
299
299
|
};
|
@@ -301,6 +301,154 @@ VALUE Event_Backend_KQueue_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE even
|
|
301
301
|
return rb_rescue(io_wait_transfer, (VALUE)&io_wait_arguments, io_wait_rescue, (VALUE)&io_wait_arguments);
|
302
302
|
}
|
303
303
|
|
304
|
+
struct io_read_arguments {
|
305
|
+
VALUE self;
|
306
|
+
VALUE fiber;
|
307
|
+
VALUE io;
|
308
|
+
|
309
|
+
int flags;
|
310
|
+
|
311
|
+
int descriptor;
|
312
|
+
|
313
|
+
VALUE buffer;
|
314
|
+
size_t offset;
|
315
|
+
size_t length;
|
316
|
+
};
|
317
|
+
|
318
|
+
static
|
319
|
+
VALUE io_read_loop(VALUE _arguments) {
|
320
|
+
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
321
|
+
|
322
|
+
size_t offset = arguments->offset;
|
323
|
+
size_t length = arguments->length;
|
324
|
+
size_t total = 0;
|
325
|
+
|
326
|
+
while (length > 0) {
|
327
|
+
char *buffer = Event_Backend_resize_to_capacity(arguments->buffer, offset, length);
|
328
|
+
ssize_t result = read(arguments->descriptor, buffer+offset, length);
|
329
|
+
|
330
|
+
if (result >= 0) {
|
331
|
+
offset += result;
|
332
|
+
length -= result;
|
333
|
+
total += result;
|
334
|
+
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
335
|
+
Event_Backend_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(READABLE));
|
336
|
+
} else {
|
337
|
+
rb_sys_fail("Event_Backend_KQueue_io_read");
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
341
|
+
Event_Backend_resize_to_fit(arguments->buffer, arguments->offset, arguments->length);
|
342
|
+
|
343
|
+
return SIZET2NUM(total);
|
344
|
+
}
|
345
|
+
|
346
|
+
static
|
347
|
+
VALUE io_read_ensure(VALUE _arguments) {
|
348
|
+
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
349
|
+
|
350
|
+
Event_Backend_nonblock_restore(arguments->descriptor, arguments->flags);
|
351
|
+
|
352
|
+
return Qnil;
|
353
|
+
}
|
354
|
+
|
355
|
+
VALUE Event_Backend_KQueue_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _offset, VALUE _length) {
|
356
|
+
struct Event_Backend_KQueue *data = NULL;
|
357
|
+
TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
|
358
|
+
|
359
|
+
int descriptor = RB_NUM2INT(rb_funcall(io, id_fileno, 0));
|
360
|
+
|
361
|
+
size_t offset = NUM2SIZET(_offset);
|
362
|
+
size_t length = NUM2SIZET(_length);
|
363
|
+
|
364
|
+
struct io_read_arguments io_read_arguments = {
|
365
|
+
.self = self,
|
366
|
+
.fiber = fiber,
|
367
|
+
.io = io,
|
368
|
+
|
369
|
+
.flags = Event_Backend_nonblock_set(descriptor),
|
370
|
+
.descriptor = descriptor,
|
371
|
+
.buffer = buffer,
|
372
|
+
.offset = offset,
|
373
|
+
.length = length,
|
374
|
+
};
|
375
|
+
|
376
|
+
return rb_ensure(io_read_loop, (VALUE)&io_read_arguments, io_read_ensure, (VALUE)&io_read_arguments);
|
377
|
+
}
|
378
|
+
|
379
|
+
struct io_write_arguments {
|
380
|
+
VALUE self;
|
381
|
+
VALUE fiber;
|
382
|
+
VALUE io;
|
383
|
+
|
384
|
+
int flags;
|
385
|
+
|
386
|
+
int descriptor;
|
387
|
+
|
388
|
+
VALUE buffer;
|
389
|
+
size_t offset;
|
390
|
+
size_t length;
|
391
|
+
};
|
392
|
+
|
393
|
+
static
|
394
|
+
VALUE io_write_loop(VALUE _arguments) {
|
395
|
+
struct io_write_arguments *arguments = (struct io_write_arguments *)_arguments;
|
396
|
+
|
397
|
+
size_t offset = arguments->offset;
|
398
|
+
size_t length = arguments->length;
|
399
|
+
size_t total = 0;
|
400
|
+
|
401
|
+
while (length > 0) {
|
402
|
+
char *buffer = Event_Backend_verify_size(arguments->buffer, offset, length);
|
403
|
+
ssize_t result = write(arguments->descriptor, buffer+offset, length);
|
404
|
+
|
405
|
+
if (result >= 0) {
|
406
|
+
length -= result;
|
407
|
+
offset += result;
|
408
|
+
total += result;
|
409
|
+
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
410
|
+
Event_Backend_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(WRITABLE));
|
411
|
+
} else {
|
412
|
+
rb_sys_fail("Event_Backend_KQueue_io_write");
|
413
|
+
}
|
414
|
+
}
|
415
|
+
|
416
|
+
return SIZET2NUM(total);
|
417
|
+
};
|
418
|
+
|
419
|
+
static
|
420
|
+
VALUE io_write_ensure(VALUE _arguments) {
|
421
|
+
struct io_write_arguments *arguments = (struct io_write_arguments *)_arguments;
|
422
|
+
|
423
|
+
Event_Backend_nonblock_restore(arguments->descriptor, arguments->flags);
|
424
|
+
|
425
|
+
return Qnil;
|
426
|
+
};
|
427
|
+
|
428
|
+
VALUE Event_Backend_KQueue_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _offset, VALUE _length) {
|
429
|
+
struct Event_Backend_KQueue *data = NULL;
|
430
|
+
TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
|
431
|
+
|
432
|
+
int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
|
433
|
+
|
434
|
+
size_t offset = NUM2SIZET(_offset);
|
435
|
+
size_t length = NUM2SIZET(_length);
|
436
|
+
|
437
|
+
struct io_write_arguments io_write_arguments = {
|
438
|
+
.self = self,
|
439
|
+
.fiber = fiber,
|
440
|
+
.io = io,
|
441
|
+
|
442
|
+
.flags = Event_Backend_nonblock_set(descriptor),
|
443
|
+
.descriptor = descriptor,
|
444
|
+
.buffer = buffer,
|
445
|
+
.offset = offset,
|
446
|
+
.length = length,
|
447
|
+
};
|
448
|
+
|
449
|
+
return rb_ensure(io_write_loop, (VALUE)&io_write_arguments, io_write_ensure, (VALUE)&io_write_arguments);
|
450
|
+
}
|
451
|
+
|
304
452
|
static
|
305
453
|
struct timespec * make_timeout(VALUE duration, struct timespec * storage) {
|
306
454
|
if (duration == Qnil) {
|
@@ -420,9 +568,12 @@ void Init_Event_Backend_KQueue(VALUE Event_Backend) {
|
|
420
568
|
|
421
569
|
rb_define_alloc_func(Event_Backend_KQueue, Event_Backend_KQueue_allocate);
|
422
570
|
rb_define_method(Event_Backend_KQueue, "initialize", Event_Backend_KQueue_initialize, 1);
|
571
|
+
rb_define_method(Event_Backend_KQueue, "select", Event_Backend_KQueue_select, 1);
|
423
572
|
rb_define_method(Event_Backend_KQueue, "close", Event_Backend_KQueue_close, 0);
|
424
573
|
|
425
574
|
rb_define_method(Event_Backend_KQueue, "io_wait", Event_Backend_KQueue_io_wait, 3);
|
426
|
-
rb_define_method(Event_Backend_KQueue, "
|
575
|
+
rb_define_method(Event_Backend_KQueue, "io_read", Event_Backend_KQueue_io_read, 5);
|
576
|
+
rb_define_method(Event_Backend_KQueue, "io_write", Event_Backend_KQueue_io_write, 5);
|
577
|
+
|
427
578
|
rb_define_method(Event_Backend_KQueue, "process_wait", Event_Backend_KQueue_process_wait, 3);
|
428
579
|
}
|
data/ext/event/backend/uring.c
CHANGED
@@ -260,88 +260,98 @@ VALUE Event_Backend_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE event
|
|
260
260
|
return rb_rescue(io_wait_transfer, (VALUE)&io_wait_arguments, io_wait_rescue, (VALUE)&io_wait_arguments);
|
261
261
|
}
|
262
262
|
|
263
|
-
|
264
|
-
|
265
|
-
size_t current_length = RSTRING_LEN(string);
|
266
|
-
long difference = (long)(offset + length) - (long)current_length;
|
267
|
-
|
268
|
-
difference += 1;
|
269
|
-
|
270
|
-
if (difference > 0) {
|
271
|
-
rb_str_modify_expand(string, difference);
|
272
|
-
} else {
|
273
|
-
rb_str_modify(string);
|
274
|
-
}
|
275
|
-
}
|
276
|
-
|
277
|
-
inline static
|
278
|
-
void resize_to_fit(VALUE string, size_t offset, size_t length) {
|
279
|
-
size_t current_length = RSTRING_LEN(string);
|
280
|
-
|
281
|
-
if (current_length < (offset + length)) {
|
282
|
-
rb_str_set_len(string, offset + length);
|
283
|
-
}
|
284
|
-
}
|
285
|
-
|
286
|
-
VALUE Event_Backend_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE offset, VALUE length) {
|
287
|
-
struct Event_Backend_URing *data = NULL;
|
288
|
-
TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
|
289
|
-
|
290
|
-
resize_to_capacity(buffer, NUM2SIZET(offset), NUM2SIZET(length));
|
291
|
-
|
292
|
-
int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
|
263
|
+
static
|
264
|
+
int io_read(struct Event_Backend_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length) {
|
293
265
|
struct io_uring_sqe *sqe = io_get_sqe(data);
|
294
266
|
assert(sqe);
|
295
267
|
|
296
268
|
struct iovec iovecs[1];
|
297
|
-
iovecs[0].iov_base =
|
298
|
-
iovecs[0].iov_len =
|
269
|
+
iovecs[0].iov_base = buffer;
|
270
|
+
iovecs[0].iov_len = length;
|
299
271
|
|
300
272
|
io_uring_prep_readv(sqe, descriptor, iovecs, 1, 0);
|
301
273
|
io_uring_sqe_set_data(sqe, (void*)fiber);
|
302
274
|
io_uring_submit(&data->ring);
|
303
275
|
|
304
|
-
|
305
|
-
|
306
|
-
int result = NUM2INT(Event_Backend_transfer(data->loop));
|
307
|
-
|
308
|
-
if (result < 0) {
|
309
|
-
rb_syserr_fail(-result, strerror(-result));
|
310
|
-
}
|
311
|
-
|
312
|
-
resize_to_fit(buffer, NUM2SIZET(offset), (size_t)result);
|
313
|
-
|
314
|
-
return INT2NUM(result);
|
276
|
+
return NUM2INT(Event_Backend_transfer(data->loop));
|
315
277
|
}
|
316
278
|
|
317
|
-
VALUE
|
279
|
+
VALUE Event_Backend_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE _buffer, VALUE _offset, VALUE _length) {
|
318
280
|
struct Event_Backend_URing *data = NULL;
|
319
281
|
TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
|
320
282
|
|
321
|
-
|
322
|
-
|
283
|
+
int descriptor = RB_NUM2INT(rb_funcall(io, id_fileno, 0));
|
284
|
+
|
285
|
+
size_t offset = NUM2SIZET(_offset);
|
286
|
+
size_t length = NUM2SIZET(_length);
|
287
|
+
|
288
|
+
size_t start = offset;
|
289
|
+
size_t total = 0;
|
290
|
+
|
291
|
+
while (length > 0) {
|
292
|
+
char *buffer = Event_Backend_resize_to_capacity(_buffer, offset, length);
|
293
|
+
int result = io_read(data, fiber, descriptor, buffer+offset, length);
|
294
|
+
|
295
|
+
if (result >= 0) {
|
296
|
+
offset += result;
|
297
|
+
length -= result;
|
298
|
+
total += result;
|
299
|
+
} else if (-result == EAGAIN || -result == EWOULDBLOCK) {
|
300
|
+
Event_Backend_URing_io_wait(self, fiber, io, RB_INT2NUM(READABLE));
|
301
|
+
} else {
|
302
|
+
rb_syserr_fail(-result, strerror(-result));
|
303
|
+
}
|
323
304
|
}
|
324
305
|
|
325
|
-
|
306
|
+
Event_Backend_resize_to_fit(_buffer, start, total);
|
307
|
+
|
308
|
+
return SIZET2NUM(total);
|
309
|
+
}
|
310
|
+
|
311
|
+
static
|
312
|
+
int io_write(struct Event_Backend_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length) {
|
326
313
|
struct io_uring_sqe *sqe = io_get_sqe(data);
|
314
|
+
assert(sqe);
|
327
315
|
|
328
316
|
struct iovec iovecs[1];
|
329
|
-
iovecs[0].iov_base =
|
330
|
-
iovecs[0].iov_len =
|
317
|
+
iovecs[0].iov_base = buffer;
|
318
|
+
iovecs[0].iov_len = length;
|
331
319
|
|
332
320
|
io_uring_prep_writev(sqe, descriptor, iovecs, 1, 0);
|
333
321
|
io_uring_sqe_set_data(sqe, (void*)fiber);
|
334
322
|
io_uring_submit(&data->ring);
|
335
323
|
|
336
|
-
|
324
|
+
return NUM2INT(Event_Backend_transfer(data->loop));
|
325
|
+
}
|
326
|
+
|
327
|
+
VALUE Event_Backend_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE _buffer, VALUE _offset, VALUE _length) {
|
328
|
+
struct Event_Backend_URing *data = NULL;
|
329
|
+
TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
|
330
|
+
|
331
|
+
int descriptor = RB_NUM2INT(rb_funcall(io, id_fileno, 0));
|
337
332
|
|
338
|
-
|
333
|
+
size_t offset = NUM2SIZET(_offset);
|
334
|
+
size_t length = NUM2SIZET(_length);
|
339
335
|
|
340
|
-
|
341
|
-
|
336
|
+
char *buffer = Event_Backend_verify_size(_buffer, offset, length);
|
337
|
+
|
338
|
+
size_t total = 0;
|
339
|
+
|
340
|
+
while (length > 0) {
|
341
|
+
int result = io_write(data, fiber, descriptor, buffer+offset, length);
|
342
|
+
|
343
|
+
if (result >= 0) {
|
344
|
+
length -= result;
|
345
|
+
offset += result;
|
346
|
+
total += result;
|
347
|
+
} else if (-result == EAGAIN || -result == EWOULDBLOCK) {
|
348
|
+
Event_Backend_URing_io_wait(self, fiber, io, RB_INT2NUM(WRITABLE));
|
349
|
+
} else {
|
350
|
+
rb_syserr_fail(-result, strerror(-result));
|
351
|
+
}
|
342
352
|
}
|
343
353
|
|
344
|
-
return
|
354
|
+
return SIZET2NUM(total);
|
345
355
|
}
|
346
356
|
|
347
357
|
static
|
@@ -477,12 +487,12 @@ void Init_Event_Backend_URing(VALUE Event_Backend) {
|
|
477
487
|
|
478
488
|
rb_define_alloc_func(Event_Backend_URing, Event_Backend_URing_allocate);
|
479
489
|
rb_define_method(Event_Backend_URing, "initialize", Event_Backend_URing_initialize, 1);
|
490
|
+
rb_define_method(Event_Backend_URing, "select", Event_Backend_URing_select, 1);
|
480
491
|
rb_define_method(Event_Backend_URing, "close", Event_Backend_URing_close, 0);
|
481
492
|
|
482
493
|
rb_define_method(Event_Backend_URing, "io_wait", Event_Backend_URing_io_wait, 3);
|
483
|
-
rb_define_method(Event_Backend_URing, "select", Event_Backend_URing_select, 1);
|
484
|
-
|
485
494
|
rb_define_method(Event_Backend_URing, "io_read", Event_Backend_URing_io_read, 5);
|
486
495
|
rb_define_method(Event_Backend_URing, "io_write", Event_Backend_URing_io_write, 5);
|
496
|
+
|
487
497
|
rb_define_method(Event_Backend_URing, "process_wait", Event_Backend_URing_process_wait, 3);
|
488
498
|
}
|
data/ext/event/event.bundle
CHANGED
Binary file
|
data/ext/event/extconf.rb
CHANGED
@@ -33,8 +33,7 @@ $CFLAGS << " -Wall"
|
|
33
33
|
$srcs = ["event.c", "backend/backend.c"]
|
34
34
|
$VPATH << "$(srcdir)/backend"
|
35
35
|
|
36
|
-
|
37
|
-
have_func('rb_fiber_transfer_kw')
|
36
|
+
have_func('&rb_fiber_transfer')
|
38
37
|
|
39
38
|
if have_library('uring') and have_header('liburing.h')
|
40
39
|
$srcs << "backend/uring.c"
|
data/ext/event/kqueue.o
CHANGED
Binary file
|
data/ext/event/mkmf.log
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
have_func: checking for
|
1
|
+
have_func: checking for &rb_fiber_transfer()... -------------------- no
|
2
2
|
|
3
3
|
"clang -fdeclspec -o conftest -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20 -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -pipe -Wall conftest.c -L. -L/Users/samuel/.rubies/ruby-3.0.1/lib -L/opt/local/lib -L. -fstack-protector-strong -L/opt/local/lib -lruby.3.0-static -framework Security -framework Foundation -lpthread -lgmp -ldl -lobjc "
|
4
4
|
checked program was:
|
@@ -12,9 +12,9 @@ checked program was:
|
|
12
12
|
/* end */
|
13
13
|
|
14
14
|
"clang -fdeclspec -o conftest -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20 -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -pipe -Wall conftest.c -L. -L/Users/samuel/.rubies/ruby-3.0.1/lib -L/opt/local/lib -L. -fstack-protector-strong -L/opt/local/lib -lruby.3.0-static -framework Security -framework Foundation -lpthread -lgmp -ldl -lobjc "
|
15
|
-
conftest.c:14:
|
16
|
-
int t(void) { void
|
17
|
-
|
15
|
+
conftest.c:14:76: error: use of undeclared identifier 'rb_fiber_transfer'
|
16
|
+
int t(void) { const volatile void *volatile p; p = (const volatile void *)&rb_fiber_transfer; return !p; }
|
17
|
+
^
|
18
18
|
1 error generated.
|
19
19
|
checked program was:
|
20
20
|
/* begin */
|
@@ -31,32 +31,7 @@ checked program was:
|
|
31
31
|
11:
|
32
32
|
12: return !!argv[argc];
|
33
33
|
13: }
|
34
|
-
14: int t(void) { void
|
35
|
-
/* end */
|
36
|
-
|
37
|
-
"clang -fdeclspec -o conftest -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/x86_64-darwin20 -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0/ruby/backward -I/Users/samuel/.rubies/ruby-3.0.1/include/ruby-3.0.0 -I. -I/opt/local/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdivision-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wmissing-noreturn -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wextra-tokens -pipe -Wall conftest.c -L. -L/Users/samuel/.rubies/ruby-3.0.1/lib -L/opt/local/lib -L. -fstack-protector-strong -L/opt/local/lib -lruby.3.0-static -framework Security -framework Foundation -lpthread -lgmp -ldl -lobjc "
|
38
|
-
Undefined symbols for architecture x86_64:
|
39
|
-
"_rb_fiber_transfer_kw", referenced from:
|
40
|
-
_t in conftest-3b7f21.o
|
41
|
-
ld: symbol(s) not found for architecture x86_64
|
42
|
-
clang: error: linker command failed with exit code 1 (use -v to see invocation)
|
43
|
-
checked program was:
|
44
|
-
/* begin */
|
45
|
-
1: #include "ruby.h"
|
46
|
-
2:
|
47
|
-
3: /*top*/
|
48
|
-
4: extern int t(void);
|
49
|
-
5: int main(int argc, char **argv)
|
50
|
-
6: {
|
51
|
-
7: if (argc > 1000000) {
|
52
|
-
8: int (* volatile tp)(void)=(int (*)(void))&t;
|
53
|
-
9: printf("%d", (*tp)());
|
54
|
-
10: }
|
55
|
-
11:
|
56
|
-
12: return !!argv[argc];
|
57
|
-
13: }
|
58
|
-
14: extern void rb_fiber_transfer_kw();
|
59
|
-
15: int t(void) { rb_fiber_transfer_kw(); return 0; }
|
34
|
+
14: int t(void) { const volatile void *volatile p; p = (const volatile void *)&rb_fiber_transfer; return !p; }
|
60
35
|
/* end */
|
61
36
|
|
62
37
|
--------------------
|
data/lib/event/backend/select.rb
CHANGED
@@ -52,7 +52,50 @@ module Event
|
|
52
52
|
@readable.delete(io) if remove_readable
|
53
53
|
@writable.delete(io) if remove_writable
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
|
+
def io_read(fiber, io, buffer, offset, length)
|
57
|
+
buffer.force_encoding(Encoding::BINARY)
|
58
|
+
|
59
|
+
while length > 0
|
60
|
+
case result = io.read_nonblock(length, exception: false)
|
61
|
+
when :wait_readable
|
62
|
+
self.io_wait(fiber, io, READABLE)
|
63
|
+
when :wait_writable
|
64
|
+
self.io_wait(fiber, io, WRITABLE)
|
65
|
+
else
|
66
|
+
result.force_encoding(Encoding::BINARY)
|
67
|
+
buffer[offset, result.bytesize] = result
|
68
|
+
|
69
|
+
offset += result.bytesize
|
70
|
+
length -= result.bytesize
|
71
|
+
end
|
72
|
+
end
|
73
|
+
rescue EOFError
|
74
|
+
return nil
|
75
|
+
end
|
76
|
+
|
77
|
+
def io_write(fiber, io, buffer, offset, length)
|
78
|
+
buffer.force_encoding(Encoding::BINARY)
|
79
|
+
|
80
|
+
total = 0
|
81
|
+
|
82
|
+
while length > 0
|
83
|
+
chunk = buffer[offset, length]
|
84
|
+
case result = io.write_nonblock(chunk, exception: false)
|
85
|
+
when :wait_readable
|
86
|
+
self.io_wait(fiber, io, READABLE)
|
87
|
+
when :wait_writable
|
88
|
+
self.io_wait(fiber, io, WRITABLE)
|
89
|
+
else
|
90
|
+
offset += result
|
91
|
+
length -= result
|
92
|
+
total += result
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
return total
|
97
|
+
end
|
98
|
+
|
56
99
|
def process_wait(fiber, pid, flags)
|
57
100
|
r, w = IO.pipe
|
58
101
|
|
data/lib/event/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: event
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bake
|