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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62bded3e0e8e8929ef5f76b427a975f1444c215d3566423e17b6aecdcbbb1f0b
|
4
|
+
data.tar.gz: 6c241f562c00af271443406efa52c935f84fb6b30023b4c7086a8c4ee5b7b965
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75b5af033d60eb53df18b9b6fe9805827ccd4bfef0f4e26943428ddb4aee43006ce4eb12897102d33d50b31834c7bbd0be70821f2bcd6fe30cab5a657839321a
|
7
|
+
data.tar.gz: 57d719b1318c0740c58df4476ffb44719c8ded66d78889eeb60e15aead7d86e9778ad464a460dda4a2318f3435450e43778873aac8ea7a9c0150c37f828b4646
|
data/ext/event/event.c
CHANGED
@@ -19,10 +19,10 @@
|
|
19
19
|
// THE SOFTWARE.
|
20
20
|
|
21
21
|
#include "event.h"
|
22
|
-
#include "
|
22
|
+
#include "selector/selector.h"
|
23
23
|
|
24
24
|
VALUE Event = Qnil;
|
25
|
-
VALUE
|
25
|
+
VALUE Event_Selector = Qnil;
|
26
26
|
|
27
27
|
void Init_event()
|
28
28
|
{
|
@@ -31,19 +31,19 @@ void Init_event()
|
|
31
31
|
#endif
|
32
32
|
|
33
33
|
Event = rb_define_module("Event");
|
34
|
-
|
34
|
+
Event_Selector = rb_define_module_under(Event, "Selector");
|
35
35
|
|
36
|
-
|
36
|
+
Init_Event_Selector(Event_Selector);
|
37
37
|
|
38
|
-
#ifdef
|
39
|
-
|
38
|
+
#ifdef EVENT_SELECTOR_URING
|
39
|
+
Init_Event_Selector_URing(Event_Selector);
|
40
40
|
#endif
|
41
41
|
|
42
|
-
#ifdef
|
43
|
-
|
42
|
+
#ifdef EVENT_SELECTOR_EPOLL
|
43
|
+
Init_Event_Selector_EPoll(Event_Selector);
|
44
44
|
#endif
|
45
45
|
|
46
|
-
#ifdef
|
47
|
-
|
46
|
+
#ifdef EVENT_SELECTOR_KQUEUE
|
47
|
+
Init_Event_Selector_KQueue(Event_Selector);
|
48
48
|
#endif
|
49
49
|
}
|
data/ext/event/event.h
CHANGED
@@ -27,13 +27,13 @@
|
|
27
27
|
void Init_event();
|
28
28
|
|
29
29
|
#ifdef HAVE_LIBURING_H
|
30
|
-
#include "
|
30
|
+
#include "selector/uring.h"
|
31
31
|
#endif
|
32
32
|
|
33
33
|
#ifdef HAVE_SYS_EPOLL_H
|
34
|
-
#include "
|
34
|
+
#include "selector/epoll.h"
|
35
35
|
#endif
|
36
36
|
|
37
37
|
#ifdef HAVE_SYS_EVENT_H
|
38
|
-
#include "
|
38
|
+
#include "selector/kqueue.h"
|
39
39
|
#endif
|
data/ext/event/extconf.rb
CHANGED
@@ -30,23 +30,29 @@ dir_config(extension_name)
|
|
30
30
|
|
31
31
|
$CFLAGS << " -Wall"
|
32
32
|
|
33
|
-
$srcs = ["event.c", "
|
34
|
-
$VPATH << "$(srcdir)/
|
33
|
+
$srcs = ["event.c", "selector/selector.c"]
|
34
|
+
$VPATH << "$(srcdir)/selector"
|
35
35
|
|
36
36
|
have_func('&rb_fiber_transfer')
|
37
37
|
|
38
38
|
if have_library('uring') and have_header('liburing.h')
|
39
|
-
$srcs << "
|
39
|
+
$srcs << "selector/uring.c"
|
40
40
|
end
|
41
41
|
|
42
42
|
if have_header('sys/epoll.h')
|
43
|
-
$srcs << "
|
43
|
+
$srcs << "selector/epoll.c"
|
44
44
|
end
|
45
45
|
|
46
46
|
if have_header('sys/event.h')
|
47
|
-
$srcs << "
|
47
|
+
$srcs << "selector/kqueue.c"
|
48
48
|
end
|
49
49
|
|
50
|
+
have_func("rb_io_descriptor")
|
51
|
+
have_func("&rb_process_status_wait")
|
52
|
+
have_func("&rb_fiber_raise")
|
53
|
+
|
54
|
+
have_header('ruby/io/buffer.h')
|
55
|
+
|
50
56
|
create_header
|
51
57
|
|
52
58
|
# Generate the makefile to compile the native binary into `lib`:
|
@@ -19,7 +19,7 @@
|
|
19
19
|
// THE SOFTWARE.
|
20
20
|
|
21
21
|
#include "kqueue.h"
|
22
|
-
#include "
|
22
|
+
#include "selector.h"
|
23
23
|
|
24
24
|
#include <sys/epoll.h>
|
25
25
|
#include <time.h>
|
@@ -27,70 +27,69 @@
|
|
27
27
|
|
28
28
|
#include "pidfd.c"
|
29
29
|
|
30
|
-
static VALUE
|
31
|
-
static ID id_fileno;
|
30
|
+
static VALUE Event_Selector_EPoll = Qnil;
|
32
31
|
|
33
32
|
enum {EPOLL_MAX_EVENTS = 64};
|
34
33
|
|
35
|
-
struct
|
36
|
-
|
34
|
+
struct Event_Selector_EPoll {
|
35
|
+
struct Event_Selector backend;
|
37
36
|
int descriptor;
|
38
37
|
};
|
39
38
|
|
40
|
-
void
|
39
|
+
void Event_Selector_EPoll_Type_mark(void *_data)
|
41
40
|
{
|
42
|
-
struct
|
43
|
-
|
41
|
+
struct Event_Selector_EPoll *data = _data;
|
42
|
+
Event_Selector_mark(&data->backend);
|
44
43
|
}
|
45
44
|
|
46
45
|
static
|
47
|
-
void close_internal(struct
|
46
|
+
void close_internal(struct Event_Selector_EPoll *data) {
|
48
47
|
if (data->descriptor >= 0) {
|
49
48
|
close(data->descriptor);
|
50
49
|
data->descriptor = -1;
|
51
50
|
}
|
52
51
|
}
|
53
52
|
|
54
|
-
void
|
53
|
+
void Event_Selector_EPoll_Type_free(void *_data)
|
55
54
|
{
|
56
|
-
struct
|
55
|
+
struct Event_Selector_EPoll *data = _data;
|
57
56
|
|
58
57
|
close_internal(data);
|
59
58
|
|
60
59
|
free(data);
|
61
60
|
}
|
62
61
|
|
63
|
-
size_t
|
62
|
+
size_t Event_Selector_EPoll_Type_size(const void *data)
|
64
63
|
{
|
65
|
-
return sizeof(struct
|
64
|
+
return sizeof(struct Event_Selector_EPoll);
|
66
65
|
}
|
67
66
|
|
68
|
-
static const rb_data_type_t
|
67
|
+
static const rb_data_type_t Event_Selector_EPoll_Type = {
|
69
68
|
.wrap_struct_name = "Event::Backend::EPoll",
|
70
69
|
.function = {
|
71
|
-
.dmark =
|
72
|
-
.dfree =
|
73
|
-
.dsize =
|
70
|
+
.dmark = Event_Selector_EPoll_Type_mark,
|
71
|
+
.dfree = Event_Selector_EPoll_Type_free,
|
72
|
+
.dsize = Event_Selector_EPoll_Type_size,
|
74
73
|
},
|
75
74
|
.data = NULL,
|
76
75
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
77
76
|
};
|
78
77
|
|
79
|
-
VALUE
|
80
|
-
struct
|
81
|
-
VALUE instance = TypedData_Make_Struct(self, struct
|
78
|
+
VALUE Event_Selector_EPoll_allocate(VALUE self) {
|
79
|
+
struct Event_Selector_EPoll *data = NULL;
|
80
|
+
VALUE instance = TypedData_Make_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
82
81
|
|
83
|
-
data->
|
82
|
+
Event_Selector_initialize(&data->backend, Qnil);
|
84
83
|
data->descriptor = -1;
|
85
84
|
|
86
85
|
return instance;
|
87
86
|
}
|
88
87
|
|
89
|
-
VALUE
|
90
|
-
struct
|
91
|
-
TypedData_Get_Struct(self, struct
|
88
|
+
VALUE Event_Selector_EPoll_initialize(VALUE self, VALUE loop) {
|
89
|
+
struct Event_Selector_EPoll *data = NULL;
|
90
|
+
TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
92
91
|
|
93
|
-
data->
|
92
|
+
Event_Selector_initialize(&data->backend, loop);
|
94
93
|
int result = epoll_create1(EPOLL_CLOEXEC);
|
95
94
|
|
96
95
|
if (result == -1) {
|
@@ -104,17 +103,62 @@ VALUE Event_Backend_EPoll_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_EPoll_close(VALUE self) {
|
107
|
+
struct Event_Selector_EPoll *data = NULL;
|
108
|
+
TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
110
109
|
|
111
110
|
close_internal(data);
|
112
111
|
|
113
112
|
return Qnil;
|
114
113
|
}
|
115
114
|
|
115
|
+
VALUE Event_Selector_EPoll_transfer(int argc, VALUE *argv, VALUE self)
|
116
|
+
{
|
117
|
+
struct Event_Selector_EPoll *data = NULL;
|
118
|
+
TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
119
|
+
|
120
|
+
Event_Selector_wait_and_transfer(&data->backend, argc, argv);
|
121
|
+
|
122
|
+
return Qnil;
|
123
|
+
}
|
124
|
+
|
125
|
+
VALUE Event_Selector_EPoll_yield(VALUE self)
|
126
|
+
{
|
127
|
+
struct Event_Selector_EPoll *data = NULL;
|
128
|
+
TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
129
|
+
|
130
|
+
Event_Selector_yield(&data->backend);
|
131
|
+
|
132
|
+
return Qnil;
|
133
|
+
}
|
134
|
+
|
135
|
+
VALUE Event_Selector_EPoll_push(VALUE self, VALUE fiber)
|
136
|
+
{
|
137
|
+
struct Event_Selector_EPoll *data = NULL;
|
138
|
+
TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
139
|
+
|
140
|
+
Event_Selector_queue_push(&data->backend, fiber);
|
141
|
+
|
142
|
+
return Qnil;
|
143
|
+
}
|
144
|
+
|
145
|
+
VALUE Event_Selector_EPoll_raise(int argc, VALUE *argv, VALUE self)
|
146
|
+
{
|
147
|
+
struct Event_Selector_EPoll *data = NULL;
|
148
|
+
TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
149
|
+
|
150
|
+
return Event_Selector_wait_and_raise(&data->backend, argc, argv);
|
151
|
+
}
|
152
|
+
|
153
|
+
VALUE Event_Selector_EPoll_ready_p(VALUE self) {
|
154
|
+
struct Event_Selector_EPoll *data = NULL;
|
155
|
+
TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
156
|
+
|
157
|
+
return data->backend.ready ? Qtrue : Qfalse;
|
158
|
+
}
|
159
|
+
|
116
160
|
struct process_wait_arguments {
|
117
|
-
struct
|
161
|
+
struct Event_Selector_EPoll *data;
|
118
162
|
pid_t pid;
|
119
163
|
int flags;
|
120
164
|
int descriptor;
|
@@ -124,9 +168,9 @@ static
|
|
124
168
|
VALUE process_wait_transfer(VALUE _arguments) {
|
125
169
|
struct process_wait_arguments *arguments = (struct process_wait_arguments *)_arguments;
|
126
170
|
|
127
|
-
|
171
|
+
Event_Selector_fiber_transfer(arguments->data->backend.loop, 0, NULL);
|
128
172
|
|
129
|
-
return
|
173
|
+
return Event_Selector_process_status_wait(arguments->pid);
|
130
174
|
}
|
131
175
|
|
132
176
|
static
|
@@ -140,10 +184,10 @@ VALUE process_wait_ensure(VALUE _arguments) {
|
|
140
184
|
return Qnil;
|
141
185
|
}
|
142
186
|
|
143
|
-
VALUE
|
144
|
-
struct
|
145
|
-
TypedData_Get_Struct(self, struct
|
146
|
-
|
187
|
+
VALUE Event_Selector_EPoll_process_wait(VALUE self, VALUE fiber, VALUE pid, VALUE flags) {
|
188
|
+
struct Event_Selector_EPoll *data = NULL;
|
189
|
+
TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
190
|
+
|
147
191
|
struct process_wait_arguments process_wait_arguments = {
|
148
192
|
.data = data,
|
149
193
|
.pid = NUM2PIDT(pid),
|
@@ -171,9 +215,9 @@ static inline
|
|
171
215
|
uint32_t epoll_flags_from_events(int events) {
|
172
216
|
uint32_t flags = 0;
|
173
217
|
|
174
|
-
if (events &
|
175
|
-
if (events &
|
176
|
-
if (events &
|
218
|
+
if (events & EVENT_READABLE) flags |= EPOLLIN;
|
219
|
+
if (events & EVENT_PRIORITY) flags |= EPOLLPRI;
|
220
|
+
if (events & EVENT_WRITABLE) flags |= EPOLLOUT;
|
177
221
|
|
178
222
|
flags |= EPOLLRDHUP;
|
179
223
|
flags |= EPOLLONESHOT;
|
@@ -185,15 +229,15 @@ static inline
|
|
185
229
|
int events_from_epoll_flags(uint32_t flags) {
|
186
230
|
int events = 0;
|
187
231
|
|
188
|
-
if (flags & EPOLLIN) events |=
|
189
|
-
if (flags & EPOLLPRI) events |=
|
190
|
-
if (flags & EPOLLOUT) events |=
|
232
|
+
if (flags & EPOLLIN) events |= EVENT_READABLE;
|
233
|
+
if (flags & EPOLLPRI) events |= EVENT_PRIORITY;
|
234
|
+
if (flags & EPOLLOUT) events |= EVENT_WRITABLE;
|
191
235
|
|
192
236
|
return events;
|
193
237
|
}
|
194
238
|
|
195
239
|
struct io_wait_arguments {
|
196
|
-
struct
|
240
|
+
struct Event_Selector_EPoll *data;
|
197
241
|
int descriptor;
|
198
242
|
int duplicate;
|
199
243
|
};
|
@@ -217,18 +261,18 @@ static
|
|
217
261
|
VALUE io_wait_transfer(VALUE _arguments) {
|
218
262
|
struct io_wait_arguments *arguments = (struct io_wait_arguments *)_arguments;
|
219
263
|
|
220
|
-
VALUE result =
|
264
|
+
VALUE result = Event_Selector_fiber_transfer(arguments->data->backend.loop, 0, NULL);
|
221
265
|
|
222
266
|
return INT2NUM(events_from_epoll_flags(NUM2INT(result)));
|
223
267
|
};
|
224
268
|
|
225
|
-
VALUE
|
226
|
-
struct
|
227
|
-
TypedData_Get_Struct(self, struct
|
269
|
+
VALUE Event_Selector_EPoll_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE events) {
|
270
|
+
struct Event_Selector_EPoll *data = NULL;
|
271
|
+
TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
228
272
|
|
229
273
|
struct epoll_event event = {0};
|
230
274
|
|
231
|
-
int descriptor =
|
275
|
+
int descriptor = Event_Selector_io_descriptor(io);
|
232
276
|
int duplicate = -1;
|
233
277
|
|
234
278
|
event.events = epoll_flags_from_events(NUM2INT(events));
|
@@ -264,6 +308,8 @@ VALUE Event_Backend_EPoll_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE event
|
|
264
308
|
return rb_ensure(io_wait_transfer, (VALUE)&io_wait_arguments, io_wait_ensure, (VALUE)&io_wait_arguments);
|
265
309
|
}
|
266
310
|
|
311
|
+
#ifdef HAVE_RUBY_IO_BUFFER_H
|
312
|
+
|
267
313
|
struct io_read_arguments {
|
268
314
|
VALUE self;
|
269
315
|
VALUE fiber;
|
@@ -274,7 +320,6 @@ struct io_read_arguments {
|
|
274
320
|
int descriptor;
|
275
321
|
|
276
322
|
VALUE buffer;
|
277
|
-
size_t offset;
|
278
323
|
size_t length;
|
279
324
|
};
|
280
325
|
|
@@ -282,58 +327,54 @@ static
|
|
282
327
|
VALUE io_read_loop(VALUE _arguments) {
|
283
328
|
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
284
329
|
|
285
|
-
|
330
|
+
void *base;
|
331
|
+
size_t size;
|
332
|
+
rb_io_buffer_get_mutable(arguments->buffer, &base, &size);
|
333
|
+
|
334
|
+
size_t offset = 0;
|
286
335
|
size_t length = arguments->length;
|
287
|
-
size_t total = 0;
|
288
336
|
|
289
337
|
while (length > 0) {
|
290
|
-
|
291
|
-
ssize_t result = read(arguments->descriptor,
|
338
|
+
size_t maximum_size = size - offset;
|
339
|
+
ssize_t result = read(arguments->descriptor, (char*)base+offset, maximum_size);
|
292
340
|
|
293
|
-
if (result
|
341
|
+
if (result == 0) {
|
342
|
+
break;
|
343
|
+
} else if (result > 0) {
|
294
344
|
offset += result;
|
295
345
|
length -= result;
|
296
|
-
total += result;
|
297
346
|
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
298
|
-
|
347
|
+
Event_Selector_EPoll_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(EVENT_READABLE));
|
299
348
|
} else {
|
300
|
-
rb_sys_fail("
|
349
|
+
rb_sys_fail("Event_Selector_EPoll_io_read");
|
301
350
|
}
|
302
351
|
}
|
303
352
|
|
304
|
-
|
305
|
-
|
306
|
-
return SIZET2NUM(total);
|
353
|
+
return SIZET2NUM(offset);
|
307
354
|
}
|
308
355
|
|
309
356
|
static
|
310
357
|
VALUE io_read_ensure(VALUE _arguments) {
|
311
358
|
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
312
359
|
|
313
|
-
|
360
|
+
Event_Selector_nonblock_restore(arguments->descriptor, arguments->flags);
|
314
361
|
|
315
362
|
return Qnil;
|
316
363
|
}
|
317
364
|
|
318
|
-
VALUE
|
319
|
-
|
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));
|
365
|
+
VALUE Event_Selector_EPoll_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length) {
|
366
|
+
int descriptor = Event_Selector_io_descriptor(io);
|
323
367
|
|
324
|
-
size_t offset = NUM2SIZET(_offset);
|
325
368
|
size_t length = NUM2SIZET(_length);
|
326
369
|
|
327
|
-
|
328
370
|
struct io_read_arguments io_read_arguments = {
|
329
371
|
.self = self,
|
330
372
|
.fiber = fiber,
|
331
373
|
.io = io,
|
332
374
|
|
333
|
-
.flags =
|
375
|
+
.flags = Event_Selector_nonblock_set(descriptor),
|
334
376
|
.descriptor = descriptor,
|
335
377
|
.buffer = buffer,
|
336
|
-
.offset = offset,
|
337
378
|
.length = length,
|
338
379
|
};
|
339
380
|
|
@@ -350,7 +391,6 @@ struct io_write_arguments {
|
|
350
391
|
int descriptor;
|
351
392
|
|
352
393
|
VALUE buffer;
|
353
|
-
size_t offset;
|
354
394
|
size_t length;
|
355
395
|
};
|
356
396
|
|
@@ -358,44 +398,45 @@ static
|
|
358
398
|
VALUE io_write_loop(VALUE _arguments) {
|
359
399
|
struct io_write_arguments *arguments = (struct io_write_arguments *)_arguments;
|
360
400
|
|
361
|
-
|
401
|
+
const void *base;
|
402
|
+
size_t size;
|
403
|
+
rb_io_buffer_get_immutable(arguments->buffer, &base, &size);
|
404
|
+
|
405
|
+
size_t offset = 0;
|
362
406
|
size_t length = arguments->length;
|
363
|
-
|
407
|
+
|
408
|
+
if (length > size) {
|
409
|
+
rb_raise(rb_eRuntimeError, "Length exceeds size of buffer!");
|
410
|
+
}
|
364
411
|
|
365
412
|
while (length > 0) {
|
366
|
-
|
367
|
-
ssize_t result = write(arguments->descriptor, buffer+offset, length);
|
413
|
+
ssize_t result = write(arguments->descriptor, (char*)base+offset, length);
|
368
414
|
|
369
415
|
if (result >= 0) {
|
370
|
-
length -= result;
|
371
416
|
offset += result;
|
372
|
-
|
417
|
+
length -= result;
|
373
418
|
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
374
|
-
|
419
|
+
Event_Selector_EPoll_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(EVENT_WRITABLE));
|
375
420
|
} else {
|
376
|
-
rb_sys_fail("
|
421
|
+
rb_sys_fail("Event_Selector_EPoll_io_write");
|
377
422
|
}
|
378
423
|
}
|
379
424
|
|
380
|
-
return SIZET2NUM(
|
425
|
+
return SIZET2NUM(offset);
|
381
426
|
};
|
382
427
|
|
383
428
|
static
|
384
429
|
VALUE io_write_ensure(VALUE _arguments) {
|
385
430
|
struct io_write_arguments *arguments = (struct io_write_arguments *)_arguments;
|
386
431
|
|
387
|
-
|
432
|
+
Event_Selector_nonblock_restore(arguments->descriptor, arguments->flags);
|
388
433
|
|
389
434
|
return Qnil;
|
390
435
|
};
|
391
436
|
|
392
|
-
VALUE
|
393
|
-
|
394
|
-
TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
|
437
|
+
VALUE Event_Selector_EPoll_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length) {
|
438
|
+
int descriptor = Event_Selector_io_descriptor(io);
|
395
439
|
|
396
|
-
int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
|
397
|
-
|
398
|
-
size_t offset = NUM2SIZET(_offset);
|
399
440
|
size_t length = NUM2SIZET(_length);
|
400
441
|
|
401
442
|
struct io_write_arguments io_write_arguments = {
|
@@ -403,16 +444,17 @@ VALUE Event_Backend_EPoll_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buff
|
|
403
444
|
.fiber = fiber,
|
404
445
|
.io = io,
|
405
446
|
|
406
|
-
.flags =
|
447
|
+
.flags = Event_Selector_nonblock_set(descriptor),
|
407
448
|
.descriptor = descriptor,
|
408
449
|
.buffer = buffer,
|
409
|
-
.offset = offset,
|
410
450
|
.length = length,
|
411
451
|
};
|
412
452
|
|
413
453
|
return rb_ensure(io_write_loop, (VALUE)&io_write_arguments, io_write_ensure, (VALUE)&io_write_arguments);
|
414
454
|
}
|
415
455
|
|
456
|
+
#endif
|
457
|
+
|
416
458
|
static
|
417
459
|
int make_timeout(VALUE duration) {
|
418
460
|
if (duration == Qnil) {
|
@@ -433,7 +475,7 @@ int make_timeout(VALUE duration) {
|
|
433
475
|
}
|
434
476
|
|
435
477
|
struct select_arguments {
|
436
|
-
struct
|
478
|
+
struct Event_Selector_EPoll *data;
|
437
479
|
|
438
480
|
int count;
|
439
481
|
struct epoll_event events[EPOLL_MAX_EVENTS];
|
@@ -468,9 +510,11 @@ void select_internal_with_gvl(struct select_arguments *arguments) {
|
|
468
510
|
}
|
469
511
|
}
|
470
512
|
|
471
|
-
VALUE
|
472
|
-
struct
|
473
|
-
TypedData_Get_Struct(self, struct
|
513
|
+
VALUE Event_Selector_EPoll_select(VALUE self, VALUE duration) {
|
514
|
+
struct Event_Selector_EPoll *data = NULL;
|
515
|
+
TypedData_Get_Struct(self, struct Event_Selector_EPoll, &Event_Selector_EPoll_Type, data);
|
516
|
+
|
517
|
+
int ready = Event_Selector_queue_flush(&data->backend);
|
474
518
|
|
475
519
|
struct select_arguments arguments = {
|
476
520
|
.data = data,
|
@@ -478,8 +522,9 @@ VALUE Event_Backend_EPoll_select(VALUE self, VALUE duration) {
|
|
478
522
|
};
|
479
523
|
|
480
524
|
select_internal_with_gvl(&arguments);
|
481
|
-
|
482
|
-
|
525
|
+
|
526
|
+
// If the ready list was empty and no events were processed:
|
527
|
+
if (!ready && arguments.count == 0) {
|
483
528
|
arguments.timeout = make_timeout(duration);
|
484
529
|
|
485
530
|
if (arguments.timeout != 0) {
|
@@ -493,25 +538,34 @@ VALUE Event_Backend_EPoll_select(VALUE self, VALUE duration) {
|
|
493
538
|
|
494
539
|
// fprintf(stderr, "-> fiber=%p descriptor=%d\n", (void*)fiber, events[i].data.fd);
|
495
540
|
|
496
|
-
|
541
|
+
Event_Selector_fiber_transfer(fiber, 1, &result);
|
497
542
|
}
|
498
543
|
|
499
544
|
return INT2NUM(arguments.count);
|
500
545
|
}
|
501
546
|
|
502
|
-
void
|
503
|
-
|
547
|
+
void Init_Event_Selector_EPoll(VALUE Event_Selector) {
|
548
|
+
Event_Selector_EPoll = rb_define_class_under(Event_Selector, "EPoll", rb_cObject);
|
549
|
+
|
550
|
+
rb_define_alloc_func(Event_Selector_EPoll, Event_Selector_EPoll_allocate);
|
551
|
+
rb_define_method(Event_Selector_EPoll, "initialize", Event_Selector_EPoll_initialize, 1);
|
552
|
+
|
553
|
+
rb_define_method(Event_Selector_EPoll, "transfer", Event_Selector_EPoll_transfer, -1);
|
554
|
+
rb_define_method(Event_Selector_EPoll, "yield", Event_Selector_EPoll_yield, 0);
|
555
|
+
rb_define_method(Event_Selector_EPoll, "push", Event_Selector_EPoll_push, 1);
|
556
|
+
rb_define_method(Event_Selector_EPoll, "raise", Event_Selector_EPoll_raise, -1);
|
557
|
+
|
558
|
+
rb_define_method(Event_Selector_EPoll, "ready?", Event_Selector_EPoll_ready_p, 0);
|
504
559
|
|
505
|
-
|
560
|
+
rb_define_method(Event_Selector_EPoll, "select", Event_Selector_EPoll_select, 1);
|
561
|
+
rb_define_method(Event_Selector_EPoll, "close", Event_Selector_EPoll_close, 0);
|
506
562
|
|
507
|
-
|
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);
|
510
|
-
rb_define_method(Event_Backend_EPoll, "close", Event_Backend_EPoll_close, 0);
|
563
|
+
rb_define_method(Event_Selector_EPoll, "io_wait", Event_Selector_EPoll_io_wait, 3);
|
511
564
|
|
512
|
-
|
513
|
-
rb_define_method(
|
514
|
-
rb_define_method(
|
565
|
+
#ifdef HAVE_RUBY_IO_BUFFER_H
|
566
|
+
rb_define_method(Event_Selector_EPoll, "io_read", Event_Selector_EPoll_io_read, 4);
|
567
|
+
rb_define_method(Event_Selector_EPoll, "io_write", Event_Selector_EPoll_io_write, 4);
|
568
|
+
#endif
|
515
569
|
|
516
|
-
rb_define_method(
|
570
|
+
rb_define_method(Event_Selector_EPoll, "process_wait", Event_Selector_EPoll_process_wait, 3);
|
517
571
|
}
|