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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0380b6d95d8bd8f8d378820eefa77e6c6f0f1aaceb2afec54cb4d38f57747cbc'
4
- data.tar.gz: 2a0bfede977154f30a402fda4ec445eedc4daf3893bae8760eceaa1e58c999be
3
+ metadata.gz: 62bded3e0e8e8929ef5f76b427a975f1444c215d3566423e17b6aecdcbbb1f0b
4
+ data.tar.gz: 6c241f562c00af271443406efa52c935f84fb6b30023b4c7086a8c4ee5b7b965
5
5
  SHA512:
6
- metadata.gz: d12fab2ce89b8c22d583a7472670f8bdb5b5b3428832938f9c51ce3635f08bfaf7d107b6568f762849a4fa8b32fdb0d79823bbd4ebd795b690e885b0eff52798
7
- data.tar.gz: 793cf18caeb1457cd5499ee3d0fd2108dbf46e953cbc11b80e7c800efeb6beac279395a24da420b4c751a89ee5ecd54ad53a3b3a58d4b07d75e9a89d84a8be4d
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 "backend/backend.h"
22
+ #include "selector/selector.h"
23
23
 
24
24
  VALUE Event = Qnil;
25
- VALUE Event_Backend = Qnil;
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
- Event_Backend = rb_define_module_under(Event, "Backend");
34
+ Event_Selector = rb_define_module_under(Event, "Selector");
35
35
 
36
- Init_Event_Backend(Event_Backend);
36
+ Init_Event_Selector(Event_Selector);
37
37
 
38
- #ifdef EVENT_BACKEND_URING
39
- Init_Event_Backend_URing(Event_Backend);
38
+ #ifdef EVENT_SELECTOR_URING
39
+ Init_Event_Selector_URing(Event_Selector);
40
40
  #endif
41
41
 
42
- #ifdef EVENT_BACKEND_EPOLL
43
- Init_Event_Backend_EPoll(Event_Backend);
42
+ #ifdef EVENT_SELECTOR_EPOLL
43
+ Init_Event_Selector_EPoll(Event_Selector);
44
44
  #endif
45
45
 
46
- #ifdef EVENT_BACKEND_KQUEUE
47
- Init_Event_Backend_KQueue(Event_Backend);
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 "backend/uring.h"
30
+ #include "selector/uring.h"
31
31
  #endif
32
32
 
33
33
  #ifdef HAVE_SYS_EPOLL_H
34
- #include "backend/epoll.h"
34
+ #include "selector/epoll.h"
35
35
  #endif
36
36
 
37
37
  #ifdef HAVE_SYS_EVENT_H
38
- #include "backend/kqueue.h"
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", "backend/backend.c"]
34
- $VPATH << "$(srcdir)/backend"
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 << "backend/uring.c"
39
+ $srcs << "selector/uring.c"
40
40
  end
41
41
 
42
42
  if have_header('sys/epoll.h')
43
- $srcs << "backend/epoll.c"
43
+ $srcs << "selector/epoll.c"
44
44
  end
45
45
 
46
46
  if have_header('sys/event.h')
