nio4r 2.5.4 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/workflow.yml +34 -16
  3. data/.mailmap +16 -0
  4. data/Gemfile +5 -5
  5. data/{CHANGES.md → changes.md} +54 -0
  6. data/examples/echo_server.rb +7 -0
  7. data/ext/libev/Changes +71 -2
  8. data/ext/libev/ev.c +611 -198
  9. data/ext/libev/ev.h +25 -22
  10. data/ext/libev/ev_epoll.c +16 -14
  11. data/ext/libev/ev_iouring.c +694 -0
  12. data/ext/libev/ev_kqueue.c +4 -4
  13. data/ext/libev/ev_linuxaio.c +78 -100
  14. data/ext/libev/ev_poll.c +6 -6
  15. data/ext/libev/ev_port.c +3 -3
  16. data/ext/libev/ev_select.c +6 -6
  17. data/ext/libev/ev_vars.h +34 -0
  18. data/ext/libev/ev_win32.c +2 -2
  19. data/ext/libev/ev_wrap.h +56 -0
  20. data/ext/nio4r/bytebuffer.c +75 -38
  21. data/ext/nio4r/extconf.rb +24 -1
  22. data/ext/nio4r/monitor.c +47 -22
  23. data/ext/nio4r/nio4r.h +1 -5
  24. data/ext/nio4r/org/nio4r/ByteBuffer.java +2 -0
  25. data/ext/nio4r/org/nio4r/Monitor.java +1 -0
  26. data/ext/nio4r/org/nio4r/Selector.java +8 -10
  27. data/ext/nio4r/selector.c +88 -48
  28. data/lib/nio/bytebuffer.rb +6 -0
  29. data/lib/nio/monitor.rb +7 -0
  30. data/lib/nio/selector.rb +26 -9
  31. data/lib/nio/version.rb +6 -1
  32. data/lib/nio.rb +29 -1
  33. data/lib/nio4r.rb +5 -0
  34. data/license.md +77 -0
  35. data/nio4r.gemspec +4 -3
  36. data/rakelib/extension.rake +1 -2
  37. data/readme.md +91 -0
  38. data/spec/nio/acceptables_spec.rb +4 -0
  39. data/spec/nio/bytebuffer_spec.rb +6 -0
  40. data/spec/nio/monitor_spec.rb +7 -0
  41. data/spec/nio/selectables/pipe_spec.rb +6 -0
  42. data/spec/nio/selectables/ssl_socket_spec.rb +8 -3
  43. data/spec/nio/selectables/tcp_socket_spec.rb +7 -0
  44. data/spec/nio/selectables/udp_socket_spec.rb +7 -0
  45. data/spec/nio/selector_spec.rb +16 -0
  46. data/spec/spec_helper.rb +7 -2
  47. data/spec/support/selectable_examples.rb +8 -0
  48. metadata +14 -9
  49. 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(struct NIO_Selector *loop);
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(struct NIO_Selector *loop);
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 *args), VALUE *args);
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 *args);
49
- static VALUE NIO_Selector_deregister_synchronized(VALUE *args);
50
- static VALUE NIO_Selector_select_synchronized(VALUE *args);
51
- static VALUE NIO_Selector_close_synchronized(VALUE *args);
52
- static VALUE NIO_Selector_closed_synchronized(VALUE *args);
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
- selector = (struct NIO_Selector *)xmalloc(sizeof(struct NIO_Selector));
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 = Qnil;
133
+ RB_OBJ_WRITE(obj, &selector->ready_array, Qnil);
134
+ return obj;
135
+ }
122
136
 
123
- return Data_Wrap_Struct(klass, NIO_Selector_mark, NIO_Selector_free, selector);
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(struct NIO_Selector *selector)
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(struct NIO_Selector *selector)
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
- Data_Get_Struct(self, struct NIO_Selector, selector);
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
- Data_Get_Struct(self, struct NIO_Selector, selector);
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 *args), VALUE *args)
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)args, NIO_Selector_unlock, self);
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(args);
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] = { self, io, interests };
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 *args)
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
- Data_Get_Struct(self, struct NIO_Selector, selector);
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] = { self, io };
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 *args)
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[0] = self;
392
- args[1] = timeout;
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 *args)
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
- Data_Get_Struct(args[0], struct NIO_Selector, selector);
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 = rb_ary_new();
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 = Qnil;
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 = Qnil;
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
- Data_Get_Struct(self, struct NIO_Selector, selector);
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
- VALUE args[1] = { self };
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 *args)
536
+ static VALUE NIO_Selector_close_synchronized(VALUE self)
496
537
  {
497
538
  struct NIO_Selector *selector;
498
- VALUE self = args[0];
499
- Data_Get_Struct(self, struct NIO_Selector, selector);
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
- VALUE args[1] = { self };
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 *args)
553
+ static VALUE NIO_Selector_closed_synchronized(VALUE self)
514
554
  {
515
555
  struct NIO_Selector *selector;
516
- VALUE self = args[0];
517
- Data_Get_Struct(self, struct NIO_Selector, selector);
556
+
557
+ TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector);
518
558
 
519
559
  return selector->closed ? Qtrue : Qfalse;
520
560
  }
@@ -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 backend == :ruby
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 - pure Ruby (i.e IO.select)
30
- # * :java - Java NIO on JRuby
31
- # * :epoll - libev w\ Linux epoll
32
- # * :poll - libev w\ POSIX poll
33
- # * :kqueue - libev w\ BSD kqueue
34
- # * :select - libev w\ SysV select
35
- # * :port - libev w\ I/O completion ports
36
- # * :unknown - libev w\ unknown backend
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
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # Released under the MIT License.
4
+ # Copyright, 2011-2018, by Tony Arcieri.
5
+ # Copyright, 2018-2023, by Samuel Williams.
6
+ # Copyright, 2023, by Tsimnuj Hawj.
7
+
3
8
  module NIO
4
- VERSION = "2.5.4"
9
+ VERSION = "2.7.0"
5
10
  end
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 ENV["NIO4R_PURE"] == "true" || (Gem.win_platform? && !defined?(JRUBY_VERSION))
45
+ if NIO.pure?
18
46
  require "nio/monitor"
19
47
  require "nio/selector"
20
48
  require "nio/bytebuffer"
data/lib/nio4r.rb ADDED
@@ -0,0 +1,5 @@
1
+ # Released under the MIT License.
2
+ # Copyright, 2023, by Phillip Aldridge.
3
+ # Copyright, 2023, by Samuel Williams.
4
+
5
+ require_relative "nio"
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/master/CHANGES.md",
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"
@@ -4,8 +4,7 @@ if defined? JRUBY_VERSION
4
4
  require "rake/javaextensiontask"
5
5
  Rake::JavaExtensionTask.new("nio4r_ext") do |ext|
6
6
  ext.ext_dir = "ext/nio4r"
7
- ext.source_version = "1.8"
8
- ext.target_version = "1.8"
7
+ ext.release = '8'
9
8
  end
10
9
  else
11
10
  require "rake/extensiontask"