event 0.6.0 → 0.8.2
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/event.c +10 -10
- data/ext/event/event.h +3 -3
- data/ext/event/extconf.rb +11 -5
- data/ext/event/{backend → selector}/epoll.c +160 -106
- data/ext/event/{backend → selector}/epoll.h +2 -2
- data/ext/event/{backend → selector}/kqueue.c +160 -102
- data/ext/event/{backend → selector}/kqueue.h +2 -2
- data/ext/event/{backend → selector}/pidfd.c +0 -0
- data/ext/event/selector/selector.c +263 -0
- data/ext/event/selector/selector.h +127 -0
- data/ext/event/selector/uring.c +638 -0
- data/ext/event/{backend → selector}/uring.h +3 -3
- data/lib/event.rb +2 -1
- data/lib/event/debug.rb +126 -0
- data/lib/event/selector.rb +25 -2
- data/lib/event/{backend → selector}/select.rb +81 -36
- data/lib/event/version.rb +1 -1
- metadata +13 -21
- data/ext/event/Makefile +0 -267
- data/ext/event/backend.o +0 -0
- data/ext/event/backend/backend.c +0 -108
- data/ext/event/backend/backend.h +0 -45
- data/ext/event/backend/uring.c +0 -498
- data/ext/event/event.bundle +0 -0
- data/ext/event/event.o +0 -0
- data/ext/event/extconf.h +0 -4
- data/ext/event/kqueue.o +0 -0
- data/ext/event/mkmf.log +0 -100
- data/lib/event/backend.rb +0 -49
- data/lib/event/debug/selector.rb +0 -108
@@ -19,77 +19,76 @@
|
|
19
19
|
// THE SOFTWARE.
|
20
20
|
|
21
21
|
#include "kqueue.h"
|
22
|
-
#include "
|
22
|
+
#include "selector.h"
|
23
23
|
|
24
24
|
#include <sys/event.h>
|
25
25
|
#include <sys/ioctl.h>
|
26
26
|
#include <time.h>
|
27
27
|
#include <errno.h>
|
28
28
|
|
29
|
-
static VALUE
|
30
|
-
static ID id_fileno;
|
29
|
+
static VALUE Event_Selector_KQueue = Qnil;
|
31
30
|
|
32
31
|
enum {KQUEUE_MAX_EVENTS = 64};
|
33
32
|
|
34
|
-
struct
|
35
|
-
|
33
|
+
struct Event_Selector_KQueue {
|
34
|
+
struct Event_Selector backend;
|
36
35
|
int descriptor;
|
37
36
|
};
|
38
37
|
|
39
|
-
void
|
38
|
+
void Event_Selector_KQueue_Type_mark(void *_data)
|
40
39
|
{
|
41
|
-
struct
|
42
|
-
|
40
|
+
struct Event_Selector_KQueue *data = _data;
|
41
|
+
Event_Selector_mark(&data->backend);
|
43
42
|
}
|
44
43
|
|
45
44
|
static
|
46
|
-
void close_internal(struct
|
45
|
+
void close_internal(struct Event_Selector_KQueue *data) {
|
47
46
|
if (data->descriptor >= 0) {
|
48
47
|
close(data->descriptor);
|
49
48
|
data->descriptor = -1;
|
50
49
|
}
|
51
50
|
}
|
52
51
|
|
53
|
-
void
|
52
|
+
void Event_Selector_KQueue_Type_free(void *_data)
|
54
53
|
{
|
55
|
-
struct
|
54
|
+
struct Event_Selector_KQueue *data = _data;
|
56
55
|
|
57
56
|
close_internal(data);
|
58
57
|
|
59
58
|
free(data);
|
60
59
|
}
|
61
60
|
|
62
|
-
size_t
|
61
|
+
size_t Event_Selector_KQueue_Type_size(const void *data)
|
63
62
|
{
|
64
|
-
return sizeof(struct
|
63
|
+
return sizeof(struct Event_Selector_KQueue);
|
65
64
|
}
|
66
65
|
|
67
|
-
static const rb_data_type_t
|
66
|
+
static const rb_data_type_t Event_Selector_KQueue_Type = {
|
68
67
|
.wrap_struct_name = "Event::Backend::KQueue",
|
69
68
|
.function = {
|
70
|
-
.dmark =
|
71
|
-
.dfree =
|
72
|
-
.dsize =
|
69
|
+
.dmark = Event_Selector_KQueue_Type_mark,
|
70
|
+
.dfree = Event_Selector_KQueue_Type_free,
|
71
|
+
.dsize = Event_Selector_KQueue_Type_size,
|
73
72
|
},
|
74
73
|
.data = NULL,
|
75
74
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
76
75
|
};
|
77
76
|
|
78
|
-
VALUE
|
79
|
-
struct
|
80
|
-
VALUE instance = TypedData_Make_Struct(self, struct
|
77
|
+
VALUE Event_Selector_KQueue_allocate(VALUE self) {
|
78
|
+
struct Event_Selector_KQueue *data = NULL;
|
79
|
+
VALUE instance = TypedData_Make_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
81
80
|
|
82
|
-
data->
|
81
|
+
Event_Selector_initialize(&data->backend, Qnil);
|
83
82
|
data->descriptor = -1;
|
84
83
|
|
85
84
|
return instance;
|
86
85
|
}
|
87
86
|
|
88
|
-
VALUE
|
89
|
-
struct
|
90
|
-
TypedData_Get_Struct(self, struct
|
87
|
+
VALUE Event_Selector_KQueue_initialize(VALUE self, VALUE loop) {
|
88
|
+
struct Event_Selector_KQueue *data = NULL;
|
89
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
91
90
|
|
92
|
-
data->
|
91
|
+
Event_Selector_initialize(&data->backend, loop);
|
93
92
|
int result = kqueue();
|
94
93
|
|
95
94
|
if (result == -1) {
|
@@ -104,17 +103,60 @@ VALUE Event_Backend_KQueue_initialize(VALUE self, VALUE loop) {
|
|
104
103
|
return self;
|
105
104
|
}
|
106
105
|
|
107
|
-
VALUE
|
108
|
-
struct
|
109
|
-
TypedData_Get_Struct(self, struct
|
106
|
+
VALUE Event_Selector_KQueue_close(VALUE self) {
|
107
|
+
struct Event_Selector_KQueue *data = NULL;
|
108
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
110
109
|
|
111
110
|
close_internal(data);
|
112
111
|
|
113
112
|
return Qnil;
|
114
113
|
}
|
115
114
|
|
115
|
+
VALUE Event_Selector_KQueue_transfer(int argc, VALUE *argv, VALUE self)
|
116
|
+
{
|
117
|
+
struct Event_Selector_KQueue *data = NULL;
|
118
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
119
|
+
|
120
|
+
return Event_Selector_wait_and_transfer(&data->backend, argc, argv);
|
121
|
+
}
|
122
|
+
|
123
|
+
VALUE Event_Selector_KQueue_yield(VALUE self)
|
124
|
+
{
|
125
|
+
struct Event_Selector_KQueue *data = NULL;
|
126
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
127
|
+
|
128
|
+
Event_Selector_yield(&data->backend);
|
129
|
+
|
130
|
+
return Qnil;
|
131
|
+
}
|
132
|
+
|
133
|
+
VALUE Event_Selector_KQueue_push(VALUE self, VALUE fiber)
|
134
|
+
{
|
135
|
+
struct Event_Selector_KQueue *data = NULL;
|
136
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
137
|
+
|
138
|
+
Event_Selector_queue_push(&data->backend, fiber);
|
139
|
+
|
140
|
+
return Qnil;
|
141
|
+
}
|
142
|
+
|
143
|
+
VALUE Event_Selector_KQueue_raise(int argc, VALUE *argv, VALUE self)
|
144
|
+
{
|
145
|
+
struct Event_Selector_KQueue *data = NULL;
|
146
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
147
|
+
|
148
|
+
return Event_Selector_wait_and_raise(&data->backend, argc, argv);
|
149
|
+
}
|
150
|
+
|
151
|
+
VALUE Event_Selector_KQueue_ready_p(VALUE self) {
|
152
|
+
struct Event_Selector_KQueue *data = NULL;
|
153
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
154
|
+
|
155
|
+
return data->backend.ready ? Qtrue : Qfalse;
|
156
|
+
}
|
157
|
+
|
116
158
|
struct process_wait_arguments {
|
117
|
-
struct
|
159
|
+
struct Event_Selector_KQueue *data;
|
118
160
|
pid_t pid;
|
119
161
|
int flags;
|
120
162
|
};
|
@@ -160,9 +202,9 @@ static
|
|
160
202
|
VALUE process_wait_transfer(VALUE _arguments) {
|
161
203
|
struct process_wait_arguments *arguments = (struct process_wait_arguments *)_arguments;
|
162
204
|
|
163
|
-
|
205
|
+
Event_Selector_fiber_transfer(arguments->data->backend.loop, 0, NULL);
|
164
206
|
|
165
|
-
return
|
207
|
+
return Event_Selector_process_status_wait(arguments->pid);
|
166
208
|
}
|
167
209
|
|
168
210
|
static
|
@@ -174,9 +216,9 @@ VALUE process_wait_rescue(VALUE _arguments, VALUE exception) {
|
|
174
216
|
rb_exc_raise(exception);
|
175
217
|
}
|
176
218
|
|
177
|
-
VALUE
|
178
|
-
struct
|
179
|
-
TypedData_Get_Struct(self, struct
|
219
|
+
VALUE Event_Selector_KQueue_process_wait(VALUE self, VALUE fiber, VALUE pid, VALUE flags) {
|
220
|
+
struct Event_Selector_KQueue *data = NULL;
|
221
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
180
222
|
|
181
223
|
struct process_wait_arguments process_wait_arguments = {
|
182
224
|
.data = data,
|
@@ -189,7 +231,7 @@ VALUE Event_Backend_KQueue_process_wait(VALUE self, VALUE fiber, VALUE pid, VALU
|
|
189
231
|
if (waiting) {
|
190
232
|
return rb_rescue(process_wait_transfer, (VALUE)&process_wait_arguments, process_wait_rescue, (VALUE)&process_wait_arguments);
|
191
233
|
} else {
|
192
|
-
return
|
234
|
+
return Event_Selector_process_status_wait(process_wait_arguments.pid);
|
193
235
|
}
|
194
236
|
}
|
195
237
|
|
@@ -198,7 +240,7 @@ int io_add_filters(int descriptor, int ident, int events, VALUE fiber) {
|
|
198
240
|
int count = 0;
|
199
241
|
struct kevent kevents[2] = {0};
|
200
242
|
|
201
|
-
if (events &
|
243
|
+
if (events & EVENT_READABLE) {
|
202
244
|
kevents[count].ident = ident;
|
203
245
|
kevents[count].filter = EVFILT_READ;
|
204
246
|
kevents[count].flags = EV_ADD | EV_ENABLE | EV_ONESHOT;
|
@@ -213,7 +255,7 @@ int io_add_filters(int descriptor, int ident, int events, VALUE fiber) {
|
|
213
255
|
count++;
|
214
256
|
}
|
215
257
|
|
216
|
-
if (events &
|
258
|
+
if (events & EVENT_WRITABLE) {
|
217
259
|
kevents[count].ident = ident;
|
218
260
|
kevents[count].filter = EVFILT_WRITE;
|
219
261
|
kevents[count].flags = EV_ADD | EV_ENABLE | EV_ONESHOT;
|
@@ -235,7 +277,7 @@ void io_remove_filters(int descriptor, int ident, int events) {
|
|
235
277
|
int count = 0;
|
236
278
|
struct kevent kevents[2] = {0};
|
237
279
|
|
238
|
-
if (events &
|
280
|
+
if (events & EVENT_READABLE) {
|
239
281
|
kevents[count].ident = ident;
|
240
282
|
kevents[count].filter = EVFILT_READ;
|
241
283
|
kevents[count].flags = EV_DELETE;
|
@@ -243,7 +285,7 @@ void io_remove_filters(int descriptor, int ident, int events) {
|
|
243
285
|
count++;
|
244
286
|
}
|
245
287
|
|
246
|
-
if (events &
|
288
|
+
if (events & EVENT_WRITABLE) {
|
247
289
|
kevents[count].ident = ident;
|
248
290
|
kevents[count].filter = EVFILT_WRITE;
|
249
291
|
kevents[count].flags = EV_DELETE;
|
@@ -255,7 +297,7 @@ void io_remove_filters(int descriptor, int ident, int events) {
|
|
255
297
|
}
|
256
298
|
|
257
299
|
struct io_wait_arguments {
|
258
|
-
struct
|
300
|
+
struct Event_Selector_KQueue *data;
|
259
301
|
int events;
|
260
302
|
int descriptor;
|
261
303
|
};
|
@@ -271,8 +313,8 @@ VALUE io_wait_rescue(VALUE _arguments, VALUE exception) {
|
|
271
313
|
|
272
314
|
static inline
|
273
315
|
int events_from_kqueue_filter(int filter) {
|
274
|
-
if (filter == EVFILT_READ) return
|
275
|
-
if (filter == EVFILT_WRITE) return
|
316
|
+
if (filter == EVFILT_READ) return EVENT_READABLE;
|
317
|
+
if (filter == EVFILT_WRITE) return EVENT_WRITABLE;
|
276
318
|
|
277
319
|
return 0;
|
278
320
|
}
|
@@ -281,16 +323,16 @@ static
|
|
281
323
|
VALUE io_wait_transfer(VALUE _arguments) {
|
282
324
|
struct io_wait_arguments *arguments = (struct io_wait_arguments *)_arguments;
|
283
325
|
|
284
|
-
VALUE result =
|
326
|
+
VALUE result = Event_Selector_fiber_transfer(arguments->data->backend.loop, 0, NULL);
|
285
327
|
|
286
328
|
return INT2NUM(events_from_kqueue_filter(RB_NUM2INT(result)));
|
287
329
|
}
|
288
330
|
|
289
|
-
VALUE
|
290
|
-
struct
|
291
|
-
TypedData_Get_Struct(self, struct
|
331
|
+
VALUE Event_Selector_KQueue_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE events) {
|
332
|
+
struct Event_Selector_KQueue *data = NULL;
|
333
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
292
334
|
|
293
|
-
int descriptor =
|
335
|
+
int descriptor = Event_Selector_io_descriptor(io);
|
294
336
|
|
295
337
|
struct io_wait_arguments io_wait_arguments = {
|
296
338
|
.events = io_add_filters(data->descriptor, descriptor, RB_NUM2INT(events), fiber),
|
@@ -301,6 +343,8 @@ VALUE Event_Backend_KQueue_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE even
|
|
301
343
|
return rb_rescue(io_wait_transfer, (VALUE)&io_wait_arguments, io_wait_rescue, (VALUE)&io_wait_arguments);
|
302
344
|
}
|
303
345
|
|
346
|
+
#ifdef HAVE_RUBY_IO_BUFFER_H
|
347
|
+
|
304
348
|
struct io_read_arguments {
|
305
349
|
VALUE self;
|
306
350
|
VALUE fiber;
|
@@ -311,7 +355,6 @@ struct io_read_arguments {
|
|
311
355
|
int descriptor;
|
312
356
|
|
313
357
|
VALUE buffer;
|
314
|
-
size_t offset;
|
315
358
|
size_t length;
|
316
359
|
};
|
317
360
|
|
@@ -319,46 +362,47 @@ static
|
|
319
362
|
VALUE io_read_loop(VALUE _arguments) {
|
320
363
|
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
321
364
|
|
322
|
-
|
365
|
+
void *base;
|
366
|
+
size_t size;
|
367
|
+
rb_io_buffer_get_mutable(arguments->buffer, &base, &size);
|
368
|
+
|
369
|
+
size_t offset = 0;
|
323
370
|
size_t length = arguments->length;
|
324
|
-
size_t total = 0;
|
325
371
|
|
326
372
|
while (length > 0) {
|
327
|
-
|
328
|
-
ssize_t result = read(arguments->descriptor,
|
373
|
+
size_t maximum_size = size - offset;
|
374
|
+
ssize_t result = read(arguments->descriptor, (char*)base+offset, maximum_size);
|
329
375
|
|
330
|
-
if (result
|
376
|
+
if (result == 0) {
|
377
|
+
break;
|
378
|
+
} else if (result > 0) {
|
331
379
|
offset += result;
|
332
380
|
length -= result;
|
333
|
-
total += result;
|
334
381
|
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
335
|
-
|
382
|
+
Event_Selector_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(READABLE));
|
336
383
|
} else {
|
337
|
-
rb_sys_fail("
|
384
|
+
rb_sys_fail("Event_Selector_KQueue_io_read");
|
338
385
|
}
|
339
386
|
}
|
340
387
|
|
341
|
-
|
342
|
-
|
343
|
-
return SIZET2NUM(total);
|
388
|
+
return SIZET2NUM(offset);
|
344
389
|
}
|
345
390
|
|
346
391
|
static
|
347
392
|
VALUE io_read_ensure(VALUE _arguments) {
|
348
393
|
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
349
394
|
|
350
|
-
|
395
|
+
Event_Selector_nonblock_restore(arguments->descriptor, arguments->flags);
|
351
396
|
|
352
397
|
return Qnil;
|
353
398
|
}
|
354
399
|
|
355
|
-
VALUE
|
356
|
-
struct
|
357
|
-
TypedData_Get_Struct(self, struct
|
400
|
+
VALUE Event_Selector_KQueue_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length) {
|
401
|
+
struct Event_Selector_KQueue *data = NULL;
|
402
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
358
403
|
|
359
|
-
int descriptor =
|
404
|
+
int descriptor = Event_Selector_io_descriptor(io);
|
360
405
|
|
361
|
-
size_t offset = NUM2SIZET(_offset);
|
362
406
|
size_t length = NUM2SIZET(_length);
|
363
407
|
|
364
408
|
struct io_read_arguments io_read_arguments = {
|
@@ -366,10 +410,9 @@ VALUE Event_Backend_KQueue_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buff
|
|
366
410
|
.fiber = fiber,
|
367
411
|
.io = io,
|
368
412
|
|
369
|
-
.flags =
|
413
|
+
.flags = Event_Selector_nonblock_set(descriptor),
|
370
414
|
.descriptor = descriptor,
|
371
415
|
.buffer = buffer,
|
372
|
-
.offset = offset,
|
373
416
|
.length = length,
|
374
417
|
};
|
375
418
|
|
@@ -386,7 +429,6 @@ struct io_write_arguments {
|
|
386
429
|
int descriptor;
|
387
430
|
|
388
431
|
VALUE buffer;
|
389
|
-
size_t offset;
|
390
432
|
size_t length;
|
391
433
|
};
|
392
434
|
|
@@ -394,44 +436,48 @@ static
|
|
394
436
|
VALUE io_write_loop(VALUE _arguments) {
|
395
437
|
struct io_write_arguments *arguments = (struct io_write_arguments *)_arguments;
|
396
438
|
|
397
|
-
|
439
|
+
const void *base;
|
440
|
+
size_t size;
|
441
|
+
rb_io_buffer_get_immutable(arguments->buffer, &base, &size);
|
442
|
+
|
443
|
+
size_t offset = 0;
|
398
444
|
size_t length = arguments->length;
|
399
|
-
|
445
|
+
|
446
|
+
if (length > size) {
|
447
|
+
rb_raise(rb_eRuntimeError, "Length exceeds size of buffer!");
|
448
|
+
}
|
400
449
|
|
401
450
|
while (length > 0) {
|
402
|
-
|
403
|
-
ssize_t result = write(arguments->descriptor, buffer+offset, length);
|
451
|
+
ssize_t result = write(arguments->descriptor, (char*)base+offset, length);
|
404
452
|
|
405
453
|
if (result >= 0) {
|
406
|
-
length -= result;
|
407
454
|
offset += result;
|
408
|
-
|
455
|
+
length -= result;
|
409
456
|
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
410
|
-
|
457
|
+
Event_Selector_KQueue_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(WRITABLE));
|
411
458
|
} else {
|
412
|
-
rb_sys_fail("
|
459
|
+
rb_sys_fail("Event_Selector_KQueue_io_write");
|
413
460
|
}
|
414
461
|
}
|
415
462
|
|
416
|
-
return SIZET2NUM(
|
463
|
+
return SIZET2NUM(offset);
|
417
464
|
};
|
418
465
|
|
419
466
|
static
|
420
467
|
VALUE io_write_ensure(VALUE _arguments) {
|
421
468
|
struct io_write_arguments *arguments = (struct io_write_arguments *)_arguments;
|
422
469
|
|
423
|
-
|
470
|
+
Event_Selector_nonblock_restore(arguments->descriptor, arguments->flags);
|
424
471
|
|
425
472
|
return Qnil;
|
426
473
|
};
|
427
474
|
|
428
|
-
VALUE
|
429
|
-
struct
|
430
|
-
TypedData_Get_Struct(self, struct
|
475
|
+
VALUE Event_Selector_KQueue_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length) {
|
476
|
+
struct Event_Selector_KQueue *data = NULL;
|
477
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
431
478
|
|
432
|
-
int descriptor =
|
479
|
+
int descriptor = Event_Selector_io_descriptor(io);
|
433
480
|
|
434
|
-
size_t offset = NUM2SIZET(_offset);
|
435
481
|
size_t length = NUM2SIZET(_length);
|
436
482
|
|
437
483
|
struct io_write_arguments io_write_arguments = {
|
@@ -439,16 +485,17 @@ VALUE Event_Backend_KQueue_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buf
|
|
439
485
|
.fiber = fiber,
|
440
486
|
.io = io,
|
441
487
|
|
442
|
-
.flags =
|
488
|
+
.flags = Event_Selector_nonblock_set(descriptor),
|
443
489
|
.descriptor = descriptor,
|
444
490
|
.buffer = buffer,
|
445
|
-
.offset = offset,
|
446
491
|
.length = length,
|
447
492
|
};
|
448
493
|
|
449
494
|
return rb_ensure(io_write_loop, (VALUE)&io_write_arguments, io_write_ensure, (VALUE)&io_write_arguments);
|
450
495
|
}
|
451
496
|
|
497
|
+
#endif
|
498
|
+
|
452
499
|
static
|
453
500
|
struct timespec * make_timeout(VALUE duration, struct timespec * storage) {
|
454
501
|
if (duration == Qnil) {
|
@@ -481,7 +528,7 @@ int timeout_nonblocking(struct timespec * timespec) {
|
|
481
528
|
}
|
482
529
|
|
483
530
|
struct select_arguments {
|
484
|
-
struct
|
531
|
+
struct Event_Selector_KQueue *data;
|
485
532
|
|
486
533
|
int count;
|
487
534
|
struct kevent events[KQUEUE_MAX_EVENTS];
|
@@ -517,9 +564,11 @@ void select_internal_with_gvl(struct select_arguments *arguments) {
|
|
517
564
|
}
|
518
565
|
}
|
519
566
|
|
520
|
-
VALUE
|
521
|
-
struct
|
522
|
-
TypedData_Get_Struct(self, struct
|
567
|
+
VALUE Event_Selector_KQueue_select(VALUE self, VALUE duration) {
|
568
|
+
struct Event_Selector_KQueue *data = NULL;
|
569
|
+
TypedData_Get_Struct(self, struct Event_Selector_KQueue, &Event_Selector_KQueue_Type, data);
|
570
|
+
|
571
|
+
int ready = Event_Selector_queue_flush(&data->backend);
|
523
572
|
|
524
573
|
struct select_arguments arguments = {
|
525
574
|
.data = data,
|
@@ -541,7 +590,7 @@ VALUE Event_Backend_KQueue_select(VALUE self, VALUE duration) {
|
|
541
590
|
select_internal_with_gvl(&arguments);
|
542
591
|
|
543
592
|
// If there were no pending events, if we have a timeout, wait for more events:
|
544
|
-
if (arguments.count == 0) {
|
593
|
+
if (!ready && arguments.count == 0) {
|
545
594
|
arguments.timeout = make_timeout(duration, &arguments.storage);
|
546
595
|
|
547
596
|
if (!timeout_nonblocking(arguments.timeout)) {
|
@@ -555,25 +604,34 @@ VALUE Event_Backend_KQueue_select(VALUE self, VALUE duration) {
|
|
555
604
|
VALUE fiber = (VALUE)arguments.events[i].udata;
|
556
605
|
VALUE result = INT2NUM(arguments.events[i].filter);
|
557
606
|
|
558
|
-
|
607
|
+
Event_Selector_fiber_transfer(fiber, 1, &result);
|
559
608
|
}
|
560
609
|
|
561
610
|
return INT2NUM(arguments.count);
|
562
611
|
}
|
563
612
|
|
564
|
-
void
|
565
|
-
|
613
|
+
void Init_Event_Selector_KQueue(VALUE Event_Selector) {
|
614
|
+
Event_Selector_KQueue = rb_define_class_under(Event_Selector, "KQueue", rb_cObject);
|
615
|
+
|
616
|
+
rb_define_alloc_func(Event_Selector_KQueue, Event_Selector_KQueue_allocate);
|
617
|
+
rb_define_method(Event_Selector_KQueue, "initialize", Event_Selector_KQueue_initialize, 1);
|
618
|
+
|
619
|
+
rb_define_method(Event_Selector_KQueue, "transfer", Event_Selector_KQueue_transfer, -1);
|
620
|
+
rb_define_method(Event_Selector_KQueue, "yield", Event_Selector_KQueue_yield, 0);
|
621
|
+
rb_define_method(Event_Selector_KQueue, "push", Event_Selector_KQueue_push, 1);
|
622
|
+
rb_define_method(Event_Selector_KQueue, "raise", Event_Selector_KQueue_raise, -1);
|
623
|
+
|
624
|
+
rb_define_method(Event_Selector_KQueue, "ready?", Event_Selector_KQueue_ready_p, 0);
|
566
625
|
|
567
|
-
|
626
|
+
rb_define_method(Event_Selector_KQueue, "select", Event_Selector_KQueue_select, 1);
|
627
|
+
rb_define_method(Event_Selector_KQueue, "close", Event_Selector_KQueue_close, 0);
|
568
628
|
|
569
|
-
|
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);
|
572
|
-
rb_define_method(Event_Backend_KQueue, "close", Event_Backend_KQueue_close, 0);
|
629
|
+
rb_define_method(Event_Selector_KQueue, "io_wait", Event_Selector_KQueue_io_wait, 3);
|
573
630
|
|
574
|
-
|
575
|
-
rb_define_method(
|
576
|
-
rb_define_method(
|
631
|
+
#ifdef HAVE_RUBY_IO_BUFFER_H
|
632
|
+
rb_define_method(Event_Selector_KQueue, "io_read", Event_Selector_KQueue_io_read, 4);
|
633
|
+
rb_define_method(Event_Selector_KQueue, "io_write", Event_Selector_KQueue_io_write, 4);
|
634
|
+
#endif
|
577
635
|
|
578
|
-
rb_define_method(
|
636
|
+
rb_define_method(Event_Selector_KQueue, "process_wait", Event_Selector_KQueue_process_wait, 3);
|
579
637
|
}
|