io-event 1.0.7 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/design.md +63 -0
- data/ext/extconf.rb +4 -0
- data/ext/io/event/selector/epoll.c +44 -10
- data/ext/io/event/selector/kqueue.c +40 -10
- data/ext/io/event/selector/selector.h +4 -0
- data/ext/io/event/selector/uring.c +36 -11
- data/lib/io/event/debug/selector.rb +16 -27
- data/lib/io/event/interrupt.rb +4 -19
- data/lib/io/event/selector/select.rb +84 -44
- data/lib/io/event/selector.rb +11 -23
- data/lib/io/event/support.rb +22 -0
- data/lib/io/event/version.rb +8 -21
- data/lib/io/event.rb +4 -19
- data/license.md +25 -0
- data/readme.md +23 -0
- data.tar.gz.sig +0 -0
- metadata +39 -5
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 529ab26d211811182c1ac8b7b292431533c830eddcfd8781185c9ea4ff623c93
|
4
|
+
data.tar.gz: cef3ea8d930d3f3f92e0c814c0f89405a78e3da1d4ebd6c0d1e73bd32f6839a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 77cd0725f41f507e391f54dae4071c9b2721a1fc4ce1c4dbcbf7b4dac8a7453c0e4867679b9f9c615d82ce06af2b3f77745b0d1526f0c6bb02cf06a60c84f763
|
7
|
+
data.tar.gz: 6d9a389303af3b13540ff2761d8e35762e3af975c7e1defddf8765088129f43dc4584029947bafd2a6eb35c60f8206b0dc184d425c52163d1652392e62bb9333
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data/design.md
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
## Dual `_select` without GVL:
|
2
|
+
|
3
|
+
Always release GVL:
|
4
|
+
|
5
|
+
```
|
6
|
+
Warming up --------------------------------------
|
7
|
+
KQueue 55.896k i/100ms
|
8
|
+
Select 17.023k i/100ms
|
9
|
+
Calculating -------------------------------------
|
10
|
+
KQueue 532.515k (± 8.0%) i/s - 2.683M in 5.071193s
|
11
|
+
Select 177.956k (± 3.4%) i/s - 902.219k in 5.075817s
|
12
|
+
|
13
|
+
Comparison:
|
14
|
+
KQueue: 532515.3 i/s
|
15
|
+
Select: 177956.1 i/s - 2.99x (± 0.00) slower
|
16
|
+
```
|
17
|
+
|
18
|
+
Only release GVL with non-zero timeout, with selector.elect(1) (so always hitting slow path):
|
19
|
+
|
20
|
+
```
|
21
|
+
Warming up --------------------------------------
|
22
|
+
KQueue 39.628k i/100ms
|
23
|
+
Select 18.330k i/100ms
|
24
|
+
Calculating -------------------------------------
|
25
|
+
KQueue 381.868k (± 6.5%) i/s - 1.902M in 5.004267s
|
26
|
+
Select 171.623k (± 3.0%) i/s - 861.510k in 5.024308s
|
27
|
+
|
28
|
+
Comparison:
|
29
|
+
KQueue: 381867.8 i/s
|
30
|
+
Select: 171622.5 i/s - 2.23x (± 0.00) slower
|
31
|
+
```
|
32
|
+
|
33
|
+
Only release GVL with non-zero timeout, with selector.select(0) so always hitting fast path:
|
34
|
+
|
35
|
+
```
|
36
|
+
Warming up --------------------------------------
|
37
|
+
KQueue 56.240k i/100ms
|
38
|
+
Select 17.888k i/100ms
|
39
|
+
Calculating -------------------------------------
|
40
|
+
KQueue 543.042k (± 7.8%) i/s - 2.700M in 5.003790s
|
41
|
+
Select 171.866k (± 4.3%) i/s - 858.624k in 5.005785s
|
42
|
+
|
43
|
+
Comparison:
|
44
|
+
KQueue: 543041.5 i/s
|
45
|
+
Select: 171866.2 i/s - 3.16x (± 0.00) slower
|
46
|
+
```
|
47
|
+
|
48
|
+
Only release GVL when no events are ready and non-zero timeout, with selector.select(1):
|
49
|
+
|
50
|
+
```
|
51
|
+
Warming up --------------------------------------
|
52
|
+
KQueue 53.401k i/100ms
|
53
|
+
Select 16.691k i/100ms
|
54
|
+
Calculating -------------------------------------
|
55
|
+
KQueue 524.564k (± 6.1%) i/s - 2.617M in 5.006996s
|
56
|
+
Select 179.329k (± 2.4%) i/s - 901.314k in 5.029136s
|
57
|
+
|
58
|
+
Comparison:
|
59
|
+
KQueue: 524564.0 i/s
|
60
|
+
Select: 179329.1 i/s - 2.93x (± 0.00) slower
|
61
|
+
```
|
62
|
+
|
63
|
+
So this approach seems to be a net win of about 1.5x throughput.
|
data/ext/extconf.rb
CHANGED
@@ -241,7 +241,7 @@ VALUE IO_Event_Selector_EPoll_process_wait(VALUE self, VALUE fiber, VALUE pid, V
|
|
241
241
|
rb_update_max_fd(process_wait_arguments.descriptor);
|
242
242
|
|
243
243
|
struct epoll_event event = {
|
244
|
-
.events = EPOLLIN|
|
244
|
+
.events = EPOLLIN|EPOLLERR|EPOLLHUP|EPOLLONESHOT,
|
245
245
|
.data = {.ptr = (void*)fiber},
|
246
246
|
};
|
247
247
|
|
@@ -385,7 +385,7 @@ VALUE IO_Event_Selector_EPoll_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE e
|
|
385
385
|
return rb_ensure(io_wait_transfer, (VALUE)&io_wait_arguments, io_wait_ensure, (VALUE)&io_wait_arguments);
|
386
386
|
}
|
387
387
|
|
388
|
-
#ifdef
|
388
|
+
#ifdef RUBY_FIBER_SCHEDULER_VERSION
|
389
389
|
|
390
390
|
struct io_read_arguments {
|
391
391
|
VALUE self;
|
@@ -398,6 +398,7 @@ struct io_read_arguments {
|
|
398
398
|
|
399
399
|
VALUE buffer;
|
400
400
|
size_t length;
|
401
|
+
size_t offset;
|
401
402
|
};
|
402
403
|
|
403
404
|
static
|
@@ -408,8 +409,8 @@ VALUE io_read_loop(VALUE _arguments) {
|
|
408
409
|
size_t size;
|
409
410
|
rb_io_buffer_get_bytes_for_writing(arguments->buffer, &base, &size);
|
410
411
|
|
411
|
-
size_t offset = 0;
|
412
412
|
size_t length = arguments->length;
|
413
|
+
size_t offset = arguments->offset;
|
413
414
|
|
414
415
|
while (true) {
|
415
416
|
size_t maximum_size = size - offset;
|
@@ -440,9 +441,10 @@ VALUE io_read_ensure(VALUE _arguments) {
|
|
440
441
|
return Qnil;
|
441
442
|
}
|
442
443
|
|
443
|
-
VALUE IO_Event_Selector_EPoll_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length) {
|
444
|
+
VALUE IO_Event_Selector_EPoll_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length, VALUE _offset) {
|
444
445
|
int descriptor = IO_Event_Selector_io_descriptor(io);
|
445
446
|
|
447
|
+
size_t offset = NUM2SIZET(_offset);
|
446
448
|
size_t length = NUM2SIZET(_length);
|
447
449
|
|
448
450
|
struct io_read_arguments io_read_arguments = {
|
@@ -454,11 +456,25 @@ VALUE IO_Event_Selector_EPoll_io_read(VALUE self, VALUE fiber, VALUE io, VALUE b
|
|
454
456
|
.descriptor = descriptor,
|
455
457
|
.buffer = buffer,
|
456
458
|
.length = length,
|
459
|
+
.offset = offset,
|
457
460
|
};
|
458
461
|
|
459
462
|
return rb_ensure(io_read_loop, (VALUE)&io_read_arguments, io_read_ensure, (VALUE)&io_read_arguments);
|
460
463
|
}
|
461
464
|
|
465
|
+
VALUE IO_Event_Selector_EPoll_io_read_compatible(int argc, VALUE *argv, VALUE self)
|
466
|
+
{
|
467
|
+
rb_check_arity(argc, 4, 5);
|
468
|
+
|
469
|
+
VALUE _offset = SIZET2NUM(0);
|
470
|
+
|
471
|
+
if (argc == 5) {
|
472
|
+
_offset = argv[4];
|
473
|
+
}
|
474
|
+
|
475
|
+
return IO_Event_Selector_EPoll_io_read(self, argv[0], argv[1], argv[2], argv[3], _offset);
|
476
|
+
}
|
477
|
+
|
462
478
|
struct io_write_arguments {
|
463
479
|
VALUE self;
|
464
480
|
VALUE fiber;
|
@@ -470,6 +486,7 @@ struct io_write_arguments {
|
|
470
486
|
|
471
487
|
VALUE buffer;
|
472
488
|
size_t length;
|
489
|
+
size_t offset;
|
473
490
|
};
|
474
491
|
|
475
492
|
static
|
@@ -480,8 +497,8 @@ VALUE io_write_loop(VALUE _arguments) {
|
|
480
497
|
size_t size;
|
481
498
|
rb_io_buffer_get_bytes_for_reading(arguments->buffer, &base, &size);
|
482
499
|
|
483
|
-
size_t offset = 0;
|
484
500
|
size_t length = arguments->length;
|
501
|
+
size_t offset = arguments->offset;
|
485
502
|
|
486
503
|
if (length > size) {
|
487
504
|
rb_raise(rb_eRuntimeError, "Length exceeds size of buffer!");
|
@@ -516,10 +533,11 @@ VALUE io_write_ensure(VALUE _arguments) {
|
|
516
533
|
return Qnil;
|
517
534
|
};
|
518
535
|
|
519
|
-
VALUE IO_Event_Selector_EPoll_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length) {
|
536
|
+
VALUE IO_Event_Selector_EPoll_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length, VALUE _offset) {
|
520
537
|
int descriptor = IO_Event_Selector_io_descriptor(io);
|
521
538
|
|
522
539
|
size_t length = NUM2SIZET(_length);
|
540
|
+
size_t offset = NUM2SIZET(_offset);
|
523
541
|
|
524
542
|
struct io_write_arguments io_write_arguments = {
|
525
543
|
.self = self,
|
@@ -530,11 +548,25 @@ VALUE IO_Event_Selector_EPoll_io_write(VALUE self, VALUE fiber, VALUE io, VALUE
|
|
530
548
|
.descriptor = descriptor,
|
531
549
|
.buffer = buffer,
|
532
550
|
.length = length,
|
551
|
+
.offset = offset,
|
533
552
|
};
|
534
553
|
|
535
554
|
return rb_ensure(io_write_loop, (VALUE)&io_write_arguments, io_write_ensure, (VALUE)&io_write_arguments);
|
536
555
|
}
|
537
556
|
|
557
|
+
VALUE IO_Event_Selector_EPoll_io_write_compatible(int argc, VALUE *argv, VALUE self)
|
558
|
+
{
|
559
|
+
rb_check_arity(argc, 4, 5);
|
560
|
+
|
561
|
+
VALUE _offset = SIZET2NUM(0);
|
562
|
+
|
563
|
+
if (argc == 5) {
|
564
|
+
_offset = argv[4];
|
565
|
+
}
|
566
|
+
|
567
|
+
return IO_Event_Selector_EPoll_io_write(self, argv[0], argv[1], argv[2], argv[3], _offset);
|
568
|
+
}
|
569
|
+
|
538
570
|
#endif
|
539
571
|
|
540
572
|
static
|
@@ -683,11 +715,13 @@ void Init_IO_Event_Selector_EPoll(VALUE IO_Event_Selector) {
|
|
683
715
|
rb_define_method(IO_Event_Selector_EPoll, "close", IO_Event_Selector_EPoll_close, 0);
|
684
716
|
|
685
717
|
rb_define_method(IO_Event_Selector_EPoll, "io_wait", IO_Event_Selector_EPoll_io_wait, 3);
|
718
|
+
|
719
|
+
rb_define_method(IO_Event_Selector_EPoll, "io_read", IO_Event_Selector_EPoll_io_read_compatible, -1);
|
720
|
+
rb_define_method(IO_Event_Selector_EPoll, "io_write", IO_Event_Selector_EPoll_io_write_compatible, -1);
|
686
721
|
|
687
|
-
|
688
|
-
rb_define_method(IO_Event_Selector_EPoll, "io_read", IO_Event_Selector_EPoll_io_read,
|
689
|
-
rb_define_method(IO_Event_Selector_EPoll, "io_write", IO_Event_Selector_EPoll_io_write,
|
690
|
-
#endif
|
722
|
+
// Once compatibility isn't a concern, we can do this:
|
723
|
+
// rb_define_method(IO_Event_Selector_EPoll, "io_read", IO_Event_Selector_EPoll_io_read, 5);
|
724
|
+
// rb_define_method(IO_Event_Selector_EPoll, "io_write", IO_Event_Selector_EPoll_io_write, 5);
|
691
725
|
|
692
726
|
rb_define_method(IO_Event_Selector_EPoll, "process_wait", IO_Event_Selector_EPoll_process_wait, 3);
|
693
727
|
}
|
@@ -380,7 +380,7 @@ VALUE IO_Event_Selector_KQueue_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE
|
|
380
380
|
return rb_rescue(io_wait_transfer, (VALUE)&io_wait_arguments, io_wait_rescue, (VALUE)&io_wait_arguments);
|
381
381
|
}
|
382
382
|
|
383
|
-
#ifdef
|
383
|
+
#ifdef RUBY_FIBER_SCHEDULER_VERSION
|
384
384
|
|
385
385
|
struct io_read_arguments {
|
386
386
|
VALUE self;
|
@@ -393,6 +393,7 @@ struct io_read_arguments {
|
|
393
393
|
|
394
394
|
VALUE buffer;
|
395
395
|
size_t length;
|
396
|
+
size_t offset;
|
396
397
|
};
|
397
398
|
|
398
399
|
static
|
@@ -403,8 +404,8 @@ VALUE io_read_loop(VALUE _arguments) {
|
|
403
404
|
size_t size;
|
404
405
|
rb_io_buffer_get_bytes_for_writing(arguments->buffer, &base, &size);
|
405
406
|
|
406
|
-
size_t offset = 0;
|
407
407
|
size_t length = arguments->length;
|
408
|
+
size_t offset = arguments->offset;
|
408
409
|
|
409
410
|
if (DEBUG_IO_READ) fprintf(stderr, "io_read_loop(fd=%d, length=%zu)\n", arguments->descriptor, length);
|
410
411
|
|
@@ -442,13 +443,14 @@ VALUE io_read_ensure(VALUE _arguments) {
|
|
442
443
|
return Qnil;
|
443
444
|
}
|
444
445
|
|
445
|
-
VALUE IO_Event_Selector_KQueue_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length) {
|
446
|
+
VALUE IO_Event_Selector_KQueue_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length, VALUE _offset) {
|
446
447
|
struct IO_Event_Selector_KQueue *data = NULL;
|
447
448
|
TypedData_Get_Struct(self, struct IO_Event_Selector_KQueue, &IO_Event_Selector_KQueue_Type, data);
|
448
449
|
|
449
450
|
int descriptor = IO_Event_Selector_io_descriptor(io);
|
450
451
|
|
451
452
|
size_t length = NUM2SIZET(_length);
|
453
|
+
size_t offset = NUM2SIZET(_offset);
|
452
454
|
|
453
455
|
struct io_read_arguments io_read_arguments = {
|
454
456
|
.self = self,
|
@@ -459,11 +461,25 @@ VALUE IO_Event_Selector_KQueue_io_read(VALUE self, VALUE fiber, VALUE io, VALUE
|
|
459
461
|
.descriptor = descriptor,
|
460
462
|
.buffer = buffer,
|
461
463
|
.length = length,
|
464
|
+
.offset = offset,
|
462
465
|
};
|
463
466
|
|
464
467
|
return rb_ensure(io_read_loop, (VALUE)&io_read_arguments, io_read_ensure, (VALUE)&io_read_arguments);
|
465
468
|
}
|
466
469
|
|
470
|
+
static VALUE IO_Event_Selector_KQueue_io_read_compatible(int argc, VALUE *argv, VALUE self)
|
471
|
+
{
|
472
|
+
rb_check_arity(argc, 4, 5);
|
473
|
+
|
474
|
+
VALUE _offset = SIZET2NUM(0);
|
475
|
+
|
476
|
+
if (argc == 5) {
|
477
|
+
_offset = argv[4];
|
478
|
+
}
|
479
|
+
|
480
|
+
return IO_Event_Selector_KQueue_io_read(self, argv[0], argv[1], argv[2], argv[3], _offset);
|
481
|
+
}
|
482
|
+
|
467
483
|
struct io_write_arguments {
|
468
484
|
VALUE self;
|
469
485
|
VALUE fiber;
|
@@ -475,6 +491,7 @@ struct io_write_arguments {
|
|
475
491
|
|
476
492
|
VALUE buffer;
|
477
493
|
size_t length;
|
494
|
+
size_t offset;
|
478
495
|
};
|
479
496
|
|
480
497
|
static
|
@@ -485,8 +502,8 @@ VALUE io_write_loop(VALUE _arguments) {
|
|
485
502
|
size_t size;
|
486
503
|
rb_io_buffer_get_bytes_for_reading(arguments->buffer, &base, &size);
|
487
504
|
|
488
|
-
size_t offset = 0;
|
489
505
|
size_t length = arguments->length;
|
506
|
+
size_t offset = arguments->offset;
|
490
507
|
|
491
508
|
if (length > size) {
|
492
509
|
rb_raise(rb_eRuntimeError, "Length exceeds size of buffer!");
|
@@ -528,13 +545,14 @@ VALUE io_write_ensure(VALUE _arguments) {
|
|
528
545
|
return Qnil;
|
529
546
|
};
|
530
547
|
|
531
|
-
VALUE IO_Event_Selector_KQueue_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length) {
|
548
|
+
VALUE IO_Event_Selector_KQueue_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length, VALUE _offset) {
|
532
549
|
struct IO_Event_Selector_KQueue *data = NULL;
|
533
550
|
TypedData_Get_Struct(self, struct IO_Event_Selector_KQueue, &IO_Event_Selector_KQueue_Type, data);
|
534
551
|
|
535
552
|
int descriptor = IO_Event_Selector_io_descriptor(io);
|
536
553
|
|
537
554
|
size_t length = NUM2SIZET(_length);
|
555
|
+
size_t offset = NUM2SIZET(_offset);
|
538
556
|
|
539
557
|
struct io_write_arguments io_write_arguments = {
|
540
558
|
.self = self,
|
@@ -545,11 +563,25 @@ VALUE IO_Event_Selector_KQueue_io_write(VALUE self, VALUE fiber, VALUE io, VALUE
|
|
545
563
|
.descriptor = descriptor,
|
546
564
|
.buffer = buffer,
|
547
565
|
.length = length,
|
566
|
+
.offset = offset,
|
548
567
|
};
|
549
568
|
|
550
569
|
return rb_ensure(io_write_loop, (VALUE)&io_write_arguments, io_write_ensure, (VALUE)&io_write_arguments);
|
551
570
|
}
|
552
571
|
|
572
|
+
static VALUE IO_Event_Selector_KQueue_io_write_compatible(int argc, VALUE *argv, VALUE self)
|
573
|
+
{
|
574
|
+
rb_check_arity(argc, 4, 5);
|
575
|
+
|
576
|
+
VALUE _offset = SIZET2NUM(0);
|
577
|
+
|
578
|
+
if (argc == 5) {
|
579
|
+
_offset = argv[4];
|
580
|
+
}
|
581
|
+
|
582
|
+
return IO_Event_Selector_KQueue_io_write(self, argv[0], argv[1], argv[2], argv[3], _offset);
|
583
|
+
}
|
584
|
+
|
553
585
|
#endif
|
554
586
|
|
555
587
|
static
|
@@ -732,11 +764,9 @@ void Init_IO_Event_Selector_KQueue(VALUE IO_Event_Selector) {
|
|
732
764
|
rb_define_method(IO_Event_Selector_KQueue, "close", IO_Event_Selector_KQueue_close, 0);
|
733
765
|
|
734
766
|
rb_define_method(IO_Event_Selector_KQueue, "io_wait", IO_Event_Selector_KQueue_io_wait, 3);
|
735
|
-
|
736
|
-
|
737
|
-
rb_define_method(IO_Event_Selector_KQueue, "
|
738
|
-
rb_define_method(IO_Event_Selector_KQueue, "io_write", IO_Event_Selector_KQueue_io_write, 4);
|
739
|
-
#endif
|
767
|
+
|
768
|
+
rb_define_method(IO_Event_Selector_KQueue, "io_read", IO_Event_Selector_KQueue_io_read_compatible, -1);
|
769
|
+
rb_define_method(IO_Event_Selector_KQueue, "io_write", IO_Event_Selector_KQueue_io_write_compatible, -1);
|
740
770
|
|
741
771
|
rb_define_method(IO_Event_Selector_KQueue, "process_wait", IO_Event_Selector_KQueue_process_wait, 3);
|
742
772
|
}
|
@@ -23,6 +23,7 @@
|
|
23
23
|
|
24
24
|
#include <liburing.h>
|
25
25
|
#include <poll.h>
|
26
|
+
#include <stdint.h>
|
26
27
|
#include <time.h>
|
27
28
|
|
28
29
|
#include "pidfd.c"
|
@@ -324,7 +325,7 @@ VALUE io_wait_rescue(VALUE _arguments, VALUE exception) {
|
|
324
325
|
|
325
326
|
if (DEBUG) fprintf(stderr, "io_wait_rescue:io_uring_prep_poll_remove(%p)\n", (void*)arguments->fiber);
|
326
327
|
|
327
|
-
io_uring_prep_poll_remove(sqe, (
|
328
|
+
io_uring_prep_poll_remove(sqe, (uintptr_t)arguments->fiber);
|
328
329
|
io_uring_submit_now(data);
|
329
330
|
|
330
331
|
rb_exc_raise(exception);
|
@@ -375,7 +376,7 @@ VALUE IO_Event_Selector_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE e
|
|
375
376
|
return rb_rescue(io_wait_transfer, (VALUE)&io_wait_arguments, io_wait_rescue, (VALUE)&io_wait_arguments);
|
376
377
|
}
|
377
378
|
|
378
|
-
#ifdef
|
379
|
+
#ifdef RUBY_FIBER_SCHEDULER_VERSION
|
379
380
|
|
380
381
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
|
381
382
|
static inline off_t io_seekable(int descriptor) {
|
@@ -408,7 +409,7 @@ static int io_read(struct IO_Event_Selector_URing *data, VALUE fiber, int descri
|
|
408
409
|
return RB_NUM2INT(result);
|
409
410
|
}
|
410
411
|
|
411
|
-
VALUE IO_Event_Selector_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length) {
|
412
|
+
VALUE IO_Event_Selector_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length, VALUE _offset) {
|
412
413
|
struct IO_Event_Selector_URing *data = NULL;
|
413
414
|
TypedData_Get_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, data);
|
414
415
|
|
@@ -418,8 +419,8 @@ VALUE IO_Event_Selector_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE b
|
|
418
419
|
size_t size;
|
419
420
|
rb_io_buffer_get_bytes_for_writing(buffer, &base, &size);
|
420
421
|
|
421
|
-
size_t offset = 0;
|
422
422
|
size_t length = NUM2SIZET(_length);
|
423
|
+
size_t offset = NUM2SIZET(_offset);
|
423
424
|
|
424
425
|
while (true) {
|
425
426
|
size_t maximum_size = size - offset;
|
@@ -443,6 +444,19 @@ VALUE IO_Event_Selector_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE b
|
|
443
444
|
return rb_fiber_scheduler_io_result(offset, 0);
|
444
445
|
}
|
445
446
|
|
447
|
+
static VALUE IO_Event_Selector_URing_io_read_compatible(int argc, VALUE *argv, VALUE self)
|
448
|
+
{
|
449
|
+
rb_check_arity(argc, 4, 5);
|
450
|
+
|
451
|
+
VALUE _offset = SIZET2NUM(0);
|
452
|
+
|
453
|
+
if (argc == 5) {
|
454
|
+
_offset = argv[4];
|
455
|
+
}
|
456
|
+
|
457
|
+
return IO_Event_Selector_URing_io_read(self, argv[0], argv[1], argv[2], argv[3], _offset);
|
458
|
+
}
|
459
|
+
|
446
460
|
static
|
447
461
|
int io_write(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length) {
|
448
462
|
struct io_uring_sqe *sqe = io_get_sqe(data);
|
@@ -459,7 +473,7 @@ int io_write(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor,
|
|
459
473
|
return result;
|
460
474
|
}
|
461
475
|
|
462
|
-
VALUE IO_Event_Selector_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length) {
|
476
|
+
VALUE IO_Event_Selector_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length, VALUE _offset) {
|
463
477
|
struct IO_Event_Selector_URing *data = NULL;
|
464
478
|
TypedData_Get_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, data);
|
465
479
|
|
@@ -469,8 +483,8 @@ VALUE IO_Event_Selector_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE
|
|
469
483
|
size_t size;
|
470
484
|
rb_io_buffer_get_bytes_for_reading(buffer, &base, &size);
|
471
485
|
|
472
|
-
size_t offset = 0;
|
473
486
|
size_t length = NUM2SIZET(_length);
|
487
|
+
size_t offset = NUM2SIZET(_offset);
|
474
488
|
|
475
489
|
if (length > size) {
|
476
490
|
rb_raise(rb_eRuntimeError, "Length exceeds size of buffer!");
|
@@ -496,6 +510,19 @@ VALUE IO_Event_Selector_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE
|
|
496
510
|
return rb_fiber_scheduler_io_result(offset, 0);
|
497
511
|
}
|
498
512
|
|
513
|
+
static VALUE IO_Event_Selector_URing_io_write_compatible(int argc, VALUE *argv, VALUE self)
|
514
|
+
{
|
515
|
+
rb_check_arity(argc, 4, 5);
|
516
|
+
|
517
|
+
VALUE _offset = SIZET2NUM(0);
|
518
|
+
|
519
|
+
if (argc == 5) {
|
520
|
+
_offset = argv[4];
|
521
|
+
}
|
522
|
+
|
523
|
+
return IO_Event_Selector_URing_io_write(self, argv[0], argv[1], argv[2], argv[3], _offset);
|
524
|
+
}
|
525
|
+
|
499
526
|
#endif
|
500
527
|
|
501
528
|
static const int ASYNC_CLOSE = 1;
|
@@ -710,11 +737,9 @@ void Init_IO_Event_Selector_URing(VALUE IO_Event_Selector) {
|
|
710
737
|
rb_define_method(IO_Event_Selector_URing, "close", IO_Event_Selector_URing_close, 0);
|
711
738
|
|
712
739
|
rb_define_method(IO_Event_Selector_URing, "io_wait", IO_Event_Selector_URing_io_wait, 3);
|
713
|
-
|
714
|
-
|
715
|
-
rb_define_method(IO_Event_Selector_URing, "
|
716
|
-
rb_define_method(IO_Event_Selector_URing, "io_write", IO_Event_Selector_URing_io_write, 4);
|
717
|
-
#endif
|
740
|
+
|
741
|
+
rb_define_method(IO_Event_Selector_URing, "io_read", IO_Event_Selector_URing_io_read_compatible, -1);
|
742
|
+
rb_define_method(IO_Event_Selector_URing, "io_write", IO_Event_Selector_URing_io_write_compatible, -1);
|
718
743
|
|
719
744
|
rb_define_method(IO_Event_Selector_URing, "io_close", IO_Event_Selector_URing_io_close, 1);
|
720
745
|
|
@@ -1,22 +1,9 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2021-2022, by Samuel Williams.
|
5
|
+
|
6
|
+
require_relative '../support'
|
20
7
|
|
21
8
|
module IO::Event
|
22
9
|
module Debug
|
@@ -80,14 +67,16 @@ module IO::Event
|
|
80
67
|
@selector.io_wait(fiber, io, events)
|
81
68
|
end
|
82
69
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
70
|
+
def io_read(...)
|
71
|
+
@selector.io_read(...)
|
72
|
+
end
|
73
|
+
|
74
|
+
def io_write(...)
|
75
|
+
@selector.io_write(...)
|
76
|
+
end
|
77
|
+
|
78
|
+
def respond_to?(name, include_private = false)
|
79
|
+
@selector.respond_to?(name, include_private)
|
91
80
|
end
|
92
81
|
|
93
82
|
def select(duration = nil)
|
data/lib/io/event/interrupt.rb
CHANGED
@@ -1,22 +1,7 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2021, by Samuel Williams.
|
20
5
|
|
21
6
|
module IO::Event
|
22
7
|
# A thread safe synchronisation primative.
|
@@ -1,24 +1,12 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2021-2022, by Samuel Williams.
|
20
5
|
|
21
6
|
require_relative '../interrupt'
|
7
|
+
require_relative '../support'
|
8
|
+
|
9
|
+
require 'io/nonblock'
|
22
10
|
|
23
11
|
module IO::Event
|
24
12
|
module Selector
|
@@ -36,7 +24,7 @@ module IO::Event
|
|
36
24
|
|
37
25
|
attr :loop
|
38
26
|
|
39
|
-
# If the event loop is currently
|
27
|
+
# If the event loop is currently sleeping, wake it up.
|
40
28
|
def wakeup
|
41
29
|
if @blocked
|
42
30
|
@interrupt.signal
|
@@ -148,11 +136,65 @@ module IO::Event
|
|
148
136
|
waiter&.invalidate
|
149
137
|
end
|
150
138
|
|
151
|
-
if
|
139
|
+
if Support.fiber_scheduler_v2?
|
152
140
|
EAGAIN = Errno::EAGAIN::Errno
|
153
141
|
|
154
|
-
def io_read(fiber, io, buffer, length)
|
155
|
-
|
142
|
+
def io_read(fiber, io, buffer, length, offset = 0)
|
143
|
+
total = 0
|
144
|
+
io.nonblock = true
|
145
|
+
|
146
|
+
while true
|
147
|
+
maximum_size = buffer.size - offset
|
148
|
+
result = Fiber.blocking{buffer.read(io, maximum_size, offset)}
|
149
|
+
|
150
|
+
if result == -EAGAIN
|
151
|
+
if length > 0
|
152
|
+
self.io_wait(fiber, io, IO::READABLE)
|
153
|
+
else
|
154
|
+
return result
|
155
|
+
end
|
156
|
+
elsif result < 0
|
157
|
+
return result
|
158
|
+
else
|
159
|
+
total += result
|
160
|
+
offset += result
|
161
|
+
break if total >= length
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
return total
|
166
|
+
end
|
167
|
+
|
168
|
+
def io_write(fiber, io, buffer, length, offset = 0)
|
169
|
+
total = 0
|
170
|
+
io.nonblock = true
|
171
|
+
|
172
|
+
while true
|
173
|
+
maximum_size = buffer.size - offset
|
174
|
+
result = Fiber.blocking{buffer.write(io, maximum_size, offset)}
|
175
|
+
|
176
|
+
if result == -EAGAIN
|
177
|
+
if length > 0
|
178
|
+
self.io_wait(fiber, io, IO::READABLE)
|
179
|
+
else
|
180
|
+
return result
|
181
|
+
end
|
182
|
+
elsif result < 0
|
183
|
+
return result
|
184
|
+
else
|
185
|
+
total += result
|
186
|
+
offset += result
|
187
|
+
break if total >= length
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
return offset
|
192
|
+
end
|
193
|
+
elsif Support.fiber_scheduler_v1?
|
194
|
+
EAGAIN = Errno::EAGAIN::Errno
|
195
|
+
|
196
|
+
def io_read(fiber, _io, buffer, length, offset = 0)
|
197
|
+
io = IO.for_fd(_io.fileno, autoclose: false)
|
156
198
|
|
157
199
|
while true
|
158
200
|
maximum_size = buffer.size - offset
|
@@ -185,8 +227,8 @@ module IO::Event
|
|
185
227
|
return offset
|
186
228
|
end
|
187
229
|
|
188
|
-
def io_write(fiber,
|
189
|
-
|
230
|
+
def io_write(fiber, _io, buffer, length, offset = 0)
|
231
|
+
io = IO.for_fd(_io.fileno, autoclose: false)
|
190
232
|
|
191
233
|
while true
|
192
234
|
maximum_size = buffer.size - offset
|
@@ -214,24 +256,17 @@ module IO::Event
|
|
214
256
|
|
215
257
|
return offset
|
216
258
|
end
|
259
|
+
|
260
|
+
def blocking(&block)
|
261
|
+
fiber = Fiber.new(blocking: true, &block)
|
262
|
+
return fiber.resume(fiber)
|
263
|
+
end
|
217
264
|
end
|
218
265
|
|
219
266
|
def process_wait(fiber, pid, flags)
|
220
|
-
|
221
|
-
|
222
|
-
thread = Thread.new do
|
267
|
+
Thread.new do
|
223
268
|
Process::Status.wait(pid, flags)
|
224
|
-
|
225
|
-
w.close
|
226
|
-
end
|
227
|
-
|
228
|
-
self.io_wait(fiber, r, IO::READABLE)
|
229
|
-
|
230
|
-
return thread.value
|
231
|
-
ensure
|
232
|
-
r.close
|
233
|
-
w.close
|
234
|
-
thread&.kill
|
269
|
+
end.value
|
235
270
|
end
|
236
271
|
|
237
272
|
private def pop_ready
|
@@ -255,6 +290,7 @@ module IO::Event
|
|
255
290
|
|
256
291
|
readable = Array.new
|
257
292
|
writable = Array.new
|
293
|
+
priority = Array.new
|
258
294
|
|
259
295
|
@waiting.each do |io, waiter|
|
260
296
|
waiter.each do |fiber, events|
|
@@ -265,12 +301,16 @@ module IO::Event
|
|
265
301
|
if (events & IO::WRITABLE) > 0
|
266
302
|
writable << io
|
267
303
|
end
|
304
|
+
|
305
|
+
if (events & IO::PRIORITY) > 0
|
306
|
+
priority << io
|
307
|
+
end
|
268
308
|
end
|
269
309
|
end
|
270
310
|
|
271
311
|
@blocked = true
|
272
312
|
duration = 0 unless @ready.empty?
|
273
|
-
readable, writable,
|
313
|
+
readable, writable, priority = ::IO.select(readable, writable, priority, duration)
|
274
314
|
@blocked = false
|
275
315
|
|
276
316
|
ready = Hash.new(0)
|
@@ -283,16 +323,16 @@ module IO::Event
|
|
283
323
|
ready[io] |= IO::WRITABLE
|
284
324
|
end
|
285
325
|
|
326
|
+
priority&.each do |io|
|
327
|
+
ready[io] |= IO::PRIORITY
|
328
|
+
end
|
329
|
+
|
286
330
|
ready.each do |io, events|
|
287
331
|
@waiting.delete(io).transfer(events)
|
288
332
|
end
|
289
333
|
|
290
334
|
return ready.size
|
291
335
|
end
|
292
|
-
|
293
|
-
private def blocking(&block)
|
294
|
-
Fiber.new(blocking: true, &block).resume
|
295
|
-
end
|
296
336
|
end
|
297
337
|
end
|
298
338
|
end
|
data/lib/io/event/selector.rb
CHANGED
@@ -1,25 +1,11 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2021-2022, by Samuel Williams.
|
20
5
|
|
21
6
|
require_relative 'selector/select'
|
22
7
|
require_relative 'debug/selector'
|
8
|
+
require_relative 'support'
|
23
9
|
|
24
10
|
module IO::Event
|
25
11
|
module Selector
|
@@ -32,12 +18,14 @@ module IO::Event
|
|
32
18
|
end
|
33
19
|
end
|
34
20
|
|
35
|
-
if self.const_defined?(:
|
36
|
-
|
21
|
+
if self.const_defined?(:URing)
|
22
|
+
URing
|
23
|
+
elsif self.const_defined?(:EPoll)
|
24
|
+
EPoll
|
37
25
|
elsif self.const_defined?(:KQueue)
|
38
|
-
|
26
|
+
KQueue
|
39
27
|
else
|
40
|
-
|
28
|
+
Select
|
41
29
|
end
|
42
30
|
end
|
43
31
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2022, by Samuel Williams.
|
5
|
+
|
6
|
+
class IO
|
7
|
+
module Event
|
8
|
+
module Support
|
9
|
+
def self.buffer?
|
10
|
+
IO.const_defined?(:Buffer)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.fiber_scheduler_v1?
|
14
|
+
IO.const_defined?(:Buffer) and !Fiber.respond_to?(:blocking)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.fiber_scheduler_v2?
|
18
|
+
IO.const_defined?(:Buffer) and Fiber.respond_to?(:blocking) and IO::Buffer.instance_method(:read).arity == -1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/io/event/version.rb
CHANGED
@@ -1,23 +1,10 @@
|
|
1
|
-
#
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
-
# of this software and associated documentation files (the "Software"), to deal
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
20
2
|
|
21
|
-
|
22
|
-
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2021-2022, by Samuel Williams.
|
5
|
+
|
6
|
+
class IO
|
7
|
+
module Event
|
8
|
+
VERSION = "1.1.0"
|
9
|
+
end
|
23
10
|
end
|
data/lib/io/event.rb
CHANGED
@@ -1,22 +1,7 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# in the Software without restriction, including without limitation the rights
|
6
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
-
# copies of the Software, and to permit persons to whom the Software is
|
8
|
-
# furnished to do so, subject to the following conditions:
|
9
|
-
#
|
10
|
-
# The above copyright notice and this permission notice shall be included in
|
11
|
-
# all copies or substantial portions of the Software.
|
12
|
-
#
|
13
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
-
# THE SOFTWARE.
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2021, by Samuel Williams.
|
20
5
|
|
21
6
|
require_relative 'event/version'
|
22
7
|
require_relative 'event/selector'
|
data/license.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# MIT License
|
2
|
+
|
3
|
+
Copyright, 2021-2022, by Samuel Williams.
|
4
|
+
Copyright, 2021, by Delton Ding.
|
5
|
+
Copyright, 2021, by Benoit Daloze.
|
6
|
+
Copyright, 2022, by Alex Matchneer.
|
7
|
+
Copyright, 2022, by Bruno Sutic.
|
8
|
+
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
11
|
+
in the Software without restriction, including without limitation the rights
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
14
|
+
furnished to do so, subject to the following conditions:
|
15
|
+
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
17
|
+
copies or substantial portions of the Software.
|
18
|
+
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
25
|
+
SOFTWARE.
|
data/readme.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# ![Event](logo.svg)
|
2
|
+
|
3
|
+
Provides low level cross-platform primitives for constructing event loops, with support for `select`, `kqueue`, `epoll` and `io_uring`.
|
4
|
+
|
5
|
+
[![Development Status](https://github.com/socketry/io-event/workflows/Test/badge.svg)](https://github.com/socketry/io-event/actions?workflow=Test)
|
6
|
+
|
7
|
+
## Motivation
|
8
|
+
|
9
|
+
The initial proof-of-concept [Async](https://github.com/socketry/async) was built on [NIO4r](https://github.com/socketry/nio4r). It was perfectly acceptable and well tested in production, however being built on `libev` was a little bit limiting. I wanted to directly built my fiber scheduler into the fabric of the event loop, which is what this gem exposes - it is specifically implemented to support building event loops beneath the fiber scheduler interface, providing an efficient C implementation of all the core operations.
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
Please see the [project documentation](https://socketry.github.io/io-event/).
|
14
|
+
|
15
|
+
## Contributing
|
16
|
+
|
17
|
+
We welcome contributions to this project.
|
18
|
+
|
19
|
+
1. Fork it
|
20
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
21
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
22
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
23
|
+
5. Create new Pull Request
|
data.tar.gz.sig
ADDED
Binary file
|
metadata
CHANGED
@@ -1,17 +1,47 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-event
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
|
-
-
|
8
|
+
- Bruno Sutic
|
9
9
|
- Benoit Daloze
|
10
10
|
- Delton Ding
|
11
|
+
- machty
|
11
12
|
autorequire:
|
12
13
|
bindir: bin
|
13
|
-
cert_chain:
|
14
|
-
|
14
|
+
cert_chain:
|
15
|
+
- |
|
16
|
+
-----BEGIN CERTIFICATE-----
|
17
|
+
MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
|
18
|
+
ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
|
19
|
+
CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
|
20
|
+
MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
|
21
|
+
MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
|
22
|
+
bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
|
23
|
+
igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
|
24
|
+
9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
|
25
|
+
sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
|
26
|
+
e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
|
27
|
+
XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
|
28
|
+
RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
|
29
|
+
tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
|
30
|
+
zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
|
31
|
+
xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
|
32
|
+
BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
|
33
|
+
aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
|
34
|
+
aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
|
35
|
+
cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
|
36
|
+
xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
|
37
|
+
c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
|
38
|
+
8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
|
39
|
+
JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
|
40
|
+
eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
|
41
|
+
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
42
|
+
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
43
|
+
-----END CERTIFICATE-----
|
44
|
+
date: 2022-10-13 00:00:00.000000000 Z
|
15
45
|
dependencies:
|
16
46
|
- !ruby/object:Gem::Dependency
|
17
47
|
name: bake
|
@@ -76,6 +106,7 @@ extensions:
|
|
76
106
|
- ext/extconf.rb
|
77
107
|
extra_rdoc_files: []
|
78
108
|
files:
|
109
|
+
- design.md
|
79
110
|
- ext/extconf.rb
|
80
111
|
- ext/io/event/event.c
|
81
112
|
- ext/io/event/event.h
|
@@ -95,7 +126,10 @@ files:
|
|
95
126
|
- lib/io/event/interrupt.rb
|
96
127
|
- lib/io/event/selector.rb
|
97
128
|
- lib/io/event/selector/select.rb
|
129
|
+
- lib/io/event/support.rb
|
98
130
|
- lib/io/event/version.rb
|
131
|
+
- license.md
|
132
|
+
- readme.md
|
99
133
|
homepage: https://github.com/socketry/io-event
|
100
134
|
licenses:
|
101
135
|
- MIT
|
@@ -115,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
149
|
- !ruby/object:Gem::Version
|
116
150
|
version: '0'
|
117
151
|
requirements: []
|
118
|
-
rubygems_version: 3.
|
152
|
+
rubygems_version: 3.3.7
|
119
153
|
signing_key:
|
120
154
|
specification_version: 4
|
121
155
|
summary: An event loop.
|
metadata.gz.sig
ADDED
Binary file
|