io-event 1.1.5 → 1.1.7
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/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
|