event 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|