nio4r 0.2.0 → 2.7.5

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.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/ext/libev/Changes +232 -3
  4. data/ext/libev/LICENSE +2 -1
  5. data/ext/libev/README +11 -10
  6. data/ext/libev/ev.c +2249 -473
  7. data/ext/libev/ev.h +165 -135
  8. data/ext/libev/ev_epoll.c +68 -36
  9. data/ext/libev/ev_iouring.c +694 -0
  10. data/ext/libev/ev_kqueue.c +44 -18
  11. data/ext/libev/ev_linuxaio.c +620 -0
  12. data/ext/libev/ev_poll.c +28 -20
  13. data/ext/libev/ev_port.c +23 -10
  14. data/ext/libev/ev_select.c +18 -12
  15. data/ext/libev/ev_vars.h +65 -19
  16. data/ext/libev/ev_win32.c +16 -7
  17. data/ext/libev/ev_wrap.h +236 -160
  18. data/ext/nio4r/.clang-format +16 -0
  19. data/ext/nio4r/bytebuffer.c +465 -0
  20. data/ext/nio4r/extconf.rb +44 -35
  21. data/ext/nio4r/libev.h +3 -4
  22. data/ext/nio4r/monitor.c +186 -54
  23. data/ext/nio4r/nio4r.h +17 -23
  24. data/ext/nio4r/nio4r_ext.c +11 -3
  25. data/ext/nio4r/org/nio4r/ByteBuffer.java +295 -0
  26. data/ext/nio4r/org/nio4r/Monitor.java +176 -0
  27. data/ext/nio4r/org/nio4r/Nio4r.java +104 -0
  28. data/ext/nio4r/org/nio4r/Selector.java +297 -0
  29. data/ext/nio4r/selector.c +350 -182
  30. data/lib/nio/bytebuffer.rb +235 -0
  31. data/lib/nio/monitor.rb +100 -8
  32. data/lib/nio/selector.rb +110 -44
  33. data/lib/nio/version.rb +8 -1
  34. data/lib/nio.rb +47 -16
  35. data/lib/nio4r.rb +7 -0
  36. data/license.md +80 -0
  37. data/readme.md +91 -0
  38. data/releases.md +343 -0
  39. data.tar.gz.sig +2 -0
  40. metadata +114 -79
  41. metadata.gz.sig +0 -0
  42. data/.gitignore +0 -20
  43. data/.rspec +0 -4
  44. data/.travis.yml +0 -7
  45. data/CHANGES.md +0 -10
  46. data/Gemfile +0 -4
  47. data/LICENSE.txt +0 -20
  48. data/README.md +0 -171
  49. data/Rakefile +0 -9
  50. data/examples/echo_server.rb +0 -38
  51. data/ext/libev/README.embed +0 -3
  52. data/ext/libev/test_libev_win32.c +0 -123
  53. data/lib/nio/jruby/monitor.rb +0 -42
  54. data/lib/nio/jruby/selector.rb +0 -135
  55. data/nio4r.gemspec +0 -22
  56. data/spec/nio/monitor_spec.rb +0 -46
  57. data/spec/nio/selector_spec.rb +0 -269
  58. data/spec/spec_helper.rb +0 -3
  59. data/tasks/extension.rake +0 -10
  60. data/tasks/rspec.rake +0 -7
data/ext/nio4r/monitor.c CHANGED
@@ -11,28 +11,39 @@ static VALUE cNIO_Monitor = Qnil;
11
11
 
12
12
  /* Allocator/deallocator */
13
13
  static VALUE NIO_Monitor_allocate(VALUE klass);
14
- static void NIO_Monitor_mark(struct NIO_Monitor *monitor);
15
- static void NIO_Monitor_free(struct NIO_Monitor *monitor);
14
+ static void NIO_Monitor_mark(void *data);
15
+ static size_t NIO_Monitor_memsize(const void *data);
16
16
 
17
17
  /* Methods */
18
18
  static VALUE NIO_Monitor_initialize(VALUE self, VALUE selector, VALUE io, VALUE interests);
19
- static VALUE NIO_Monitor_close(VALUE self);
19
+ static VALUE NIO_Monitor_close(int argc, VALUE *argv, VALUE self);
20
20
  static VALUE NIO_Monitor_is_closed(VALUE self);
