nio4r 2.5.8 → 2.7.0
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/.github/workflows/workflow.yml +33 -19
- data/.mailmap +16 -0
- data/Gemfile +5 -4
- data/{CHANGES.md → changes.md} +37 -0
- data/examples/echo_server.rb +7 -0
- data/ext/nio4r/bytebuffer.c +75 -38
- data/ext/nio4r/extconf.rb +19 -1
- data/ext/nio4r/monitor.c +47 -22
- data/ext/nio4r/nio4r.h +1 -5
- data/ext/nio4r/selector.c +72 -48
- data/lib/nio/bytebuffer.rb +6 -0
- data/lib/nio/monitor.rb +7 -0
- data/lib/nio/selector.rb +15 -0
- data/lib/nio/version.rb +6 -1
- data/lib/nio.rb +9 -0
- data/lib/nio4r.rb +5 -0
- data/license.md +77 -0
- data/nio4r.gemspec +4 -3
- data/rakelib/extension.rake +1 -2
- data/readme.md +91 -0
- data/spec/nio/acceptables_spec.rb +4 -0
- data/spec/nio/bytebuffer_spec.rb +6 -0
- data/spec/nio/monitor_spec.rb +7 -0
- data/spec/nio/selectables/pipe_spec.rb +6 -0
- data/spec/nio/selectables/ssl_socket_spec.rb +8 -3
- data/spec/nio/selectables/tcp_socket_spec.rb +7 -0
- data/spec/nio/selectables/udp_socket_spec.rb +7 -0
- data/spec/nio/selector_spec.rb +12 -0
- data/spec/spec_helper.rb +5 -2
- data/spec/support/selectable_examples.rb +8 -0
- metadata +13 -9
- data/README.md +0 -133
data/ext/nio4r/monitor.c
CHANGED
@@ -11,8 +11,8 @@ 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(
|
15
|
-
static
|
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);
|
@@ -34,6 +34,18 @@ static VALUE NIO_Monitor_readiness(VALUE self);
|
|
34
34
|
static int NIO_Monitor_symbol2interest(VALUE interests);
|
35
35
|
static void NIO_Monitor_update_interests(VALUE self, int interests);
|
36
36
|
|
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
|
47
|
+
#endif
|
48
|
+
|
37
49
|
/* Monitor control how a channel is being waited for by a monitor */
|
38
50
|
void Init_NIO_Monitor()
|
39
51
|
{
|
@@ -58,22 +70,36 @@ void Init_NIO_Monitor()
|
|
58
70
|
rb_define_method(cNIO_Monitor, "writeable?", NIO_Monitor_is_writable, 0);
|
59
71
|
}
|
60
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
|
+
|
61
85
|
static VALUE NIO_Monitor_allocate(VALUE klass)
|
62
86
|
{
|
63
87
|
struct NIO_Monitor *monitor = (struct NIO_Monitor *)xmalloc(sizeof(struct NIO_Monitor));
|
64
88
|
assert(monitor);
|
65
89
|
*monitor = (struct NIO_Monitor){.self = Qnil};
|
66
|
-
return
|
90
|
+
return TypedData_Wrap_Struct(klass, &NIO_Monitor_type, monitor);
|
67
91
|
}
|
68
92
|
|
69
|
-
static void NIO_Monitor_mark(
|
93
|
+
static void NIO_Monitor_mark(void *data)
|
70
94
|
{
|
95
|
+
struct NIO_Monitor *monitor = (struct NIO_Monitor *)data;
|
71
96
|
rb_gc_mark(monitor->self);
|
72
97
|
}
|
73
98
|
|
74
|
-
static
|
99
|
+
static size_t NIO_Monitor_memsize(const void *data)
|
75
100
|
{
|
76
|
-
|
101
|
+
const struct NIO_Monitor *monitor = (const struct NIO_Monitor *)data;
|
102
|
+
return sizeof(*monitor);
|
77
103
|
}
|
78
104
|
|
79
105
|
static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE selector_obj)
|
@@ -81,11 +107,10 @@ static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE
|
|
81
107
|
struct NIO_Monitor *monitor;
|
82
108
|
struct NIO_Selector *selector;
|
83
109
|
ID interests_id;
|
84
|
-
rb_io_t *fptr;
|
85
110
|
|
86
111
|
interests_id = SYM2ID(interests);
|
87
112
|
|
88
|
-
|
113
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
89
114
|
|
90
115
|
if (interests_id == rb_intern("r")) {
|
91
116
|
monitor->interests = EV_READ;
|
@@ -97,16 +122,16 @@ static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE
|
|
97
122
|
rb_raise(rb_eArgError, "invalid event type %s (must be :r, :w, or :rw)", RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0)));
|
98
123
|
}
|
99
124
|
|
100
|
-
|
101
|
-
ev_io_init(&monitor->ev_io, NIO_Selector_monitor_callback,
|
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);
|
102
127
|
|
103
128
|
rb_ivar_set(self, rb_intern("io"), io);
|
104
129
|
rb_ivar_set(self, rb_intern("interests"), interests);
|
105
130
|
rb_ivar_set(self, rb_intern("selector"), selector_obj);
|
106
131
|
|
107
|
-
|
132
|
+
selector = NIO_Selector_unwrap(selector_obj);
|
108
133
|
|
109
|
-
monitor->self
|
134
|
+
RB_OBJ_WRITE(self, &monitor->self, self);
|
110
135
|
monitor->ev_io.data = (void *)monitor;
|
111
136
|
|
112
137
|
/* We can safely hang onto this as we also hang onto a reference to the
|
@@ -124,7 +149,7 @@ static VALUE NIO_Monitor_close(int argc, VALUE *argv, VALUE self)
|
|
124
149
|
{
|
125
150
|
VALUE deregister, selector;
|
126
151
|
struct NIO_Monitor *monitor;
|
127
|
-
|
152
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
128
153
|
|
129
154
|
rb_scan_args(argc, argv, "01", &deregister);
|
130
155
|
selector = rb_ivar_get(self, rb_intern("selector"));
|
@@ -150,7 +175,7 @@ static VALUE NIO_Monitor_close(int argc, VALUE *argv, VALUE self)
|
|
150
175
|
static VALUE NIO_Monitor_is_closed(VALUE self)
|
151
176
|
{
|
152
177
|
struct NIO_Monitor *monitor;
|
153
|
-
|
178
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
154
179
|
|
155
180
|
return monitor->selector == 0 ? Qtrue : Qfalse;
|
156
181
|
}
|
@@ -179,10 +204,10 @@ static VALUE NIO_Monitor_set_interests(VALUE self, VALUE interests)
|
|
179
204
|
static VALUE NIO_Monitor_add_interest(VALUE self, VALUE interest)
|
180
205
|
{
|
181
206
|
struct NIO_Monitor *monitor;
|
182
|
-
|
207
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
183
208
|
|
184
209
|
interest = monitor->interests | NIO_Monitor_symbol2interest(interest);
|
185
|
-
NIO_Monitor_update_interests(self, interest);
|
210
|
+
NIO_Monitor_update_interests(self, (int)interest);
|
186
211
|
|
187
212
|
return rb_ivar_get(self, rb_intern("interests"));
|
188
213
|
}
|
@@ -190,10 +215,10 @@ static VALUE NIO_Monitor_add_interest(VALUE self, VALUE interest)
|
|
190
215
|
static VALUE NIO_Monitor_remove_interest(VALUE self, VALUE interest)
|
191
216
|
{
|
192
217
|
struct NIO_Monitor *monitor;
|
193
|
-
|
218
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
194
219
|
|
195
220
|
interest = monitor->interests & ~NIO_Monitor_symbol2interest(interest);
|
196
|
-
NIO_Monitor_update_interests(self, interest);
|
221
|
+
NIO_Monitor_update_interests(self, (int)interest);
|
197
222
|
|
198
223
|
return rb_ivar_get(self, rb_intern("interests"));
|
199
224
|
}
|
@@ -216,7 +241,7 @@ static VALUE NIO_Monitor_set_value(VALUE self, VALUE obj)
|
|
216
241
|
static VALUE NIO_Monitor_readiness(VALUE self)
|
217
242
|
{
|
218
243
|
struct NIO_Monitor *monitor;
|
219
|
-
|
244
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
220
245
|
|
221
246
|
if ((monitor->revents & (EV_READ | EV_WRITE)) == (EV_READ | EV_WRITE)) {
|
222
247
|
return ID2SYM(rb_intern("rw"));
|
@@ -232,7 +257,7 @@ static VALUE NIO_Monitor_readiness(VALUE self)
|
|
232
257
|
static VALUE NIO_Monitor_is_readable(VALUE self)
|
233
258
|
{
|
234
259
|
struct NIO_Monitor *monitor;
|
235
|
-
|
260
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
236
261
|
|
237
262
|
if (monitor->revents & EV_READ) {
|
238
263
|
return Qtrue;
|
@@ -244,7 +269,7 @@ static VALUE NIO_Monitor_is_readable(VALUE self)
|
|
244
269
|
static VALUE NIO_Monitor_is_writable(VALUE self)
|
245
270
|
{
|
246
271
|
struct NIO_Monitor *monitor;
|
247
|
-
|
272
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
248
273
|
|
249
274
|
if (monitor->revents & EV_WRITE) {
|
250
275
|
return Qtrue;
|
@@ -275,7 +300,7 @@ static void NIO_Monitor_update_interests(VALUE self, int interests)
|
|
275
300
|
{
|
276
301
|
ID interests_id;
|
277
302
|
struct NIO_Monitor *monitor;
|
278
|
-
|
303
|
+
TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor);
|
279
304
|
|
280
305
|
if (NIO_Monitor_is_closed(self) == Qtrue) {
|
281
306
|
rb_raise(rb_eEOFError, "monitor is closed");
|
data/ext/nio4r/nio4r.h
CHANGED
@@ -40,11 +40,7 @@ struct NIO_ByteBuffer {
|
|
40
40
|
int position, limit, capacity, mark;
|
41
41
|
};
|
42
42
|
|
43
|
-
|
44
|
-
#define FPTR_TO_FD(fptr) (fileno(GetReadFile(fptr)))
|
45
|
-
#else
|
46
|
-
#define FPTR_TO_FD(fptr) fptr->fd
|
47
|
-
#endif /* GetReadFile */
|
43
|
+
struct NIO_Selector *NIO_Selector_unwrap(VALUE selector);
|
48
44
|
|
49
45
|
/* Thunk between libev callbacks in NIO::Monitors and NIO::Selectors */
|
50
46
|
void NIO_Selector_monitor_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents);
|
data/ext/nio4r/selector.c
CHANGED
@@ -23,9 +23,10 @@ static VALUE cNIO_Selector = Qnil;
|
|
23
23
|
|
24
24
|
/* Allocator/deallocator */
|
25
25
|
static VALUE NIO_Selector_allocate(VALUE klass);
|
26
|
-
static void NIO_Selector_mark(
|
26
|
+
static void NIO_Selector_mark(void *data);
|
27
27
|
static void NIO_Selector_shutdown(struct NIO_Selector *selector);
|
28
|
-
static void NIO_Selector_free(
|
28
|
+
static void NIO_Selector_free(void *data);
|
29
|
+
static size_t NIO_Selector_memsize(const void *data);
|
29
30
|
|
30
31
|
/* Class methods */
|
31
32
|
static VALUE NIO_Selector_supported_backends(VALUE klass);
|
@@ -43,13 +44,13 @@ static VALUE NIO_Selector_closed(VALUE self);
|
|
43
44
|
static VALUE NIO_Selector_is_empty(VALUE self);
|
44
45
|
|
45
46
|
/* Internal functions */
|
46
|
-
static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE
|
47
|
+
static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE arg), VALUE arg);
|
47
48
|
static VALUE NIO_Selector_unlock(VALUE lock);
|
48
|
-
static VALUE NIO_Selector_register_synchronized(VALUE
|
49
|
-
static VALUE NIO_Selector_deregister_synchronized(VALUE
|
50
|
-
static VALUE NIO_Selector_select_synchronized(VALUE
|
51
|
-
static VALUE NIO_Selector_close_synchronized(VALUE
|
52
|
-
static VALUE NIO_Selector_closed_synchronized(VALUE
|
49
|
+
static VALUE NIO_Selector_register_synchronized(VALUE arg);
|
50
|
+
static VALUE NIO_Selector_deregister_synchronized(VALUE arg);
|
51
|
+
static VALUE NIO_Selector_select_synchronized(VALUE arg);
|
52
|
+
static VALUE NIO_Selector_close_synchronized(VALUE arg);
|
53
|
+
static VALUE NIO_Selector_closed_synchronized(VALUE arg);
|
53
54
|
|
54
55
|
static int NIO_Selector_run(struct NIO_Selector *selector, VALUE timeout);
|
55
56
|
static void NIO_Selector_timeout_callback(struct ev_loop *ev_loop, struct ev_timer *timer, int revents);
|
@@ -62,7 +63,7 @@ static void NIO_Selector_wakeup_callback(struct ev_loop *ev_loop, struct ev_io *
|
|
62
63
|
#define BUSYWAIT_INTERVAL 0.01
|
63
64
|
|
64
65
|
/* Selectors wait for events */
|
65
|
-
void Init_NIO_Selector()
|
66
|
+
void Init_NIO_Selector(void)
|
66
67
|
{
|
67
68
|
mNIO = rb_define_module("NIO");
|
68
69
|
cNIO_Selector = rb_define_class_under(mNIO, "Selector", rb_cObject);
|
@@ -83,6 +84,18 @@ void Init_NIO_Selector()
|
|
83
84
|
cNIO_Monitor = rb_define_class_under(mNIO, "Monitor", rb_cObject);
|
84
85
|
}
|
85
86
|
|
87
|
+
static const rb_data_type_t NIO_Selector_type = {
|
88
|
+
"NIO::Selector",
|
89
|
+
{
|
90
|
+
NIO_Selector_mark,
|
91
|
+
NIO_Selector_free,
|
92
|
+
NIO_Selector_memsize,
|
93
|
+
},
|
94
|
+
0,
|
95
|
+
0,
|
96
|
+
RUBY_TYPED_WB_PROTECTED // Don't free immediately because of shutdown
|
97
|
+
};
|
98
|
+
|
86
99
|
/* Create the libev event loop and incoming event buffer */
|
87
100
|
static VALUE NIO_Selector_allocate(VALUE klass)
|
88
101
|
{
|
@@ -104,8 +117,7 @@ static VALUE NIO_Selector_allocate(VALUE klass)
|
|
104
117
|
rb_sys_fail("fcntl");
|
105
118
|
}
|
106
119
|
|
107
|
-
|
108
|
-
|
120
|
+
VALUE obj = TypedData_Make_Struct(klass, struct NIO_Selector, &NIO_Selector_type, selector);
|
109
121
|
/* Defer initializing the loop to #initialize */
|
110
122
|
selector->ev_loop = 0;
|
111
123
|
|
@@ -118,14 +130,21 @@ static VALUE NIO_Selector_allocate(VALUE klass)
|
|
118
130
|
selector->wakeup.data = (void *)selector;
|
119
131
|
|
120
132
|
selector->closed = selector->selecting = selector->wakeup_fired = selector->ready_count = 0;
|
121
|
-
selector->ready_array
|
133
|
+
RB_OBJ_WRITE(obj, &selector->ready_array, Qnil);
|
134
|
+
return obj;
|
135
|
+
}
|
122
136
|
|
123
|
-
|
137
|
+
struct NIO_Selector *NIO_Selector_unwrap(VALUE self)
|
138
|
+
{
|
139
|
+
struct NIO_Selector *selector;
|
140
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
141
|
+
return selector;
|
124
142
|
}
|
125
143
|
|
126
144
|
/* NIO selectors store all Ruby objects in instance variables so mark is a stub */
|
127
|
-
static void NIO_Selector_mark(
|
145
|
+
static void NIO_Selector_mark(void *data)
|
128
146
|
{
|
147
|
+
struct NIO_Selector *selector = (struct NIO_Selector *)data;
|
129
148
|
if (selector->ready_array != Qnil) {
|
130
149
|
rb_gc_mark(selector->ready_array);
|
131
150
|
}
|
@@ -151,12 +170,18 @@ static void NIO_Selector_shutdown(struct NIO_Selector *selector)
|
|
151
170
|
}
|
152
171
|
|
153
172
|
/* Ruby finalizer for selector objects */
|
154
|
-
static void NIO_Selector_free(
|
173
|
+
static void NIO_Selector_free(void *data)
|
155
174
|
{
|
175
|
+
struct NIO_Selector *selector = (struct NIO_Selector *)data;
|
156
176
|
NIO_Selector_shutdown(selector);
|
157
177
|
xfree(selector);
|
158
178
|
}
|
159
179
|
|
180
|
+
static size_t NIO_Selector_memsize(const void *data)
|
181
|
+
{
|
182
|
+
return sizeof(struct NIO_Selector);
|
183
|
+
}
|
184
|
+
|
160
185
|
/* Return an array of symbols for supported backends */
|
161
186
|
static VALUE NIO_Selector_supported_backends(VALUE klass)
|
162
187
|
{
|
@@ -205,7 +230,7 @@ static VALUE NIO_Selector_initialize(int argc, VALUE *argv, VALUE self)
|
|
205
230
|
struct NIO_Selector *selector;
|
206
231
|
unsigned int flags = 0;
|
207
232
|
|
208
|
-
|
233
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
209
234
|
|
210
235
|
rb_scan_args(argc, argv, "01", &backend);
|
211
236
|
|
@@ -259,7 +284,7 @@ static VALUE NIO_Selector_backend(VALUE self)
|
|
259
284
|
{
|
260
285
|
struct NIO_Selector *selector;
|
261
286
|
|
262
|
-
|
287
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
263
288
|
if (selector->closed) {
|
264
289
|
rb_raise(rb_eIOError, "selector is closed");
|
265
290
|
}
|
@@ -285,7 +310,7 @@ static VALUE NIO_Selector_backend(VALUE self)
|
|
285
310
|
}
|
286
311
|
|
287
312
|
/* Synchronize around a reentrant selector lock */
|
288
|
-
static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE
|
313
|
+
static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE arg), VALUE arg)
|
289
314
|
{
|
290
315
|
VALUE current_thread, lock_holder, lock;
|
291
316
|
|
@@ -298,10 +323,10 @@ static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE *args), VA
|
|
298
323
|
rb_ivar_set(self, rb_intern("lock_holder"), current_thread);
|
299
324
|
|
300
325
|
/* We've acquired the lock, so ensure we unlock it */
|
301
|
-
return rb_ensure(func, (VALUE)
|
326
|
+
return rb_ensure(func, (VALUE)arg, NIO_Selector_unlock, self);
|
302
327
|
} else {
|
303
328
|
/* We already hold the selector lock, so no need to unlock it */
|
304
|
-
return func(
|
329
|
+
return func(arg);
|
305
330
|
}
|
306
331
|
}
|
307
332
|
|
@@ -321,22 +346,23 @@ static VALUE NIO_Selector_unlock(VALUE self)
|
|
321
346
|
/* Register an IO object with the selector for the given interests */
|
322
347
|
static VALUE NIO_Selector_register(VALUE self, VALUE io, VALUE interests)
|
323
348
|
{
|
324
|
-
VALUE args[3] = {
|
325
|
-
return NIO_Selector_synchronize(self, NIO_Selector_register_synchronized, args);
|
349
|
+
VALUE args[3] = {self, io, interests};
|
350
|
+
return NIO_Selector_synchronize(self, NIO_Selector_register_synchronized, (VALUE)args);
|
326
351
|
}
|
327
352
|
|
328
353
|
/* Internal implementation of register after acquiring mutex */
|
329
|
-
static VALUE NIO_Selector_register_synchronized(VALUE
|
354
|
+
static VALUE NIO_Selector_register_synchronized(VALUE _args)
|
330
355
|
{
|
331
356
|
VALUE self, io, interests, selectables, monitor;
|
332
357
|
VALUE monitor_args[3];
|
333
358
|
struct NIO_Selector *selector;
|
334
359
|
|
360
|
+
VALUE *args = (VALUE *)_args;
|
335
361
|
self = args[0];
|
336
362
|
io = args[1];
|
337
363
|
interests = args[2];
|
338
364
|
|
339
|
-
|
365
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
340
366
|
if (selector->closed) {
|
341
367
|
rb_raise(rb_eIOError, "selector is closed");
|
342
368
|
}
|
@@ -361,15 +387,16 @@ static VALUE NIO_Selector_register_synchronized(VALUE *args)
|
|
361
387
|
/* Deregister an IO object from the selector */
|
362
388
|
static VALUE NIO_Selector_deregister(VALUE self, VALUE io)
|
363
389
|
{
|
364
|
-
VALUE args[2] = {
|
365
|
-
return NIO_Selector_synchronize(self, NIO_Selector_deregister_synchronized, args);
|
390
|
+
VALUE args[2] = {self, io};
|
391
|
+
return NIO_Selector_synchronize(self, NIO_Selector_deregister_synchronized, (VALUE)args);
|
366
392
|
}
|
367
393
|
|
368
394
|
/* Internal implementation of register after acquiring mutex */
|
369
|
-
static VALUE NIO_Selector_deregister_synchronized(VALUE
|
395
|
+
static VALUE NIO_Selector_deregister_synchronized(VALUE _args)
|
370
396
|
{
|
371
397
|
VALUE self, io, selectables, monitor;
|
372
398
|
|
399
|
+
VALUE *args = (VALUE *)_args;
|
373
400
|
self = args[0];
|
374
401
|
io = args[1];
|
375
402
|
|
@@ -396,7 +423,6 @@ static VALUE NIO_Selector_is_registered(VALUE self, VALUE io)
|
|
396
423
|
static VALUE NIO_Selector_select(int argc, VALUE *argv, VALUE self)
|
397
424
|
{
|
398
425
|
VALUE timeout;
|
399
|
-
VALUE args[2];
|
400
426
|
|
401
427
|
rb_scan_args(argc, argv, "01", &timeout);
|
402
428
|
|
@@ -404,27 +430,27 @@ static VALUE NIO_Selector_select(int argc, VALUE *argv, VALUE self)
|
|
404
430
|
rb_raise(rb_eArgError, "time interval must be positive");
|
405
431
|
}
|
406
432
|
|
407
|
-
args[
|
408
|
-
|
409
|
-
|
410
|
-
return NIO_Selector_synchronize(self, NIO_Selector_select_synchronized, args);
|
433
|
+
VALUE args[2] = {self, timeout};
|
434
|
+
return NIO_Selector_synchronize(self, NIO_Selector_select_synchronized, (VALUE)args);
|
411
435
|
}
|
412
436
|
|
413
437
|
/* Internal implementation of select with the selector lock held */
|
414
|
-
static VALUE NIO_Selector_select_synchronized(VALUE
|
438
|
+
static VALUE NIO_Selector_select_synchronized(VALUE _args)
|
415
439
|
{
|
416
440
|
int ready;
|
417
441
|
VALUE ready_array;
|
418
442
|
struct NIO_Selector *selector;
|
419
443
|
|
420
|
-
|
444
|
+
VALUE *args = (VALUE *)_args;
|
445
|
+
|
446
|
+
TypedData_Get_Struct(args[0], struct NIO_Selector, &NIO_Selector_type, selector);
|
421
447
|
|
422
448
|
if (selector->closed) {
|
423
449
|
rb_raise(rb_eIOError, "selector is closed");
|
424
450
|
}
|
425
451
|
|
426
452
|
if (!rb_block_given_p()) {
|
427
|
-
selector->ready_array
|
453
|
+
RB_OBJ_WRITE(args[0], &selector->ready_array, rb_ary_new());
|
428
454
|
}
|
429
455
|
|
430
456
|
ready = NIO_Selector_run(selector, args[1]);
|
@@ -432,7 +458,7 @@ static VALUE NIO_Selector_select_synchronized(VALUE *args)
|
|
432
458
|
/* Timeout */
|
433
459
|
if (ready < 0) {
|
434
460
|
if (!rb_block_given_p()) {
|
435
|
-
selector->ready_array
|
461
|
+
RB_OBJ_WRITE(args[0], &selector->ready_array, Qnil);
|
436
462
|
}
|
437
463
|
|
438
464
|
return Qnil;
|
@@ -442,7 +468,7 @@ static VALUE NIO_Selector_select_synchronized(VALUE *args)
|
|
442
468
|
return INT2NUM(ready);
|
443
469
|
} else {
|
444
470
|
ready_array = selector->ready_array;
|
445
|
-
selector->ready_array
|
471
|
+
RB_OBJ_WRITE(args[0], &selector->ready_array, Qnil);
|
446
472
|
return ready_array;
|
447
473
|
}
|
448
474
|
}
|
@@ -489,7 +515,7 @@ static int NIO_Selector_run(struct NIO_Selector *selector, VALUE timeout)
|
|
489
515
|
static VALUE NIO_Selector_wakeup(VALUE self)
|
490
516
|
{
|
491
517
|
struct NIO_Selector *selector;
|
492
|
-
|
518
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
493
519
|
|
494
520
|
if (selector->closed) {
|
495
521
|
rb_raise(rb_eIOError, "selector is closed");
|
@@ -504,15 +530,14 @@ static VALUE NIO_Selector_wakeup(VALUE self)
|
|
504
530
|
/* Close the selector and free system resources */
|
505
531
|
static VALUE NIO_Selector_close(VALUE self)
|
506
532
|
{
|
507
|
-
|
508
|
-
return NIO_Selector_synchronize(self, NIO_Selector_close_synchronized, args);
|
533
|
+
return NIO_Selector_synchronize(self, NIO_Selector_close_synchronized, self);
|
509
534
|
}
|
510
535
|
|
511
|
-
static VALUE NIO_Selector_close_synchronized(VALUE
|
536
|
+
static VALUE NIO_Selector_close_synchronized(VALUE self)
|
512
537
|
{
|
513
538
|
struct NIO_Selector *selector;
|
514
|
-
|
515
|
-
|
539
|
+
|
540
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
516
541
|
|
517
542
|
NIO_Selector_shutdown(selector);
|
518
543
|
|
@@ -522,15 +547,14 @@ static VALUE NIO_Selector_close_synchronized(VALUE *args)
|
|
522
547
|
/* Is the selector closed? */
|
523
548
|
static VALUE NIO_Selector_closed(VALUE self)
|
524
549
|
{
|
525
|
-
|
526
|
-
return NIO_Selector_synchronize(self, NIO_Selector_closed_synchronized, args);
|
550
|
+
return NIO_Selector_synchronize(self, NIO_Selector_closed_synchronized, self);
|
527
551
|
}
|
528
552
|
|
529
|
-
static VALUE NIO_Selector_closed_synchronized(VALUE
|
553
|
+
static VALUE NIO_Selector_closed_synchronized(VALUE self)
|
530
554
|
{
|
531
555
|
struct NIO_Selector *selector;
|
532
|
-
|
533
|
-
|
556
|
+
|
557
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
534
558
|
|
535
559
|
return selector->closed ? Qtrue : Qfalse;
|
536
560
|
}
|
data/lib/nio/bytebuffer.rb
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2016, by Upekshe Jayasekera.
|
5
|
+
# Copyright, 2016-2017, by Tony Arcieri.
|
6
|
+
# Copyright, 2020, by Thomas Dziedzic.
|
7
|
+
# Copyright, 2023, by Samuel Williams.
|
8
|
+
|
3
9
|
module NIO
|
4
10
|
# Efficient byte buffers for performant I/O operations
|
5
11
|
class ByteBuffer
|
data/lib/nio/monitor.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2011-2018, by Tony Arcieri.
|
5
|
+
# Copyright, 2015, by Upekshe Jayasekera.
|
6
|
+
# Copyright, 2015, by Vladimir Kochnev.
|
7
|
+
# Copyright, 2018-2023, by Samuel Williams.
|
8
|
+
# Copyright, 2019-2020, by Gregory Longtin.
|
9
|
+
|
3
10
|
module NIO
|
4
11
|
# Monitors watch IO objects for specific events
|
5
12
|
class Monitor
|
data/lib/nio/selector.rb
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2011-2017, by Tony Arcieri.
|
5
|
+
# Copyright, 2012, by Logan Bowers.
|
6
|
+
# Copyright, 2013, by Sadayuki Furuhashi.
|
7
|
+
# Copyright, 2013, by Stephen von Takach.
|
8
|
+
# Copyright, 2013, by Tim Carey-Smith.
|
9
|
+
# Copyright, 2013, by Ravil Bayramgalin.
|
10
|
+
# Copyright, 2014, by Sergey Avseyev.
|
11
|
+
# Copyright, 2014, by John Thornton.
|
12
|
+
# Copyright, 2015, by Vladimir Kochnev.
|
13
|
+
# Copyright, 2015, by Upekshe Jayasekera.
|
14
|
+
# Copyright, 2019-2020, by Gregory Longtin.
|
15
|
+
# Copyright, 2020-2021, by Joao Fernandes.
|
16
|
+
# Copyright, 2023, by Samuel Williams.
|
17
|
+
|
3
18
|
require "set"
|
4
19
|
|
5
20
|
module NIO
|
data/lib/nio/version.rb
CHANGED
data/lib/nio.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2011-2017, by Tony Arcieri.
|
5
|
+
# Copyright, 2013, by Stephen von Takach.
|
6
|
+
# Copyright, 2013, by Per Lundberg.
|
7
|
+
# Copyright, 2014, by Marek Kowalcze.
|
8
|
+
# Copyright, 2016, by Upekshe Jayasekera.
|
9
|
+
# Copyright, 2019-2023, by Samuel Williams.
|
10
|
+
# Copyright, 2021, by Jun Jiang.
|
11
|
+
|
3
12
|
require "socket"
|
4
13
|
require "nio/version"
|
5
14
|
|
data/lib/nio4r.rb
ADDED
data/license.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# MIT License
|
2
|
+
|
3
|
+
Copyright, 2011-2020, by Tony Arcieri.
|
4
|
+
Copyright, 2012, by Bernd Ahlers.
|
5
|
+
Copyright, 2012, by Logan Bowers.
|
6
|
+
Copyright, 2012, by Dirkjan Bussink.
|
7
|
+
Copyright, 2013, by Sadayuki Furuhashi.
|
8
|
+
Copyright, 2013, by Shannon Skipper.
|
9
|
+
Copyright, 2013, by Stephen von Takach.
|
10
|
+
Copyright, 2013, by Tim Carey-Smith.
|
11
|
+
Copyright, 2013, by Per Lundberg.
|
12
|
+
Copyright, 2013, by Ravil Bayramgalin.
|
13
|
+
Copyright, 2013, by Luis Lavena.
|
14
|
+
Copyright, 2014, by Anatol Pomozov.
|
15
|
+
Copyright, 2014, by Hiroshi Shibata.
|
16
|
+
Copyright, 2014, by Marek Kowalcze.
|
17
|
+
Copyright, 2014, by Sergey Avseyev.
|
18
|
+
Copyright, 2014, by John Thornton.
|
19
|
+
Copyright, 2015-2017, by Tiago Cardoso.
|
20
|
+
Copyright, 2015, by Daniel Berger.
|
21
|
+
Copyright, 2015-2016, by Upekshe Jayasekera.
|
22
|
+
Copyright, 2015, by Vladimir Kochnev.
|
23
|
+
Copyright, 2016-2018, by Jun Aruga.
|
24
|
+
Copyright, 2016, by Omer Katz.
|
25
|
+
Copyright, 2016, by Denis Washington.
|
26
|
+
Copyright, 2016-2021, by Olle Jonsson.
|
27
|
+
Copyright, 2017, by Tao Luo.
|
28
|
+
Copyright, 2017, by Usaku Nakamura.
|
29
|
+
Copyright, 2017-2022, by Gregory Longtin.
|
30
|
+
Copyright, 2017, by Lars Kanis.
|
31
|
+
Copyright, 2017, by Tomoya Ishida.
|
32
|
+
Copyright, 2018-2023, by Samuel Williams.
|
33
|
+
Copyright, 2019, by Cédric Boutillier.
|
34
|
+
Copyright, 2019-2020, by Benoit Daloze.
|
35
|
+
Copyright, 2019, by Jesús Burgos Maciá.
|
36
|
+
Copyright, 2019, by Thomas Kuntz.
|
37
|
+
Copyright, 2019, by Orien Madgwick.
|
38
|
+
Copyright, 2019, by Zhang Kang.
|
39
|
+
Copyright, 2020, by Thomas Dziedzic.
|
40
|
+
Copyright, 2020, by Elad Eyal.
|
41
|
+
Copyright, 2020, by Pedro Paiva.
|
42
|
+
Copyright, 2020, by Boaz Segev.
|
43
|
+
Copyright, 2020, by Charles Oliver Nutter.
|
44
|
+
Copyright, 2020-2021, by Joao Fernandes.
|
45
|
+
Copyright, 2021, by Jun Jiang.
|
46
|
+
Copyright, 2021, by Pavel Lobashov.
|
47
|
+
Copyright, 2021, by Jeffrey Martin.
|
48
|
+
Copyright, 2023, by Pavel Rosický.
|
49
|
+
Copyright, 2023, by Tsimnuj Hawj.
|
50
|
+
Copyright, 2023, by Phillip Aldridge.
|
51
|
+
|
52
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
53
|
+
of this software and associated documentation files (the "Software"), to deal
|
54
|
+
in the Software without restriction, including without limitation the rights
|
55
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
56
|
+
copies of the Software, and to permit persons to whom the Software is
|
57
|
+
furnished to do so, subject to the following conditions:
|
58
|
+
|
59
|
+
The above copyright notice and this permission notice shall be included in all
|
60
|
+
copies or substantial portions of the Software.
|
61
|
+
|
62
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
63
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
64
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
65
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
66
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
67
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
68
|
+
SOFTWARE.
|
69
|
+
|
70
|
+
## libev
|
71
|
+
|
72
|
+
Released under the BSD-2-Clause OR GPL-2.0-or-later license.
|
73
|
+
See [ext/libev/LICENSE] for details.
|
74
|
+
|
75
|
+
Copyright, 2007-2019, by Marc Alexander Lehmann.
|
76
|
+
|
77
|
+
[ext/libev/LICENSE]: https://github.com/socketry/nio4r/blob/master/ext/libev/LICENSE
|