nio4r 2.5.4 → 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 +34 -16
- data/.mailmap +16 -0
- data/Gemfile +5 -5
- data/{CHANGES.md → changes.md} +54 -0
- data/examples/echo_server.rb +7 -0
- data/ext/libev/Changes +71 -2
- data/ext/libev/ev.c +611 -198
- data/ext/libev/ev.h +25 -22
- data/ext/libev/ev_epoll.c +16 -14
- data/ext/libev/ev_iouring.c +694 -0
- data/ext/libev/ev_kqueue.c +4 -4
- data/ext/libev/ev_linuxaio.c +78 -100
- data/ext/libev/ev_poll.c +6 -6
- data/ext/libev/ev_port.c +3 -3
- data/ext/libev/ev_select.c +6 -6
- data/ext/libev/ev_vars.h +34 -0
- data/ext/libev/ev_win32.c +2 -2
- data/ext/libev/ev_wrap.h +56 -0
- data/ext/nio4r/bytebuffer.c +75 -38
- data/ext/nio4r/extconf.rb +24 -1
- data/ext/nio4r/monitor.c +47 -22
- data/ext/nio4r/nio4r.h +1 -5
- data/ext/nio4r/org/nio4r/ByteBuffer.java +2 -0
- data/ext/nio4r/org/nio4r/Monitor.java +1 -0
- data/ext/nio4r/org/nio4r/Selector.java +8 -10
- data/ext/nio4r/selector.c +88 -48
- data/lib/nio/bytebuffer.rb +6 -0
- data/lib/nio/monitor.rb +7 -0
- data/lib/nio/selector.rb +26 -9
- data/lib/nio/version.rb +6 -1
- data/lib/nio.rb +29 -1
- 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 +16 -0
- data/spec/spec_helper.rb +7 -2
- data/spec/support/selectable_examples.rb +8 -0
- metadata +14 -9
- data/README.md +0 -132
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
|
{
|
@@ -183,6 +208,14 @@ static VALUE NIO_Selector_supported_backends(VALUE klass)
|
|
183
208
|
rb_ary_push(result, ID2SYM(rb_intern("port")));
|
184
209
|
}
|
185
210
|
|
211
|
+
if (backends & EVBACKEND_LINUXAIO) {
|
212
|
+
rb_ary_push(result, ID2SYM(rb_intern("linuxaio")));
|
213
|
+
}
|
214
|
+
|
215
|
+
if (backends & EVBACKEND_IOURING) {
|
216
|
+
rb_ary_push(result, ID2SYM(rb_intern("io_uring")));
|
217
|
+
}
|
218
|
+
|
186
219
|
return result;
|
187
220
|
}
|
188
221
|
|
@@ -197,7 +230,7 @@ static VALUE NIO_Selector_initialize(int argc, VALUE *argv, VALUE self)
|
|
197
230
|
struct NIO_Selector *selector;
|
198
231
|
unsigned int flags = 0;
|
199
232
|
|
200
|
-
|
233
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
201
234
|
|
202
235
|
rb_scan_args(argc, argv, "01", &backend);
|
203
236
|
|
@@ -218,6 +251,10 @@ static VALUE NIO_Selector_initialize(int argc, VALUE *argv, VALUE self)
|
|
218
251
|
flags = EVBACKEND_SELECT;
|
219
252
|
} else if (backend_id == rb_intern("port")) {
|
220
253
|
flags = EVBACKEND_PORT;
|
254
|
+
} else if (backend_id == rb_intern("linuxaio")) {
|
255
|
+
flags = EVBACKEND_LINUXAIO;
|
256
|
+
} else if (backend_id == rb_intern("io_uring")) {
|
257
|
+
flags = EVBACKEND_IOURING;
|
221
258
|
} else {
|
222
259
|
rb_raise(rb_eArgError, "unsupported backend: %s", RSTRING_PTR(rb_funcall(backend, rb_intern("inspect"), 0)));
|
223
260
|
}
|
@@ -247,7 +284,7 @@ static VALUE NIO_Selector_backend(VALUE self)
|
|
247
284
|
{
|
248
285
|
struct NIO_Selector *selector;
|
249
286
|
|
250
|
-
|
287
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
251
288
|
if (selector->closed) {
|
252
289
|
rb_raise(rb_eIOError, "selector is closed");
|
253
290
|
}
|
@@ -263,13 +300,17 @@ static VALUE NIO_Selector_backend(VALUE self)
|
|
263
300
|
return ID2SYM(rb_intern("select"));
|
264
301
|
case EVBACKEND_PORT:
|
265
302
|
return ID2SYM(rb_intern("port"));
|
303
|
+
case EVBACKEND_LINUXAIO:
|
304
|
+
return ID2SYM(rb_intern("linuxaio"));
|
305
|
+
case EVBACKEND_IOURING:
|
306
|
+
return ID2SYM(rb_intern("io_uring"));
|
266
307
|
}
|
267
308
|
|
268
309
|
return ID2SYM(rb_intern("unknown"));
|
269
310
|
}
|
270
311
|
|
271
312
|
/* Synchronize around a reentrant selector lock */
|
272
|
-
static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE
|
313
|
+
static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE arg), VALUE arg)
|
273
314
|
{
|
274
315
|
VALUE current_thread, lock_holder, lock;
|
275
316
|
|
@@ -282,10 +323,10 @@ static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE *args), VA
|
|
282
323
|
rb_ivar_set(self, rb_intern("lock_holder"), current_thread);
|
283
324
|
|
284
325
|
/* We've acquired the lock, so ensure we unlock it */
|
285
|
-
return rb_ensure(func, (VALUE)
|
326
|
+
return rb_ensure(func, (VALUE)arg, NIO_Selector_unlock, self);
|
286
327
|
} else {
|
287
328
|
/* We already hold the selector lock, so no need to unlock it */
|
288
|
-
return func(
|
329
|
+
return func(arg);
|
289
330
|
}
|
290
331
|
}
|
291
332
|
|
@@ -305,22 +346,23 @@ static VALUE NIO_Selector_unlock(VALUE self)
|
|
305
346
|
/* Register an IO object with the selector for the given interests */
|
306
347
|
static VALUE NIO_Selector_register(VALUE self, VALUE io, VALUE interests)
|
307
348
|
{
|
308
|
-
VALUE args[3] = {
|
309
|
-
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);
|
310
351
|
}
|
311
352
|
|
312
353
|
/* Internal implementation of register after acquiring mutex */
|
313
|
-
static VALUE NIO_Selector_register_synchronized(VALUE
|
354
|
+
static VALUE NIO_Selector_register_synchronized(VALUE _args)
|
314
355
|
{
|
315
356
|
VALUE self, io, interests, selectables, monitor;
|
316
357
|
VALUE monitor_args[3];
|
317
358
|
struct NIO_Selector *selector;
|
318
359
|
|
360
|
+
VALUE *args = (VALUE *)_args;
|
319
361
|
self = args[0];
|
320
362
|
io = args[1];
|
321
363
|
interests = args[2];
|
322
364
|
|
323
|
-
|
365
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
324
366
|
if (selector->closed) {
|
325
367
|
rb_raise(rb_eIOError, "selector is closed");
|
326
368
|
}
|
@@ -345,15 +387,16 @@ static VALUE NIO_Selector_register_synchronized(VALUE *args)
|
|
345
387
|
/* Deregister an IO object from the selector */
|
346
388
|
static VALUE NIO_Selector_deregister(VALUE self, VALUE io)
|
347
389
|
{
|
348
|
-
VALUE args[2] = {
|
349
|
-
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);
|
350
392
|
}
|
351
393
|
|
352
394
|
/* Internal implementation of register after acquiring mutex */
|
353
|
-
static VALUE NIO_Selector_deregister_synchronized(VALUE
|
395
|
+
static VALUE NIO_Selector_deregister_synchronized(VALUE _args)
|
354
396
|
{
|
355
397
|
VALUE self, io, selectables, monitor;
|
356
398
|
|
399
|
+
VALUE *args = (VALUE *)_args;
|
357
400
|
self = args[0];
|
358
401
|
io = args[1];
|
359
402
|
|
@@ -380,7 +423,6 @@ static VALUE NIO_Selector_is_registered(VALUE self, VALUE io)
|
|
380
423
|
static VALUE NIO_Selector_select(int argc, VALUE *argv, VALUE self)
|
381
424
|
{
|
382
425
|
VALUE timeout;
|
383
|
-
VALUE args[2];
|
384
426
|
|
385
427
|
rb_scan_args(argc, argv, "01", &timeout);
|
386
428
|
|
@@ -388,27 +430,27 @@ static VALUE NIO_Selector_select(int argc, VALUE *argv, VALUE self)
|
|
388
430
|
rb_raise(rb_eArgError, "time interval must be positive");
|
389
431
|
}
|
390
432
|
|
391
|
-
args[
|
392
|
-
|
393
|
-
|
394
|
-
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);
|
395
435
|
}
|
396
436
|
|
397
437
|
/* Internal implementation of select with the selector lock held */
|
398
|
-
static VALUE NIO_Selector_select_synchronized(VALUE
|
438
|
+
static VALUE NIO_Selector_select_synchronized(VALUE _args)
|
399
439
|
{
|
400
440
|
int ready;
|
401
441
|
VALUE ready_array;
|
402
442
|
struct NIO_Selector *selector;
|
403
443
|
|
404
|
-
|
444
|
+
VALUE *args = (VALUE *)_args;
|
445
|
+
|
446
|
+
TypedData_Get_Struct(args[0], struct NIO_Selector, &NIO_Selector_type, selector);
|
405
447
|
|
406
448
|
if (selector->closed) {
|
407
449
|
rb_raise(rb_eIOError, "selector is closed");
|
408
450
|
}
|
409
451
|
|
410
452
|
if (!rb_block_given_p()) {
|
411
|
-
selector->ready_array
|
453
|
+
RB_OBJ_WRITE(args[0], &selector->ready_array, rb_ary_new());
|
412
454
|
}
|
413
455
|
|
414
456
|
ready = NIO_Selector_run(selector, args[1]);
|
@@ -416,7 +458,7 @@ static VALUE NIO_Selector_select_synchronized(VALUE *args)
|
|
416
458
|
/* Timeout */
|
417
459
|
if (ready < 0) {
|
418
460
|
if (!rb_block_given_p()) {
|
419
|
-
selector->ready_array
|
461
|
+
RB_OBJ_WRITE(args[0], &selector->ready_array, Qnil);
|
420
462
|
}
|
421
463
|
|
422
464
|
return Qnil;
|
@@ -426,7 +468,7 @@ static VALUE NIO_Selector_select_synchronized(VALUE *args)
|
|
426
468
|
return INT2NUM(ready);
|
427
469
|
} else {
|
428
470
|
ready_array = selector->ready_array;
|
429
|
-
selector->ready_array
|
471
|
+
RB_OBJ_WRITE(args[0], &selector->ready_array, Qnil);
|
430
472
|
return ready_array;
|
431
473
|
}
|
432
474
|
}
|
@@ -473,7 +515,7 @@ static int NIO_Selector_run(struct NIO_Selector *selector, VALUE timeout)
|
|
473
515
|
static VALUE NIO_Selector_wakeup(VALUE self)
|
474
516
|
{
|
475
517
|
struct NIO_Selector *selector;
|
476
|
-
|
518
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
477
519
|
|
478
520
|
if (selector->closed) {
|
479
521
|
rb_raise(rb_eIOError, "selector is closed");
|
@@ -488,15 +530,14 @@ static VALUE NIO_Selector_wakeup(VALUE self)
|
|
488
530
|
/* Close the selector and free system resources */
|
489
531
|
static VALUE NIO_Selector_close(VALUE self)
|
490
532
|
{
|
491
|
-
|
492
|
-
return NIO_Selector_synchronize(self, NIO_Selector_close_synchronized, args);
|
533
|
+
return NIO_Selector_synchronize(self, NIO_Selector_close_synchronized, self);
|
493
534
|
}
|
494
535
|
|
495
|
-
static VALUE NIO_Selector_close_synchronized(VALUE
|
536
|
+
static VALUE NIO_Selector_close_synchronized(VALUE self)
|
496
537
|
{
|
497
538
|
struct NIO_Selector *selector;
|
498
|
-
|
499
|
-
|
539
|
+
|
540
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
500
541
|
|
501
542
|
NIO_Selector_shutdown(selector);
|
502
543
|
|
@@ -506,15 +547,14 @@ static VALUE NIO_Selector_close_synchronized(VALUE *args)
|
|
506
547
|
/* Is the selector closed? */
|
507
548
|
static VALUE NIO_Selector_closed(VALUE self)
|
508
549
|
{
|
509
|
-
|
510
|
-
return NIO_Selector_synchronize(self, NIO_Selector_closed_synchronized, args);
|
550
|
+
return NIO_Selector_synchronize(self, NIO_Selector_closed_synchronized, self);
|
511
551
|
}
|
512
552
|
|
513
|
-
static VALUE NIO_Selector_closed_synchronized(VALUE
|
553
|
+
static VALUE NIO_Selector_closed_synchronized(VALUE self)
|
514
554
|
{
|
515
555
|
struct NIO_Selector *selector;
|
516
|
-
|
517
|
-
|
556
|
+
|
557
|
+
TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
|
518
558
|
|
519
559
|
return selector->closed ? Qtrue : Qfalse;
|
520
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
|
@@ -14,7 +29,7 @@ module NIO
|
|
14
29
|
|
15
30
|
# Create a new NIO::Selector
|
16
31
|
def initialize(backend = :ruby)
|
17
|
-
raise ArgumentError, "unsupported backend: #{backend}" unless
|
32
|
+
raise ArgumentError, "unsupported backend: #{backend}" unless [:ruby, nil].include?(backend)
|
18
33
|
|
19
34
|
@selectables = {}
|
20
35
|
@lock = Mutex.new
|
@@ -26,14 +41,16 @@ module NIO
|
|
26
41
|
|
27
42
|
# Return a symbol representing the backend I/O multiplexing mechanism used.
|
28
43
|
# Supported backends are:
|
29
|
-
# * :ruby
|
30
|
-
# * :java
|
31
|
-
# * :epoll
|
32
|
-
# * :poll
|
33
|
-
# * :kqueue
|
34
|
-
# * :select
|
35
|
-
# * :port
|
36
|
-
# * :
|
44
|
+
# * :ruby - pure Ruby (i.e IO.select)
|
45
|
+
# * :java - Java NIO on JRuby
|
46
|
+
# * :epoll - libev w\ Linux epoll
|
47
|
+
# * :poll - libev w\ POSIX poll
|
48
|
+
# * :kqueue - libev w\ BSD kqueue
|
49
|
+
# * :select - libev w\ SysV select
|
50
|
+
# * :port - libev w\ I/O completion ports
|
51
|
+
# * :linuxaio - libev w\ Linux AIO io_submit (experimental)
|
52
|
+
# * :io_uring - libev w\ Linux io_uring (experimental)
|
53
|
+
# * :unknown - libev w\ unknown backend
|
37
54
|
def backend
|
38
55
|
:ruby
|
39
56
|
end
|
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
|
|
@@ -12,9 +21,28 @@ module NIO
|
|
12
21
|
def self.engine
|
13
22
|
ENGINE
|
14
23
|
end
|
24
|
+
|
25
|
+
def self.pure?(env = ENV)
|
26
|
+
# The user has explicitly opted in to non-native implementation:
|
27
|
+
if env["NIO4R_PURE"] == "true"
|
28
|
+
return true
|
29
|
+
end
|
30
|
+
|
31
|
+
# Native Ruby on Windows is not supported:
|
32
|
+
if (Gem.win_platform? && !defined?(JRUBY_VERSION))
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
|
36
|
+
# M1 native extension is crashing on M1 (arm64):
|
37
|
+
# if RUBY_PLATFORM =~ /darwin/ && RUBY_PLATFORM =~ /arm64/
|
38
|
+
# return true
|
39
|
+
# end
|
40
|
+
|
41
|
+
return false
|
42
|
+
end
|
15
43
|
end
|
16
44
|
|
17
|
-
if
|
45
|
+
if NIO.pure?
|
18
46
|
require "nio/monitor"
|
19
47
|
require "nio/selector"
|
20
48
|
require "nio/bytebuffer"
|
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
|
data/nio4r.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |spec|
|
|
6
6
|
spec.authors = ["Tony Arcieri"]
|
7
7
|
spec.email = ["bascule@gmail.com"]
|
8
8
|
spec.homepage = "https://github.com/socketry/nio4r"
|
9
|
-
spec.license = "MIT"
|
9
|
+
spec.license = "MIT AND (BSD-2-Clause OR GPL-2.0-or-later)"
|
10
10
|
spec.summary = "New IO for Ruby"
|
11
11
|
spec.description = <<-DESCRIPTION.strip.gsub(/\s+/, " ")
|
12
12
|
Cross-platform asynchronous I/O primitives for scalable network clients
|
@@ -22,10 +22,11 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.metadata = {
|
24
24
|
"bug_tracker_uri" => "https://github.com/socketry/nio4r/issues",
|
25
|
-
"changelog_uri" => "https://github.com/socketry/nio4r/blob/
|
25
|
+
"changelog_uri" => "https://github.com/socketry/nio4r/blob/main/changes.md",
|
26
26
|
"documentation_uri" => "https://www.rubydoc.info/gems/nio4r/#{spec.version}",
|
27
27
|
"source_code_uri" => "https://github.com/socketry/nio4r/tree/v#{spec.version}",
|
28
|
-
"wiki_uri" => "https://github.com/socketry/nio4r/wiki"
|
28
|
+
"wiki_uri" => "https://github.com/socketry/nio4r/wiki",
|
29
|
+
"funding_uri" => "https://github.com/sponsors/ioquatix/",
|
29
30
|
}
|
30
31
|
|
31
32
|
spec.required_ruby_version = ">= 2.4"
|
data/rakelib/extension.rake
CHANGED