21
21
  static VALUE NIO_Monitor_io(VALUE self);
22
22
  static VALUE NIO_Monitor_interests(VALUE self);
23
+ static VALUE NIO_Monitor_set_interests(VALUE self, VALUE interests);
24
+ static VALUE NIO_Monitor_add_interest(VALUE self, VALUE interest);
25
+ static VALUE NIO_Monitor_remove_interest(VALUE self, VALUE interest);
26
+ static VALUE NIO_Monitor_selector(VALUE self);
23
27
  static VALUE NIO_Monitor_is_readable(VALUE self);
24
28
  static VALUE NIO_Monitor_is_writable(VALUE self);
25
29
  static VALUE NIO_Monitor_value(VALUE self);
26
30
  static VALUE NIO_Monitor_set_value(VALUE self, VALUE obj);
27
31
  static VALUE NIO_Monitor_readiness(VALUE self);
28
32
 
29
- /* Internal functions */
30
- static void NIO_Monitor_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
33
+ /* Internal C functions */
34
+ static int NIO_Monitor_symbol2interest(VALUE interests);
35
+ static void NIO_Monitor_update_interests(VALUE self, int interests);
31
36
 
32
- #if HAVE_RB_IO_T
33
- rb_io_t *fptr;
34
- #else
35
- OpenFile *fptr;
37
+ /* Compatibility for Ruby <= 3.1 */
38
+ #ifndef HAVE_RB_IO_DESCRIPTOR
39
+ static int
40
+ io_descriptor_fallback(VALUE io)
41
+ {
42
+ rb_io_t *fptr;
43
+ GetOpenFile(io, fptr);
44
+ return fptr->fd;
45
+ }
46
+ #define rb_io_descriptor io_descriptor_fallback
36
47
  #endif
37
48
 
38
49
  /* Monitor control how a channel is being waited for by a monitor */
@@ -43,10 +54,14 @@ void Init_NIO_Monitor()
43
54
  rb_define_alloc_func(cNIO_Monitor, NIO_Monitor_allocate);
44
55
 
45
56
  rb_define_method(cNIO_Monitor, "initialize", NIO_Monitor_initialize, 3);
46
- rb_define_method(cNIO_Monitor, "close", NIO_Monitor_close, 0);
57
+ rb_define_method(cNIO_Monitor, "close", NIO_Monitor_close, -1);
47
58
  rb_define_method(cNIO_Monitor, "closed?", NIO_Monitor_is_closed, 0);
48
59
  rb_define_method(cNIO_Monitor, "io", NIO_Monitor_io, 0);
49
60
  rb_define_method(cNIO_Monitor, "interests", NIO_Monitor_interests, 0);
61
+ rb_define_method(cNIO_Monitor, "interests=", NIO_Monitor_set_interests, 1);
62
+ rb_define_method(cNIO_Monitor, "add_interest", NIO_Monitor_add_interest, 1);
63
+ rb_define_method(cNIO_Monitor, "remove_interest", NIO_Monitor_remove_interest, 1);
64
+ rb_define_method(cNIO_Monitor, "selector", NIO_Monitor_selector, 0);
50
65
  rb_define_method(cNIO_Monitor, "value", NIO_Monitor_value, 0);
51
66
  rb_define_method(cNIO_Monitor, "value=", NIO_Monitor_set_value, 1);
52
67
  rb_define_method(cNIO_Monitor, "readiness", NIO_Monitor_readiness, 0);
@@ -55,78 +70,103 @@ void Init_NIO_Monitor()
55
70
  rb_define_method(cNIO_Monitor, "writeable?", NIO_Monitor_is_writable, 0);
56
71
  }
57
72
 
73
+ static const rb_data_type_t NIO_Monitor_type = {
74
+ "NIO::Monitor",
75
+ {
76
+ NIO_Monitor_mark,
77
+ RUBY_TYPED_DEFAULT_FREE,
78
+ NIO_Monitor_memsize,
79
+ },
80
+ 0,
81
+ 0,
82
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
83
+ };
84
+
58
85
  static VALUE NIO_Monitor_allocate(VALUE klass)