47
- $srcs << "backend/kqueue.c"
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 "backend.h"
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 Event_Backend_EPoll = Qnil;
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 Event_Backend_EPoll {
36
- VALUE loop;
34
+ struct Event_Selector_EPoll {
35
+ struct Event_Selector backend;
37
36
  int descriptor;
38
37
  };
39
38
 
40
- void Event_Backend_EPoll_Type_mark(void *_data)
39
+ void Event_Selector_EPoll_Type_mark(void *_data)
41
40
  {
42
- struct Event_Backend_EPoll *data = _data;
43
- rb_gc_mark(data->loop);
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 Event_Backend_EPoll *data) {
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 Event_Backend_EPoll_Type_free(void *_data)
53
+ void Event_Selector_EPoll_Type_free(void *_data)
55
54
  {
56
- struct Event_Backend_EPoll *data = _data;
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 Event_Backend_EPoll_Type_size(const void *data)
62
+ size_t Event_Selector_EPoll_Type_size(const void *data)
64
63
  {
65
- return sizeof(struct Event_Backend_EPoll);
64
+ return sizeof(struct Event_Selector_EPoll);
66
65
  }
67
66
 
68
- static const rb_data_type_t Event_Backend_EPoll_Type = {
67
+ static const rb_data_type_t Event_Selector_EPoll_Type = {
69
68
  .wrap_struct_name = "Event::Backend::EPoll",
70
69
  .function = {
71
- .dmark = Event_Backend_EPoll_Type_mark,
72
- .dfree = Event_Backend_EPoll_Type_free,
73
- .dsize = Event_Backend_EPoll_Type_size,
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 Event_Backend_EPoll_allocate(VALUE self) {
80
- struct Event_Backend_EPoll *data = NULL;
81
- VALUE instance = TypedData_Make_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
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->loop = Qnil;
82
+ Event_Selector_initialize(&data->backend, Qnil);
84
83
  data->descriptor = -1;
85
84
 
86
85
  return instance;
87
86
  }
88
87
 
89
- VALUE Event_Backend_EPoll_initialize(VALUE self, VALUE loop) {
90
- struct Event_Backend_EPoll *data = NULL;
91
- TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
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->loop = loop;
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 Event_Backend_EPoll_close(VALUE self) {
108
- struct Event_Backend_EPoll *data = NULL;
109
- TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
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 Event_Backend_EPoll *data;
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
- Event_Backend_transfer(arguments->data->loop);
171
+ Event_Selector_fiber_transfer(arguments->data->backend.loop, 0, NULL);
128
172
 
129
- return Event_Backend_process_status_wait(arguments->pid);
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 Event_Backend_EPoll_process_wait(VALUE self, VALUE fiber, VALUE pid, VALUE flags) {
144
- struct Event_Backend_EPoll *data = NULL;
145
- TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
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 & READABLE) flags |= EPOLLIN;
175
- if (events & PRIORITY) flags |= EPOLLPRI;
176
- if (events & WRITABLE) flags |= EPOLLOUT;
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 |= READABLE;
189
- if (flags & EPOLLPRI) events |= PRIORITY;
190
- if (flags & EPOLLOUT) events |= WRITABLE;
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 Event_Backend_EPoll *data;
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 = Event_Backend_transfer(arguments->data->loop);
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 Event_Backend_EPoll_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE events) {
226
- struct Event_Backend_EPoll *data = NULL;
227
- TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
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 = NUM2INT(rb_funcall(io, id_fileno, 0));
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
- size_t offset = arguments->offset;
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
- char *buffer = Event_Backend_resize_to_capacity(arguments->buffer, offset, length);
291
- ssize_t result = read(arguments->descriptor, buffer+offset, length);
338
+ size_t maximum_size = size - offset;
339
+ ssize_t result = read(arguments->descriptor, (char*)base+offset, maximum_size);
292
340
 
293
- if (result >= 0) {
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
- Event_Backend_EPoll_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(READABLE));
347
+ Event_Selector_EPoll_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(EVENT_READABLE));
299
348
  } else {
300
- rb_sys_fail("Event_Backend_EPoll_io_read");
349
+ rb_sys_fail("Event_Selector_EPoll_io_read");
301
350
  }
302
351
  }
303
352
 
304
- Event_Backend_resize_to_fit(arguments->buffer, arguments->offset, arguments->length);
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
- Event_Backend_nonblock_restore(arguments->descriptor, arguments->flags);
360
+ Event_Selector_nonblock_restore(arguments->descriptor, arguments->flags);
314
361
 
315
362
  return Qnil;
316
363
  }
317
364
 
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));
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 = Event_Backend_nonblock_set(descriptor),
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
- size_t offset = arguments->offset;
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
- size_t total = 0;
407
+
408
+ if (length > size) {
409
+ rb_raise(rb_eRuntimeError, "Length exceeds size of buffer!");
410
+ }
364
411
 
365
412
  while (length > 0) {
366
- char *buffer = Event_Backend_verify_size(arguments->buffer, offset, length);
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
- total += result;
417
+ length -= result;
373
418
  } else if (errno == EAGAIN || errno == EWOULDBLOCK) {
374
- Event_Backend_EPoll_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(WRITABLE));
419
+ Event_Selector_EPoll_io_wait(arguments->self, arguments->fiber, arguments->io, RB_INT2NUM(EVENT_WRITABLE));
375
420
  } else {
376
- rb_sys_fail("Event_Backend_EPoll_io_write");
421
+ rb_sys_fail("Event_Selector_EPoll_io_write");
377
422
  }
378
423
  }
379
424
 
380
- return SIZET2NUM(total);
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
- Event_Backend_nonblock_restore(arguments->descriptor, arguments->flags);
432
+ Event_Selector_nonblock_restore(arguments->descriptor, arguments->flags);
388
433
 
389
434
  return Qnil;
390
435
  };
391
436
 
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);
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 = Event_Backend_nonblock_set(descriptor),
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 Event_Backend_EPoll *data;
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 Event_Backend_EPoll_select(VALUE self, VALUE duration) {
472
- struct Event_Backend_EPoll *data = NULL;
473
- TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
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
- if (arguments.count == 0) {
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
- Event_Backend_transfer_result(fiber, result);
541
+ Event_Selector_fiber_transfer(fiber, 1, &result);
497
542
  }
498
543
 
499
544
  return INT2NUM(arguments.count);
500
545
  }
501
546
 
502
- void Init_Event_Backend_EPoll(VALUE Event_Backend) {
503
- id_fileno = rb_intern("fileno");
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
- Event_Backend_EPoll = rb_define_class_under(Event_Backend, "EPoll", rb_cObject);
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
- rb_define_alloc_func(Event_Backend_EPoll, Event_Backend_EPoll_allocate);
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
- rb_define_method(Event_Backend_EPoll, "io_wait", Event_Backend_EPoll_io_wait, 3);
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);
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(Event_Backend_EPoll, "process_wait", Event_Backend_EPoll_process_wait, 3);
570
+ rb_define_method(Event_Selector_EPoll, "process_wait", Event_Selector_EPoll_process_wait, 3);
517
571
  }