io-event 1.1.5 → 1.1.7
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
- checksums.yaml.gz.sig +0 -0
- data/ext/extconf.rb +1 -1
- data/ext/io/event/selector/uring.c +138 -20
- data/lib/io/event/selector/nonblock.rb +3 -0
- data/lib/io/event/selector/select.rb +15 -7
- data/lib/io/event/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +3 -3
- 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: 0202b38104b1b6254a15fc12f687f9102509ba75592b1584d3dd5d0e44c497fb
|
4
|
+
data.tar.gz: 925de8b198ea2a9fca99b7c02c5262dd691a9864601c7db109a79c332804b944
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d0bb87512e17c8be8ca0b04390466b0c3de198c6ee4a4a0a074b31d8e2f3bb0f482ece3378d0d9653b9219d36f06d41882f4c78631b27f6c0fb02e4143688d33
|
7
|
+
data.tar.gz: 4403550628403eccfb92d60e44ccf096ecb2dee1f2e78917fbef65b8c49cc71b15db96b3074e5b16f0ce005f826db928e4a95fd1214973cf33509659195a2e9a
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/ext/extconf.rb
CHANGED
@@ -39,6 +39,8 @@ static VALUE IO_Event_Selector_URing = Qnil;
|
|
39
39
|
|
40
40
|
enum {URING_ENTRIES = 64};
|
41
41
|
|
42
|
+
#pragma mark - Data Type
|
43
|
+
|
42
44
|
struct IO_Event_Selector_URing {
|
43
45
|
struct IO_Event_Selector backend;
|
44
46
|
struct io_uring ring;
|
@@ -98,6 +100,8 @@ VALUE IO_Event_Selector_URing_allocate(VALUE self) {
|
|
98
100
|
return instance;
|
99
101
|
}
|
100
102
|
|
103
|
+
#pragma mark - Methods
|
104
|
+
|
101
105
|
VALUE IO_Event_Selector_URing_initialize(VALUE self, VALUE loop) {
|
102
106
|
struct IO_Event_Selector_URing *data = NULL;
|
103
107
|
TypedData_Get_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, data);
|
@@ -179,6 +183,9 @@ VALUE IO_Event_Selector_URing_ready_p(VALUE self) {
|
|
179
183
|
return data->backend.ready ? Qtrue : Qfalse;
|
180
184
|
}
|
181
185
|
|
186
|
+
#pragma mark - Submission Queue
|
187
|
+
|
188
|
+
// Flush the submission queue if pending operations are present.
|
182
189
|
static
|
183
190
|
int io_uring_submit_flush(struct IO_Event_Selector_URing *data) {
|
184
191
|
if (data->pending) {
|
@@ -200,8 +207,11 @@ int io_uring_submit_flush(struct IO_Event_Selector_URing *data) {
|
|
200
207
|
return 0;
|
201
208
|
}
|
202
209
|
|
210
|
+
// Immediately flush the submission queue, yielding to the event loop if it was not successful.
|
203
211
|
static
|
204
212
|
int io_uring_submit_now(struct IO_Event_Selector_URing *data) {
|
213
|
+
if (DEBUG && data->pending) fprintf(stderr, "io_uring_submit_now(pending=%ld)\n", data->pending);
|
214
|
+
|
205
215
|
while (true) {
|
206
216
|
int result = io_uring_submit(&data->ring);
|
207
217
|
|
@@ -218,9 +228,12 @@ int io_uring_submit_now(struct IO_Event_Selector_URing *data) {
|
|
218
228
|
}
|
219
229
|
}
|
220
230
|
|
231
|
+
// Submit a pending operation. This does not submit the operation immediately, but instead defers it to the next call to `io_uring_submit_flush` or `io_uring_submit_now`. This is useful for operations that are not urgent, but should be used with care as it can lead to a deadlock if the submission queue is not flushed.
|
221
232
|
static
|
222
233
|
void io_uring_submit_pending(struct IO_Event_Selector_URing *data) {
|
223
234
|
data->pending += 1;
|
235
|
+
|
236
|
+
if (DEBUG) fprintf(stderr, "io_uring_submit_pending(ring=%p, pending=%ld)\n", &data->ring, data->pending);
|
224
237
|
}
|
225
238
|
|
226
239
|
struct io_uring_sqe * io_get_sqe(struct IO_Event_Selector_URing *data) {
|
@@ -236,6 +249,8 @@ struct io_uring_sqe * io_get_sqe(struct IO_Event_Selector_URing *data) {
|
|
236
249
|
return sqe;
|
237
250
|
}
|
238
251
|
|
252
|
+
#pragma mark - Process.wait
|
253
|
+
|
239
254
|
struct process_wait_arguments {
|
240
255
|
struct IO_Event_Selector_URing *data;
|
241
256
|
pid_t pid;
|
@@ -284,6 +299,8 @@ VALUE IO_Event_Selector_URing_process_wait(VALUE self, VALUE fiber, VALUE pid, V
|
|
284
299
|
return rb_ensure(process_wait_transfer, (VALUE)&process_wait_arguments, process_wait_ensure, (VALUE)&process_wait_arguments);
|
285
300
|
}
|
286
301
|
|
302
|
+
#pragma mark - IO#wait
|
303
|
+
|
287
304
|
static inline
|
288
305
|
short poll_flags_from_events(int events) {
|
289
306
|
short flags = 0;
|
@@ -379,6 +396,8 @@ VALUE IO_Event_Selector_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE e
|
|
379
396
|
|
380
397
|
#ifdef HAVE_RUBY_IO_BUFFER_H
|
381
398
|
|
399
|
+
#pragma mark - IO#read
|
400
|
+
|
382
401
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
|
383
402
|
static inline off_t io_seekable(int descriptor) {
|
384
403
|
return -1;
|
@@ -395,19 +414,67 @@ static inline off_t io_seekable(int descriptor)
|
|
395
414
|
}
|
396
415
|
#endif
|
397
416
|
|
398
|
-
|
399
|
-
struct io_uring_sqe *sqe = io_get_sqe(data);
|
417
|
+
#pragma mark - IO#read
|
400
418
|
|
401
|
-
|
419
|
+
struct io_read_arguments {
|
420
|
+
struct IO_Event_Selector_URing *data;
|
421
|
+
VALUE fiber;
|
422
|
+
int descriptor;
|
423
|
+
char *buffer;
|
424
|
+
size_t length;
|
425
|
+
};
|
402
426
|
|
403
|
-
|
404
|
-
|
427
|
+
static VALUE
|
428
|
+
io_read_submit(VALUE _arguments)
|
429
|
+
{
|
430
|
+
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
431
|
+
struct IO_Event_Selector_URing *data = arguments->data;
|
432
|
+
struct io_uring_sqe *sqe = io_get_sqe(data);
|
433
|
+
|
434
|
+
if (DEBUG) fprintf(stderr, "io_read_submit:io_uring_prep_read(fiber=%p, descriptor=%d, buffer=%p, length=%ld)\n", (void*)arguments->fiber, arguments->descriptor, arguments->buffer, arguments->length);
|
435
|
+
|
436
|
+
io_uring_prep_read(sqe, arguments->descriptor, arguments->buffer, arguments->length, io_seekable(arguments->descriptor));
|
437
|
+
io_uring_sqe_set_data(sqe, (void*)arguments->fiber);
|
405
438
|
io_uring_submit_now(data);
|
406
439
|
|
407
|
-
|
408
|
-
|
440
|
+
return IO_Event_Selector_fiber_transfer(data->backend.loop, 0, NULL);
|
441
|
+
}
|
442
|
+
|
443
|
+
static VALUE
|
444
|
+
io_read_cancel(VALUE _arguments, VALUE exception)
|
445
|
+
{
|
446
|
+
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
447
|
+
struct IO_Event_Selector_URing *data = arguments->data;
|
448
|
+
|
449
|
+
struct io_uring_sqe *sqe = io_get_sqe(data);
|
450
|
+
|
451
|
+
if (DEBUG) fprintf(stderr, "io_read_cancel:io_uring_prep_cancel(fiber=%p)\n", (void*)arguments->fiber);
|
452
|
+
|
453
|
+
io_uring_prep_cancel(sqe, (void*)arguments->fiber, 0);
|
454
|
+
io_uring_sqe_set_data(sqe, NULL);
|
455
|
+
io_uring_submit_now(data);
|
456
|
+
|
457
|
+
rb_exc_raise(exception);
|
458
|
+
}
|
409
459
|
|
410
|
-
|
460
|
+
static int
|
461
|
+
io_read(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length)
|
462
|
+
{
|
463
|
+
struct io_read_arguments io_read_arguments = {
|
464
|
+
.data = data,
|
465
|
+
.fiber = fiber,
|
466
|
+
.descriptor = descriptor,
|
467
|
+
.buffer = buffer,
|
468
|
+
.length = length
|
469
|
+
};
|
470
|
+
|
471
|
+
int result = RB_NUM2INT(
|
472
|
+
rb_rescue(io_read_submit, (VALUE)&io_read_arguments, io_read_cancel, (VALUE)&io_read_arguments)
|
473
|
+
);
|
474
|
+
|
475
|
+
if (DEBUG) fprintf(stderr, "io_read:IO_Event_Selector_fiber_transfer -> %d\n", result);
|
476
|
+
|
477
|
+
return result;
|
411
478
|
}
|
412
479
|
|
413
480
|
VALUE IO_Event_Selector_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length, VALUE _offset) {
|
@@ -458,19 +525,67 @@ static VALUE IO_Event_Selector_URing_io_read_compatible(int argc, VALUE *argv, V
|
|
458
525
|
return IO_Event_Selector_URing_io_read(self, argv[0], argv[1], argv[2], argv[3], _offset);
|
459
526
|
}
|
460
527
|
|
461
|
-
|
462
|
-
|
528
|
+
#pragma mark - IO#write
|
529
|
+
|
530
|
+
struct io_write_arguments {
|
531
|
+
struct IO_Event_Selector_URing *data;
|
532
|
+
VALUE fiber;
|
533
|
+
int descriptor;
|
534
|
+
char *buffer;
|
535
|
+
size_t length;
|
536
|
+
};
|
537
|
+
|
538
|
+
static VALUE
|
539
|
+
io_write_submit(VALUE _argument)
|
540
|
+
{
|
541
|
+
struct io_write_arguments *arguments = (struct io_write_arguments*)_argument;
|
542
|
+
struct IO_Event_Selector_URing *data = arguments->data;
|
543
|
+
|
463
544
|
struct io_uring_sqe *sqe = io_get_sqe(data);
|
464
545
|
|
465
|
-
if (DEBUG) fprintf(stderr, "
|
466
|
-
|
467
|
-
io_uring_prep_write(sqe, descriptor, buffer, length, io_seekable(descriptor));
|
468
|
-
io_uring_sqe_set_data(sqe, (void*)fiber);
|
546
|
+
if (DEBUG) fprintf(stderr, "io_write_submit:io_uring_prep_write(fiber=%p, descriptor=%d, buffer=%p, length=%ld)\n", (void*)arguments->fiber, arguments->descriptor, arguments->buffer, arguments->length);
|
547
|
+
|
548
|
+
io_uring_prep_write(sqe, arguments->descriptor, arguments->buffer, arguments->length, io_seekable(arguments->descriptor));
|
549
|
+
io_uring_sqe_set_data(sqe, (void*)arguments->fiber);
|
469
550
|
io_uring_submit_pending(data);
|
470
551
|
|
471
|
-
|
472
|
-
|
552
|
+
return IO_Event_Selector_fiber_transfer(data->backend.loop, 0, NULL);
|
553
|
+
}
|
473
554
|
|
555
|
+
static VALUE
|
556
|
+
io_write_cancel(VALUE _argument, VALUE exception)
|
557
|
+
{
|
558
|
+
struct io_write_arguments *arguments = (struct io_write_arguments*)_argument;
|
559
|
+
struct IO_Event_Selector_URing *data = arguments->data;
|
560
|
+
|
561
|
+
struct io_uring_sqe *sqe = io_get_sqe(data);
|
562
|
+
|
563
|
+
if (DEBUG) fprintf(stderr, "io_wait_rescue:io_uring_prep_cancel(%p)\n", (void*)arguments->fiber);
|
564
|
+
|
565
|
+
io_uring_prep_cancel(sqe, (void*)arguments->fiber, 0);
|
566
|
+
io_uring_sqe_set_data(sqe, NULL);
|
567
|
+
io_uring_submit_now(data);
|
568
|
+
|
569
|
+
rb_exc_raise(exception);
|
570
|
+
}
|
571
|
+
|
572
|
+
static int
|
573
|
+
io_write(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length)
|
574
|
+
{
|
575
|
+
struct io_write_arguments arguments = {
|
576
|
+
.data = data,
|
577
|
+
.fiber = fiber,
|
578
|
+
.descriptor = descriptor,
|
579
|
+
.buffer = buffer,
|
580
|
+
.length = length,
|
581
|
+
};
|
582
|
+
|
583
|
+
int result = RB_NUM2INT(
|
584
|
+
rb_rescue(io_write_submit, (VALUE)&arguments, io_write_cancel, (VALUE)&arguments)
|
585
|
+
);
|
586
|
+
|
587
|
+
if (DEBUG) fprintf(stderr, "io_write:IO_Event_Selector_fiber_transfer -> %d\n", result);
|
588
|
+
|
474
589
|
return result;
|
475
590
|
}
|
476
591
|
|
@@ -526,6 +641,8 @@ static VALUE IO_Event_Selector_URing_io_write_compatible(int argc, VALUE *argv,
|
|
526
641
|
|
527
642
|
#endif
|
528
643
|
|
644
|
+
#pragma mark - IO#close
|
645
|
+
|
529
646
|
static const int ASYNC_CLOSE = 1;
|
530
647
|
|
531
648
|
VALUE IO_Event_Selector_URing_io_close(VALUE self, VALUE io) {
|
@@ -548,6 +665,8 @@ VALUE IO_Event_Selector_URing_io_close(VALUE self, VALUE io) {
|
|
548
665
|
return Qtrue;
|
549
666
|
}
|
550
667
|
|
668
|
+
#pragma mark - Event Loop
|
669
|
+
|
551
670
|
static
|
552
671
|
struct __kernel_timespec * make_timeout(VALUE duration, struct __kernel_timespec *storage) {
|
553
672
|
if (duration == Qnil) {
|
@@ -647,7 +766,7 @@ unsigned select_process_completions(struct io_uring *ring) {
|
|
647
766
|
|
648
767
|
// io_uring_cq_advance(ring, completed);
|
649
768
|
|
650
|
-
if (DEBUG) fprintf(stderr, "select_process_completions(completed=%d)\n", completed);
|
769
|
+
if (DEBUG && completed > 0) fprintf(stderr, "select_process_completions(completed=%d)\n", completed);
|
651
770
|
|
652
771
|
return completed;
|
653
772
|
}
|
@@ -680,9 +799,6 @@ VALUE IO_Event_Selector_URing_select(VALUE self, VALUE duration) {
|
|
680
799
|
if (!data->backend.ready && !timeout_nonblocking(arguments.timeout)) {
|
681
800
|
// This is a blocking operation, we wait for events:
|
682
801
|
result = select_internal_without_gvl(&arguments);
|
683
|
-
} else {
|
684
|
-
// The timeout specified required "nonblocking" behaviour so we just flush the SQ if required:
|
685
|
-
io_uring_submit_flush(data);
|
686
802
|
}
|
687
803
|
|
688
804
|
// After waiting/flushing the SQ, check if there are any completions:
|
@@ -721,6 +837,8 @@ VALUE IO_Event_Selector_URing_wakeup(VALUE self) {
|
|
721
837
|
return Qfalse;
|
722
838
|
}
|
723
839
|
|
840
|
+
#pragma mark - Native Methods
|
841
|
+
|
724
842
|
void Init_IO_Event_Selector_URing(VALUE IO_Event_Selector) {
|
725
843
|
IO_Event_Selector_URing = rb_define_class_under(IO_Event_Selector, "URing", rb_cObject);
|
726
844
|
rb_gc_register_mark_object(IO_Event_Selector_URing);
|
@@ -140,14 +140,14 @@ module IO::Event
|
|
140
140
|
end.value
|
141
141
|
end
|
142
142
|
|
143
|
+
EAGAIN = -Errno::EAGAIN::Errno
|
144
|
+
EWOULDBLOCK = -Errno::EWOULDBLOCK::Errno
|
145
|
+
|
146
|
+
def again?(errno)
|
147
|
+
errno == EAGAIN or errno == EWOULDBLOCK
|
148
|
+
end
|
149
|
+
|
143
150
|
if Support.fiber_scheduler_v2?
|
144
|
-
EAGAIN = -Errno::EAGAIN::Errno
|
145
|
-
EWOULDBLOCK = -Errno::EWOULDBLOCK::Errno
|
146
|
-
|
147
|
-
def again?(errno)
|
148
|
-
errno == EAGAIN or errno == EWOULDBLOCK
|
149
|
-
end
|
150
|
-
|
151
151
|
def io_read(fiber, io, buffer, length, offset = 0)
|
152
152
|
total = 0
|
153
153
|
|
@@ -236,6 +236,10 @@ module IO::Event
|
|
236
236
|
end
|
237
237
|
|
238
238
|
return total
|
239
|
+
rescue IOError => error
|
240
|
+
return -Errno::EBADF::Errno
|
241
|
+
rescue SystemCallError => error
|
242
|
+
return -error.errno
|
239
243
|
end
|
240
244
|
|
241
245
|
def io_write(fiber, _io, buffer, length, offset = 0)
|
@@ -268,6 +272,10 @@ module IO::Event
|
|
268
272
|
end
|
269
273
|
|
270
274
|
return total
|
275
|
+
rescue IOError => error
|
276
|
+
return -Errno::EBADF::Errno
|
277
|
+
rescue SystemCallError => error
|
278
|
+
return -error.errno
|
271
279
|
end
|
272
280
|
|
273
281
|
def blocking(&block)
|
data/lib/io/event/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-event
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -41,7 +41,7 @@ cert_chain:
|
|
41
41
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
42
42
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
43
43
|
-----END CERTIFICATE-----
|
44
|
-
date: 2023-
|
44
|
+
date: 2023-03-11 00:00:00.000000000 Z
|
45
45
|
dependencies:
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: bake
|
@@ -150,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
150
|
- !ruby/object:Gem::Version
|
151
151
|
version: '0'
|
152
152
|
requirements: []
|
153
|
-
rubygems_version: 3.4.
|
153
|
+
rubygems_version: 3.4.6
|
154
154
|
signing_key:
|
155
155
|
specification_version: 4
|
156
156
|
summary: An event loop.
|
metadata.gz.sig
CHANGED
Binary file
|