59
86
  {
60
87
  struct NIO_Monitor *monitor = (struct NIO_Monitor *)xmalloc(sizeof(struct NIO_Monitor));
61
-
62
- return Data_Wrap_Struct(klass, NIO_Monitor_mark, NIO_Monitor_free, monitor);
88
+ assert(monitor);
89
+ *monitor = (struct NIO_Monitor){.self = Qnil};
90
+ return TypedData_Wrap_Struct(klass, &NIO_Monitor_type, monitor);
63
91
  }
64
92
 
65
- static void NIO_Monitor_mark(struct NIO_Monitor *monitor)
93
+ static void NIO_Monitor_mark(void *data)
66
94
  {
95
+ struct NIO_Monitor *monitor = (struct NIO_Monitor *)data;
96
+ rb_gc_mark(monitor->self);
67
97
  }
68
98
 
69
- static void NIO_Monitor_free(struct NIO_Monitor *monitor)
99
+ static size_t NIO_Monitor_memsize(const void *data)
70
100
  {
71
- xfree(monitor);
101
+ const struct NIO_Monitor *monitor = (const struct NIO_Monitor *)data;
102
+ return sizeof(*monitor);
72
103
  }
73
104
 
74
- static VALUE NIO_Monitor_initialize(VALUE self, VALUE selector_obj, VALUE io, VALUE interests)
105
+ static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE selector_obj)
75
106
  {
76
107
  struct NIO_Monitor *monitor;
77
108
  struct NIO_Selector *selector;
78
109
  ID interests_id;
79
110
 
80
- #if HAVE_RB_IO_T
81
- rb_io_t *fptr;
82
- #else
83
- OpenFile *fptr;
84
- #endif
85
-
86
111
  interests_id = SYM2ID(interests);
87
112
 
88
- Data_Get_Struct(self, struct NIO_Monitor, monitor);
113
+ TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
89
114
 
90
- if(interests_id == rb_intern("r")) {
115
+ if (interests_id == rb_intern("r")) {
91
116
  monitor->interests = EV_READ;
92
- } else if(interests_id == rb_intern("w")) {
117
+ } else if (interests_id == rb_intern("w")) {
93
118
  monitor->interests = EV_WRITE;
94
- } else if(interests_id == rb_intern("rw")) {
119
+ } else if (interests_id == rb_intern("rw")) {
95
120
  monitor->interests = EV_READ | EV_WRITE;
96
121
  } else {
97
- rb_raise(rb_eArgError, "invalid event type %s (must be :r, :w, or :rw)",
98
- RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0, 0)));
122
+ rb_raise(rb_eArgError, "invalid event type %s (must be :r, :w, or :rw)", RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0)));
99
123
  }
100
124
 
101
- GetOpenFile(rb_convert_type(io, T_FILE, "IO", "to_io"), fptr);
102
- ev_io_init(&monitor->ev_io, NIO_Monitor_callback, FPTR_TO_FD(fptr), monitor->interests);
125
+ int descriptor = rb_io_descriptor(rb_convert_type(io, T_FILE, "IO", "to_io"));
126
+ ev_io_init(&monitor->ev_io, NIO_Selector_monitor_callback, descriptor, monitor->interests);
103
127
 
104
- rb_ivar_set(self, rb_intern("selector"), selector_obj);
105
128
  rb_ivar_set(self, rb_intern("io"), io);
106
129
  rb_ivar_set(self, rb_intern("interests"), interests);
130
+ rb_ivar_set(self, rb_intern("selector"), selector_obj);
107
131
 
108
- Data_Get_Struct(selector_obj, struct NIO_Selector, selector);
132
+ selector = NIO_Selector_unwrap(selector_obj);
109
133
 
110
- monitor->self = self;
134
+ RB_OBJ_WRITE(self, &monitor->self, self);
111
135
  monitor->ev_io.data = (void *)monitor;
112
136
 
113
137
  /* We can safely hang onto this as we also hang onto a reference to the
114
138
  object where it originally came from */
115
139
  monitor->selector = selector;
116
140
 
117
- ev_io_start(selector->ev_loop, &monitor->ev_io);
141
+ if (monitor->interests) {
142
+ ev_io_start(selector->ev_loop, &monitor->ev_io);
143
+ }
118
144
 
119
145
  return Qnil;
120
146
  }
121
147
 
