io-event 0.3.3 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/IO_Event.bundle +0 -0
- data/ext/event.o +0 -0
- data/ext/interrupt.o +0 -0
- data/ext/io/event/selector/epoll.c +17 -4
- data/ext/io/event/selector/kqueue.c +17 -4
- data/ext/io/event/selector/uring.c +28 -10
- data/ext/kqueue.o +0 -0
- data/ext/selector.o +0 -0
- data/lib/io/event/selector/select.rb +2 -2
- data/lib/io/event/selector.rb +2 -4
- data/lib/io/event/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92c441dcc5d0c1c052d12cca378cb86ed81ce156bbff09b8d699699424acb3e6
|
4
|
+
data.tar.gz: bd971d884cd6decd4b6e2b0de10248255d17161acb556a709f24aa732594eb32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b296a4cabf9c7db248139f23821bd9f43894269494c9f831dd0e56a67ab4b89e7346dcb7bb20c510a5067a2309e0372a743a862c548a7f781c84e3f6a51e4287
|
7
|
+
data.tar.gz: fd8df36184a53e494ec16e378721f0d35305c97b561e393821eae88d0c7b8775f04f9f883821530f07a2584525978a4c1c14912dba4f35cfe366638f396a82db
|
data/ext/IO_Event.bundle
CHANGED
Binary file
|
data/ext/event.o
CHANGED
Binary file
|
data/ext/interrupt.o
CHANGED
Binary file
|
@@ -299,6 +299,11 @@ VALUE io_wait_transfer(VALUE _arguments) {
|
|
299
299
|
|
300
300
|
VALUE result = IO_Event_Selector_fiber_transfer(arguments->data->backend.loop, 0, NULL);
|
301
301
|
|
302
|
+
// If the fiber is being cancelled, it might be resumed with nil:
|
303
|
+
if (!RTEST(result)) {
|
304
|
+
return Qfalse;
|
305
|
+
}
|
306
|
+
|
302
307
|
return INT2NUM(events_from_epoll_flags(NUM2INT(result)));
|
303
308
|
};
|
304
309
|
|
@@ -365,7 +370,7 @@ VALUE io_read_loop(VALUE _arguments) {
|
|
365
370
|
|
366
371
|
void *base;
|
367
372
|
size_t size;
|
368
|
-
|
373
|
+
rb_io_buffer_get_bytes_for_writing(arguments->buffer, &base, &size);
|
369
374
|
|
370
375
|
size_t offset = 0;
|
371
376
|
size_t length = arguments->length;
|
@@ -437,7 +442,7 @@ VALUE io_write_loop(VALUE _arguments) {
|
|
437
442
|
|
438
443
|
const void *base;
|
439
444
|
size_t size;
|
440
|
-
|
445
|
+
rb_io_buffer_get_bytes_for_reading(arguments->buffer, &base, &size);
|
441
446
|
|
442
447
|
size_t offset = 0;
|
443
448
|
size_t length = arguments->length;
|
@@ -540,7 +545,11 @@ void select_internal_without_gvl(struct select_arguments *arguments) {
|
|
540
545
|
arguments->data->blocked = 0;
|
541
546
|
|
542
547
|
if (arguments->count == -1) {
|
543
|
-
|
548
|
+
if (errno != EINTR) {
|
549
|
+
rb_sys_fail("select_internal_without_gvl:epoll_wait");
|
550
|
+
} else {
|
551
|
+
arguments->count = 0;
|
552
|
+
}
|
544
553
|
}
|
545
554
|
}
|
546
555
|
|
@@ -549,7 +558,11 @@ void select_internal_with_gvl(struct select_arguments *arguments) {
|
|
549
558
|
select_internal((void *)arguments);
|
550
559
|
|
551
560
|
if (arguments->count == -1) {
|
552
|
-
|
561
|
+
if (errno != EINTR) {
|
562
|
+
rb_sys_fail("select_internal_with_gvl:epoll_wait");
|
563
|
+
} else {
|
564
|
+
arguments->count = 0;
|
565
|
+
}
|
553
566
|
}
|
554
567
|
}
|
555
568
|
|
@@ -355,6 +355,11 @@ VALUE io_wait_transfer(VALUE _arguments) {
|
|
355
355
|
|
356
356
|
VALUE result = IO_Event_Selector_fiber_transfer(arguments->data->backend.loop, 0, NULL);
|
357
357
|
|
358
|
+
// If the fiber is being cancelled, it might be resumed with nil:
|
359
|
+
if (!RTEST(result)) {
|
360
|
+
return Qfalse;
|
361
|
+
}
|
362
|
+
|
358
363
|
return INT2NUM(events_from_kqueue_filter(RB_NUM2INT(result)));
|
359
364
|
}
|
360
365
|
|
@@ -396,7 +401,7 @@ VALUE io_read_loop(VALUE _arguments) {
|
|
396
401
|
|
397
402
|
void *base;
|
398
403
|
size_t size;
|
399
|
-
|
404
|
+
rb_io_buffer_get_bytes_for_writing(arguments->buffer, &base, &size);
|
400
405
|
|
401
406
|
size_t offset = 0;
|
402
407
|
size_t length = arguments->length;
|
@@ -478,7 +483,7 @@ VALUE io_write_loop(VALUE _arguments) {
|
|
478
483
|
|
479
484
|
const void *base;
|
480
485
|
size_t size;
|
481
|
-
|
486
|
+
rb_io_buffer_get_bytes_for_reading(arguments->buffer, &base, &size);
|
482
487
|
|
483
488
|
size_t offset = 0;
|
484
489
|
size_t length = arguments->length;
|
@@ -605,7 +610,11 @@ void select_internal_without_gvl(struct select_arguments *arguments) {
|
|
605
610
|
arguments->data->blocked = 0;
|
606
611
|
|
607
612
|
if (arguments->count == -1) {
|
608
|
-
|
613
|
+
if (errno != EINTR) {
|
614
|
+
rb_sys_fail("select_internal_without_gvl:kevent");
|
615
|
+
} else {
|
616
|
+
arguments->count = 0;
|
617
|
+
}
|
609
618
|
}
|
610
619
|
}
|
611
620
|
|
@@ -614,7 +623,11 @@ void select_internal_with_gvl(struct select_arguments *arguments) {
|
|
614
623
|
select_internal((void *)arguments);
|
615
624
|
|
616
625
|
if (arguments->count == -1) {
|
617
|
-
|
626
|
+
if (errno != EINTR) {
|
627
|
+
rb_sys_fail("select_internal_with_gvl:kevent");
|
628
|
+
} else {
|
629
|
+
arguments->count = 0;
|
630
|
+
}
|
618
631
|
}
|
619
632
|
}
|
620
633
|
|
@@ -27,6 +27,8 @@
|
|
27
27
|
|
28
28
|
#include "pidfd.c"
|
29
29
|
|
30
|
+
#include <linux/version.h>
|
31
|
+
|
30
32
|
enum {
|
31
33
|
DEBUG = 0,
|
32
34
|
DEBUG_IO_READ = 0,
|
@@ -336,6 +338,10 @@ VALUE io_wait_transfer(VALUE _arguments) {
|
|
336
338
|
VALUE result = IO_Event_Selector_fiber_transfer(data->backend.loop, 0, NULL);
|
337
339
|
if (DEBUG) fprintf(stderr, "io_wait:IO_Event_Selector_fiber_transfer -> %d\n", RB_NUM2INT(result));
|
338
340
|
|
341
|
+
if (!RTEST(result)) {
|
342
|
+
return Qfalse;
|
343
|
+
}
|
344
|
+
|
339
345
|
// We explicitly filter the resulting events based on the requested events.
|
340
346
|
// In some cases, poll will report events we didn't ask for.
|
341
347
|
short flags = arguments->flags & NUM2INT(result);
|
@@ -371,12 +377,28 @@ VALUE IO_Event_Selector_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE e
|
|
371
377
|
|
372
378
|
#ifdef HAVE_RUBY_IO_BUFFER_H
|
373
379
|
|
380
|
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
|
381
|
+
static inline off_t io_seekable(int descriptor) {
|
382
|
+
return -1;
|
383
|
+
}
|
384
|
+
#else
|
385
|
+
#warning Upgrade your kernel to 5.16! io_uring bugs prevent efficient io_read/io_write hooks.
|
386
|
+
static inline off_t io_seekable(int descriptor)
|
387
|
+
{
|
388
|
+
if (lseek(descriptor, 0, SEEK_CUR) == -1) {
|
389
|
+
return 0;
|
390
|
+
} else {
|
391
|
+
return -1;
|
392
|
+
}
|
393
|
+
}
|
394
|
+
#endif
|
395
|
+
|
374
396
|
static int io_read(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length) {
|
375
397
|
struct io_uring_sqe *sqe = io_get_sqe(data);
|
376
398
|
|
377
399
|
if (DEBUG) fprintf(stderr, "io_read:io_uring_prep_read(fiber=%p)\n", (void*)fiber);
|
378
400
|
|
379
|
-
io_uring_prep_read(sqe, descriptor, buffer, length,
|
401
|
+
io_uring_prep_read(sqe, descriptor, buffer, length, io_seekable(descriptor));
|
380
402
|
io_uring_sqe_set_data(sqe, (void*)fiber);
|
381
403
|
io_uring_submit_now(data);
|
382
404
|
|
@@ -394,7 +416,7 @@ VALUE IO_Event_Selector_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE b
|
|
394
416
|
|
395
417
|
void *base;
|
396
418
|
size_t size;
|
397
|
-
|
419
|
+
rb_io_buffer_get_bytes_for_writing(buffer, &base, &size);
|
398
420
|
|
399
421
|
size_t offset = 0;
|
400
422
|
size_t length = NUM2SIZET(_length);
|
@@ -427,7 +449,7 @@ int io_write(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor,
|
|
427
449
|
|
428
450
|
if (DEBUG) fprintf(stderr, "io_write:io_uring_prep_write(fiber=%p)\n", (void*)fiber);
|
429
451
|
|
430
|
-
io_uring_prep_write(sqe, descriptor, buffer, length,
|
452
|
+
io_uring_prep_write(sqe, descriptor, buffer, length, io_seekable(descriptor));
|
431
453
|
io_uring_sqe_set_data(sqe, (void*)fiber);
|
432
454
|
io_uring_submit_pending(data);
|
433
455
|
|
@@ -445,7 +467,7 @@ VALUE IO_Event_Selector_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE
|
|
445
467
|
|
446
468
|
const void *base;
|
447
469
|
size_t size;
|
448
|
-
|
470
|
+
rb_io_buffer_get_bytes_for_reading(buffer, &base, &size);
|
449
471
|
|
450
472
|
size_t offset = 0;
|
451
473
|
size_t length = NUM2SIZET(_length);
|
@@ -558,6 +580,8 @@ int select_internal_without_gvl(struct select_arguments *arguments) {
|
|
558
580
|
|
559
581
|
if (arguments->result == -ETIME) {
|
560
582
|
arguments->result = 0;
|
583
|
+
} else if (arguments->result == -EINTR) {
|
584
|
+
arguments->result = 0;
|
561
585
|
} else if (arguments->result < 0) {
|
562
586
|
rb_syserr_fail(-arguments->result, "select_internal_without_gvl:io_uring_wait_cqe_timeout");
|
563
587
|
} else {
|
@@ -568,8 +592,6 @@ int select_internal_without_gvl(struct select_arguments *arguments) {
|
|
568
592
|
return arguments->result;
|
569
593
|
}
|
570
594
|
|
571
|
-
// #define IO_EVENT_SELECTOR_URING_UDATA_INTERRUPT ((__u64) -2)
|
572
|
-
|
573
595
|
static inline
|
574
596
|
unsigned select_process_completions(struct io_uring *ring) {
|
575
597
|
unsigned completed = 0;
|
@@ -585,10 +607,6 @@ unsigned select_process_completions(struct io_uring *ring) {
|
|
585
607
|
continue;
|
586
608
|
}
|
587
609
|
|
588
|
-
// if (cqe->user_data == IO_EVENT_SELECTOR_URING_UDATA_INTERRUPT) {
|
589
|
-
// io_uring_cq_advance(ring, 1);
|
590
|
-
// }
|
591
|
-
|
592
610
|
VALUE fiber = (VALUE)cqe->user_data;
|
593
611
|
VALUE result = RB_INT2NUM(cqe->res);
|
594
612
|
|
data/ext/kqueue.o
CHANGED
Binary file
|
data/ext/selector.o
CHANGED
Binary file
|
@@ -158,7 +158,7 @@ module IO::Event
|
|
158
158
|
else
|
159
159
|
break unless result
|
160
160
|
|
161
|
-
buffer.
|
161
|
+
buffer.set_string(result, offset)
|
162
162
|
|
163
163
|
size = result.bytesize
|
164
164
|
offset += size
|
@@ -176,7 +176,7 @@ module IO::Event
|
|
176
176
|
while true
|
177
177
|
maximum_size = buffer.size - offset
|
178
178
|
|
179
|
-
chunk = buffer.
|
179
|
+
chunk = buffer.get_string(offset, maximum_size)
|
180
180
|
case result = blocking{io.write_nonblock(chunk, exception: false)}
|
181
181
|
when :wait_readable
|
182
182
|
if length > 0
|
data/lib/io/event/selector.rb
CHANGED
@@ -31,12 +31,10 @@ module IO::Event
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
if self.const_defined?(:
|
35
|
-
return
|
34
|
+
if self.const_defined?(:EPoll)
|
35
|
+
return EPoll
|
36
36
|
elsif self.const_defined?(:KQueue)
|
37
37
|
return KQueue
|
38
|
-
elsif self.const_defined?(:EPoll)
|
39
|
-
return EPoll
|
40
38
|
else
|
41
39
|
return Select
|
42
40
|
end
|
data/lib/io/event/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-event
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-12-
|
11
|
+
date: 2021-12-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bake
|
@@ -113,14 +113,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
113
|
requirements:
|
114
114
|
- - ">="
|
115
115
|
- !ruby/object:Gem::Version
|
116
|
-
version: '0'
|
116
|
+
version: '3.0'
|
117
117
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
118
|
requirements:
|
119
119
|
- - ">="
|
120
120
|
- !ruby/object:Gem::Version
|
121
121
|
version: '0'
|
122
122
|
requirements: []
|
123
|
-
rubygems_version: 3.3.
|
123
|
+
rubygems_version: 3.3.2
|
124
124
|
signing_key:
|
125
125
|
specification_version: 4
|
126
126
|
summary: An event loop.
|