122
- static VALUE NIO_Monitor_close(VALUE self)
148
+ static VALUE NIO_Monitor_close(int argc, VALUE *argv, VALUE self)
123
149
  {
150
+ VALUE deregister, selector;
124
151
  struct NIO_Monitor *monitor;
125
- Data_Get_Struct(self, struct NIO_Monitor, monitor);
152
+ TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
153
+
154
+ rb_scan_args(argc, argv, "01", &deregister);
155
+ selector = rb_ivar_get(self, rb_intern("selector"));
156
+
157
+ if (selector != Qnil) {
158
+ /* if ev_loop is 0, it means that the loop has been stopped already (see NIO_Selector_shutdown) */
159
+ if (monitor->interests && monitor->selector->ev_loop) {
160
+ ev_io_stop(monitor->selector->ev_loop, &monitor->ev_io);
161
+ }
126
162
 
127
- if(monitor->selector) {
128
- ev_io_stop(monitor->selector->ev_loop, &monitor->ev_io);
129
163
  monitor->selector = 0;
164
+ rb_ivar_set(self, rb_intern("selector"), Qnil);
165
+
166
+ /* Default value is true */
167
+ if (deregister == Qtrue || deregister == Qnil) {
168
+ rb_funcall(selector, rb_intern("deregister"), 1, rb_ivar_get(self, rb_intern("io")));
169
+ }
130
170
  }
131
171
 
132
172
  return Qnil;
@@ -135,9 +175,9 @@ static VALUE NIO_Monitor_close(VALUE self)
135
175
  static VALUE NIO_Monitor_is_closed(VALUE self)
136
176
  {
137
177
  struct NIO_Monitor *monitor;
138
- Data_Get_Struct(self, struct NIO_Monitor, monitor);
178
+ TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
139
179
 
140
- return !monitor->selector;
180
+ return monitor->selector == 0 ? Qtrue : Qfalse;
141
181
  }
142
182
 
143
183
  static VALUE NIO_Monitor_io(VALUE self)
@@ -150,6 +190,44 @@ static VALUE NIO_Monitor_interests(VALUE self)
150
190
  return rb_ivar_get(self, rb_intern("interests"));
151
191
  }
152
192
 
193
+ static VALUE NIO_Monitor_set_interests(VALUE self, VALUE interests)
194
+ {
195
+ if (NIL_P(interests)) {
196
+ NIO_Monitor_update_interests(self, 0);
197
+ } else {
198
+ NIO_Monitor_update_interests(self, NIO_Monitor_symbol2interest(interests));
199
+ }
200
+
201
+ return rb_ivar_get(self, rb_intern("interests"));
202
+ }
203
+
204
+ static VALUE NIO_Monitor_add_interest(VALUE self, VALUE interest)
205
+ {
206
+ struct NIO_Monitor *monitor;
207
+ TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
208
+
209
+ interest = monitor->interests | NIO_Monitor_symbol2interest(interest);
210
+ NIO_Monitor_update_interests(self, (int)interest);
211
+
212
+ return rb_ivar_get(self, rb_intern("interests"));
213
+ }
214
+
215
+ static VALUE NIO_Monitor_remove_interest(VALUE self, VALUE interest)
216
+ {
217
+ struct NIO_Monitor *monitor;
218
+ TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
219
+
220
+ interest = monitor->interests & ~NIO_Monitor_symbol2interest(interest);
221
+ NIO_Monitor_update_interests(self, (int)interest);
222
+
223
+ return rb_ivar_get(self, rb_intern("interests"));
224
+ }
225
+
226
+ static VALUE NIO_Monitor_selector(VALUE self)
227
+ {
228
+ return rb_ivar_get(self, rb_intern("selector"));
229
+ }
230
+
153
231
  static VALUE NIO_Monitor_value(VALUE self)
154
232
  {
155
233
  return rb_ivar_get(self, rb_intern("value"));
@@ -163,13 +241,13 @@ static VALUE NIO_Monitor_set_value(VALUE self, VALUE obj)
163
241
  static VALUE NIO_Monitor_readiness(VALUE self)
164
242
  {
165
243
  struct NIO_Monitor *monitor;
166
- Data_Get_Struct(self, struct NIO_Monitor, monitor);
244
+ TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
167
245
 
168
- if((monitor->revents & (EV_READ | EV_WRITE)) == (EV_READ | EV_WRITE)) {
246
+ if ((monitor->revents & (EV_READ | EV_WRITE)) == (EV_READ | EV_WRITE)) {
169
247
  return ID2SYM(rb_intern("rw"));
170
- } else if(monitor->revents & EV_READ) {
248
+ } else if (monitor->revents & EV_READ) {
171
249
  return ID2SYM(rb_intern("r"));
172
- } else if(monitor->revents & EV_WRITE) {
250
+ } else if (monitor->revents & EV_WRITE) {
173
251
  return ID2SYM(rb_intern("w"));
174
252
  } else {
175
253
  return Qnil;
@@ -179,9 +257,9 @@ static VALUE NIO_Monitor_readiness(VALUE self)
179
257
  static VALUE NIO_Monitor_is_readable(VALUE self)
180
258
  {
181
259
  struct NIO_Monitor *monitor;
182
- Data_Get_Struct(self, struct NIO_Monitor, monitor);
260
+ TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
183
261
 
184
- if(monitor->revents & EV_READ) {
262
+ if (monitor->revents & EV_READ) {
185
263
  return Qtrue;
186
264
  } else {
187
265
  return Qfalse;
@@ -191,22 +269,76 @@ static VALUE NIO_Monitor_is_readable(VALUE self)
191
269
  static VALUE NIO_Monitor_is_writable(VALUE self)
192
270
  {
193
271
  struct NIO_Monitor *monitor;
194
- Data_Get_Struct(self, struct NIO_Monitor, monitor);
272
+ TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
195
273
 
196
- if(monitor->revents & EV_WRITE) {
274
+ if (monitor->revents & EV_WRITE) {
197
275
  return Qtrue;
198
276
  } else {
199
277
  return Qfalse;
200
278
  }
201
279
  }
202
280
 
203
- /* libev callback fired whenever this monitor gets events */
204
- static void NIO_Monitor_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents)
281
+ /* Internal C functions */
282
+
283
+ static int NIO_Monitor_symbol2interest(VALUE interests)
284
+ {
285
+ ID interests_id;
286
+ interests_id = SYM2ID(interests);
287
+
288
+ if (interests_id == rb_intern("r")) {
289
+ return EV_READ;
290
+ } else if (interests_id == rb_intern("w")) {
291
+ return EV_WRITE;
292
+ } else if (interests_id == rb_intern("rw")) {
293
+ return EV_READ | EV_WRITE;
294
+ } else {
295
+ rb_raise(rb_eArgError, "invalid interest type %s (must be :r, :w, or :rw)", RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0)));
296
+ }
297
+ }
298
+
299
+ static void NIO_Monitor_update_interests(VALUE self, int interests)
205
300
  {
206
- struct NIO_Monitor *monitor = (struct NIO_Monitor *)io->data;
301
+ ID interests_id;
302
+ struct NIO_Monitor *monitor;
303
+ TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
207
304
 
208
- assert(monitor->selector != 0);
209
- monitor->revents = revents;
305
+ if (NIO_Monitor_is_closed(self) == Qtrue) {
306
+ rb_raise(rb_eEOFError, "monitor is closed");
307
+ }
210
308
 
211
- NIO_Selector_handle_event(monitor->selector, monitor->self, revents);
309
+ if (interests) {
310
+ switch (interests) {
311
+ case EV_READ:
312
+ interests_id = rb_intern("r");
313
+ break;
314
+ case EV_WRITE:
315
+ interests_id = rb_intern("w");
316
+ break;
317
+ case EV_READ | EV_WRITE:
318
+ interests_id = rb_intern("rw");
319
+ break;
320
+ default:
321
+ rb_raise(rb_eRuntimeError, "bogus NIO_Monitor_update_interests! (%d)", interests);
322
+ }
323
+
324
+ rb_ivar_set(self, rb_intern("interests"), ID2SYM(interests_id));
325
+ } else {
326
+ rb_ivar_set(self, rb_intern("interests"), Qnil);
327
+ }
328
+
329
+ if (monitor->interests != interests) {
330
+ // If the monitor currently has interests, we should stop it.
331
+ if (monitor->interests) {
332
+ ev_io_stop(monitor->selector->ev_loop, &monitor->ev_io);
333
+ }
334
+
335
+ // Assign the interests we are now monitoring for:
336
+ monitor->interests = interests;
337
+ ev_io_set(&monitor->ev_io, monitor->ev_io.fd, monitor->interests);
338
+
339
+ // If we are interested in events, schedule the monitor back into the event loop:
340
+ if (monitor->interests) {
341
+ ev_io_start(monitor->selector->ev_loop, &monitor->ev_io);
342
+ }
343
+ }
212
344
  }
data/ext/nio4r/nio4r.h CHANGED
@@ -6,49 +6,43 @@
6
6
  #ifndef NIO4R_H
7
7
  #define NIO4R_H
8
8
 
9
- #include "ruby.h"
10
- #include "rubyio.h"
11
9
  #include "libev.h"
10
+ #include "ruby.h"
11
+ #include "ruby/io.h"
12
12
 
13
- struct NIO_Selector
14
- {
13
+ struct NIO_Selector {
15
14
  struct ev_loop *ev_loop;
16
15
  struct ev_timer timer; /* for timeouts */
17
- struct ev_async wakeup;
16
+ struct ev_io wakeup;
18
17
 
19
- int closed, selecting;
20
18
  int ready_count;
21
- int ready_buffer_size;
22
- VALUE *ready_buffer;
19
+ int closed, selecting;
20
+ int wakeup_reader, wakeup_writer;
21
+ volatile int wakeup_fired;
22
+
23
+ VALUE ready_array;
23
24
  };
24
25
 
25
- struct NIO_callback_data
26
- {
26
+ struct NIO_callback_data {
27
27
  VALUE *monitor;
28
28
  struct NIO_Selector *selector;
29
29
  };
30
30
 
31
- struct NIO_Monitor
32
- {
31
+ struct NIO_Monitor {
33
32
  VALUE self;
34
33
  int interests, revents;
35
34
  struct ev_io ev_io;
36
35
  struct NIO_Selector *selector;
37
36
  };
38
37
 
39
- #ifdef GetReadFile
40
- # define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
41
- #else
42
-
43
- #if !HAVE_RB_IO_T || (RUBY_VERSION_MAJOR == 1 && RUBY_VERSION_MINOR == 8)
44
- # define FPTR_TO_FD(fptr) fileno(fptr->f)
45
- #else
46
- # define FPTR_TO_FD(fptr) fptr->fd
47
- #endif /* !HAVE_RB_IO_T */
38
+ struct NIO_ByteBuffer {
39
+ char *buffer;
40
+ int position, limit, capacity, mark;
41
+ };
48
42
 
49
- #endif /* GetReadFile */
43
+ struct NIO_Selector *NIO_Selector_unwrap(VALUE selector);
50
44
 
51
45
  /* Thunk between libev callbacks in NIO::Monitors and NIO::Selectors */
52
- void NIO_Selector_handle_event(struct NIO_Selector *selector, VALUE monitor, int revents);
46
+ void NIO_Selector_monitor_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
53
47
 
54
48
  #endif /* NIO4R_H */
@@ -1,16 +1,24 @@
1
1
  /*
2
- * Copyright (c) 2011 Tony Arcieri. Distributed under the MIT License. See
3
- * LICENSE.txt for further details.
2
+ * Copyright (c) 2011-2017 Tony Arcieri. Distributed under the MIT License.
3
+ * See LICENSE.txt for further details.
4
4
  */
5
5
 
6
- #include "nio4r.h"
7
6
  #include "../libev/ev.c"
7
+ #include "nio4r.h"
8
8
 
9
9
  void Init_NIO_Selector();
10
10
  void Init_NIO_Monitor();
11
+ void Init_NIO_ByteBuffer();
11
12
 
12
13
  void Init_nio4r_ext()
13
14
  {
15
+ #ifdef HAVE_RB_EXT_RACTOR_SAFE
16
+ rb_ext_ractor_safe(true);
17
+ #endif
18
+
19
+ ev_set_allocator(xrealloc);
20
+
14
21
  Init_NIO_Selector();
15
22
  Init_NIO_Monitor();
23
+ Init_NIO_ByteBuffer();
16
24
  }