io-event 1.3.0 → 1.3.1
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 -20
- data/ext/io/event/selector/uring.c +63 -23
- data/lib/io/event/selector.rb +1 -1
- data/lib/io/event/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +2 -2
- 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: de2b826a00b27006568dad0139dd9d695ce8708882607fd1e1e4c4eda7d727cd
|
4
|
+
data.tar.gz: 3c34946c623e2c03d31c05f7e62283b005d8e8c8d1a6dd78d80a9cf847e7231c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2f752ea2f36c3cb848b3db0a8f2db62d27cd7a97f1dc1c245a8a094e8bd44368a4bc9bfcef3091d6473d02f2027423ddbdb9adcf9073d1103404408860ae411
|
7
|
+
data.tar.gz: bab17c94312eedabf98144e2363a37e0e9356e264f51108dcde0e0a188249eaa543ba164fe330a7fa3332b623418fe8cd5d3190774e723794b9d0fc121688f26
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/ext/extconf.rb
CHANGED
@@ -3,26 +3,7 @@
|
|
3
3
|
|
4
4
|
# Released under the MIT License.
|
5
5
|
# Copyright, 2021-2023, by Samuel Williams.
|
6
|
-
|
7
|
-
# Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
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
|
17
|
-
# all 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
|
25
|
-
# THE SOFTWARE.
|
6
|
+
# Copyright, 2023, by Math Ieu.
|
26
7
|
|
27
8
|
return if RUBY_DESCRIPTION =~ /jruby/
|
28
9
|
|
@@ -34,6 +34,7 @@
|
|
34
34
|
|
35
35
|
enum {
|
36
36
|
DEBUG = 0,
|
37
|
+
DEBUG_COMPLETION = 0,
|
37
38
|
};
|
38
39
|
|
39
40
|
static VALUE IO_Event_Selector_URing = Qnil;
|
@@ -165,6 +166,8 @@ struct IO_Event_Selector_URing_Completion * IO_Event_Selector_URing_Completion_a
|
|
165
166
|
IO_Event_List_clear(&completion->list);
|
166
167
|
}
|
167
168
|
|
169
|
+
if (DEBUG_COMPLETION) fprintf(stderr, "IO_Event_Selector_URing_Completion_acquire(%p, limit=%ld)\n", (void*)completion, selector->completions.limit);
|
170
|
+
|
168
171
|
waiting->completion = completion;
|
169
172
|
completion->waiting = waiting;
|
170
173
|
|
@@ -174,6 +177,8 @@ struct IO_Event_Selector_URing_Completion * IO_Event_Selector_URing_Completion_a
|
|
174
177
|
inline static
|
175
178
|
void IO_Event_Selector_URing_Completion_cancel(struct IO_Event_Selector_URing_Completion *completion)
|
176
179
|
{
|
180
|
+
if (DEBUG_COMPLETION) fprintf(stderr, "IO_Event_Selector_URing_Completion_cancel(%p)\n", (void*)completion);
|
181
|
+
|
177
182
|
if (completion->waiting) {
|
178
183
|
completion->waiting->completion = NULL;
|
179
184
|
completion->waiting = NULL;
|
@@ -183,13 +188,17 @@ void IO_Event_Selector_URing_Completion_cancel(struct IO_Event_Selector_URing_Co
|
|
183
188
|
inline static
|
184
189
|
void IO_Event_Selector_URing_Completion_release(struct IO_Event_Selector_URing *selector, struct IO_Event_Selector_URing_Completion *completion)
|
185
190
|
{
|
191
|
+
if (DEBUG_COMPLETION) fprintf(stderr, "IO_Event_Selector_URing_Completion_release(%p)\n", (void*)completion);
|
192
|
+
|
186
193
|
IO_Event_Selector_URing_Completion_cancel(completion);
|
187
194
|
IO_Event_List_prepend(&selector->free_list, &completion->list);
|
188
195
|
}
|
189
196
|
|
190
197
|
inline static
|
191
|
-
void IO_Event_Selector_URing_Waiting_cancel(struct
|
198
|
+
void IO_Event_Selector_URing_Waiting_cancel(struct IO_Event_Selector_URing_Waiting *waiting)
|
192
199
|
{
|
200
|
+
if (DEBUG_COMPLETION) fprintf(stderr, "IO_Event_Selector_URing_Waiting_cancel(%p, %p)\n", (void*)waiting, (void*)waiting->completion);
|
201
|
+
|
193
202
|
if (waiting->completion) {
|
194
203
|
waiting->completion->waiting = NULL;
|
195
204
|
waiting->completion = NULL;
|
@@ -198,10 +207,13 @@ void IO_Event_Selector_URing_Waiting_cancel(struct IO_Event_Selector_URing *sele
|
|
198
207
|
waiting->fiber = 0;
|
199
208
|
}
|
200
209
|
|
210
|
+
struct IO_Event_List_Type IO_Event_Selector_URing_Completion_Type = {};
|
211
|
+
|
201
212
|
void IO_Event_Selector_URing_Completion_initialize(void *element)
|
202
213
|
{
|
203
214
|
struct IO_Event_Selector_URing_Completion *completion = element;
|
204
215
|
IO_Event_List_initialize(&completion->list);
|
216
|
+
completion->list.type = &IO_Event_Selector_URing_Completion_Type;
|
205
217
|
}
|
206
218
|
|
207
219
|
void IO_Event_Selector_URing_Completion_free(void *element)
|
@@ -357,6 +369,12 @@ int io_uring_submit_now(struct IO_Event_Selector_URing *selector) {
|
|
357
369
|
}
|
358
370
|
}
|
359
371
|
|
372
|
+
static
|
373
|
+
void IO_Event_Selector_URing_submit_sqe(struct io_uring_sqe *sqe)
|
374
|
+
{
|
375
|
+
if (DEBUG) fprintf(stderr, "IO_Event_Selector_URing_submit_sqe(%p): user_data=%p opcode=%d\n", sqe, (void*)sqe->user_data, sqe->opcode);
|
376
|
+
}
|
377
|
+
|
360
378
|
// 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.
|
361
379
|
static
|
362
380
|
void io_uring_submit_pending(struct IO_Event_Selector_URing *selector) {
|
@@ -407,7 +425,7 @@ VALUE process_wait_ensure(VALUE _arguments) {
|
|
407
425
|
|
408
426
|
close(arguments->descriptor);
|
409
427
|
|
410
|
-
IO_Event_Selector_URing_Waiting_cancel(arguments->
|
428
|
+
IO_Event_Selector_URing_Waiting_cancel(arguments->waiting);
|
411
429
|
|
412
430
|
return Qnil;
|
413
431
|
}
|
@@ -442,6 +460,7 @@ VALUE IO_Event_Selector_URing_process_wait(VALUE self, VALUE fiber, VALUE _pid,
|
|
442
460
|
if (DEBUG) fprintf(stderr, "IO_Event_Selector_URing_process_wait:io_uring_prep_poll_add(%p)\n", (void*)fiber);
|
443
461
|
io_uring_prep_poll_add(sqe, descriptor, POLLIN|POLLHUP|POLLERR);
|
444
462
|
io_uring_sqe_set_data(sqe, completion);
|
463
|
+
IO_Event_Selector_URing_submit_sqe(sqe);
|
445
464
|
io_uring_submit_pending(selector);
|
446
465
|
|
447
466
|
return rb_ensure(process_wait_transfer, (VALUE)&process_wait_arguments, process_wait_ensure, (VALUE)&process_wait_arguments);
|
@@ -485,12 +504,18 @@ static
|
|
485
504
|
VALUE io_wait_ensure(VALUE _arguments) {
|
486
505
|
struct io_wait_arguments *arguments = (struct io_wait_arguments *)_arguments;
|
487
506
|
|
488
|
-
|
489
|
-
// io_uring_prep_cancel(sqe, (void*)arguments->waiting, 0);
|
490
|
-
// io_uring_sqe_set_data(sqe, NULL);
|
491
|
-
// io_uring_submit_now(selector);
|
507
|
+
if (DEBUG) fprintf(stderr, "io_wait_ensure:io_uring_prep_cancel(waiting=%p, completion=%p)\n", (void*)arguments->waiting, (void*)arguments->waiting->completion);
|
492
508
|
|
493
|
-
|
509
|
+
// If the operation is still in progress, cancel it:
|
510
|
+
if (arguments->waiting->completion) {
|
511
|
+
struct io_uring_sqe *sqe = io_get_sqe(arguments->selector);
|
512
|
+
io_uring_prep_cancel(sqe, (void*)arguments->waiting->completion, 0);
|
513
|
+
io_uring_sqe_set_data(sqe, NULL);
|
514
|
+
IO_Event_Selector_URing_submit_sqe(sqe);
|
515
|
+
io_uring_submit_now(arguments->selector);
|
516
|
+
}
|
517
|
+
|
518
|
+
IO_Event_Selector_URing_Waiting_cancel(arguments->waiting);
|
494
519
|
|
495
520
|
return Qnil;
|
496
521
|
};
|
@@ -502,6 +527,8 @@ VALUE io_wait_transfer(VALUE _arguments) {
|
|
502
527
|
|
503
528
|
IO_Event_Selector_fiber_transfer(selector->backend.loop, 0, NULL);
|
504
529
|
|
530
|
+
if (DEBUG) fprintf(stderr, "io_wait_transfer:waiting=%p, result=%d\n", (void*)arguments->waiting, arguments->waiting->result);
|
531
|
+
|
505
532
|
if (arguments->waiting->result) {
|
506
533
|
// We explicitly filter the resulting events based on the requested events.
|
507
534
|
// In some cases, poll will report events we didn't ask for.
|
@@ -531,6 +558,7 @@ VALUE IO_Event_Selector_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE e
|
|
531
558
|
struct IO_Event_Selector_URing_Completion *completion = IO_Event_Selector_URing_Completion_acquire(selector, &waiting);
|
532
559
|
|
533
560
|
io_uring_sqe_set_data(sqe, completion);
|
561
|
+
IO_Event_Selector_URing_submit_sqe(sqe);
|
534
562
|
|
535
563
|
// If we are going to wait, we assume that we are waiting for a while:
|
536
564
|
io_uring_submit_pending(selector);
|
@@ -581,10 +609,11 @@ io_read_submit(VALUE _arguments)
|
|
581
609
|
struct IO_Event_Selector_URing *selector = arguments->selector;
|
582
610
|
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
583
611
|
|
584
|
-
if (DEBUG) fprintf(stderr, "io_read_submit:io_uring_prep_read(
|
612
|
+
if (DEBUG) fprintf(stderr, "io_read_submit:io_uring_prep_read(waiting=%p, completion=%p, descriptor=%d, buffer=%p, length=%ld)\n", (void*)arguments->waiting, (void*)arguments->waiting->completion, arguments->descriptor, arguments->buffer, arguments->length);
|
585
613
|
|
586
614
|
io_uring_prep_read(sqe, arguments->descriptor, arguments->buffer, arguments->length, io_seekable(arguments->descriptor));
|
587
615
|
io_uring_sqe_set_data(sqe, arguments->waiting->completion);
|
616
|
+
IO_Event_Selector_URing_submit_sqe(sqe);
|
588
617
|
io_uring_submit_now(selector);
|
589
618
|
|
590
619
|
IO_Event_Selector_fiber_transfer(selector->backend.loop, 0, NULL);
|
@@ -600,16 +629,17 @@ io_read_ensure(VALUE _arguments)
|
|
600
629
|
|
601
630
|
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
602
631
|
|
603
|
-
if (DEBUG) fprintf(stderr, "
|
632
|
+
if (DEBUG) fprintf(stderr, "io_read_ensure:io_uring_prep_cancel(waiting=%p, completion=%p)\n", (void*)arguments->waiting, (void*)arguments->waiting->completion);
|
604
633
|
|
605
|
-
// If the operation
|
606
|
-
if (
|
607
|
-
io_uring_prep_cancel(sqe, (void*)arguments->waiting, 0);
|
634
|
+
// If the operation is still in progress, cancel it:
|
635
|
+
if (arguments->waiting->completion) {
|
636
|
+
io_uring_prep_cancel(sqe, (void*)arguments->waiting->completion, 0);
|
608
637
|
io_uring_sqe_set_data(sqe, NULL);
|
638
|
+
IO_Event_Selector_URing_submit_sqe(sqe);
|
609
639
|
io_uring_submit_now(selector);
|
610
640
|
}
|
611
641
|
|
612
|
-
IO_Event_Selector_URing_Waiting_cancel(arguments->
|
642
|
+
IO_Event_Selector_URing_Waiting_cancel(arguments->waiting);
|
613
643
|
|
614
644
|
return Qnil;
|
615
645
|
}
|
@@ -704,10 +734,11 @@ io_write_submit(VALUE _argument)
|
|
704
734
|
|
705
735
|
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
706
736
|
|
707
|
-
if (DEBUG) fprintf(stderr, "io_write_submit:io_uring_prep_write(
|
737
|
+
if (DEBUG) fprintf(stderr, "io_write_submit:io_uring_prep_write(waiting=%p, completion=%p, descriptor=%d, buffer=%p, length=%ld)\n", (void*)arguments->waiting, (void*)arguments->waiting->completion, arguments->descriptor, arguments->buffer, arguments->length);
|
708
738
|
|
709
739
|
io_uring_prep_write(sqe, arguments->descriptor, arguments->buffer, arguments->length, io_seekable(arguments->descriptor));
|
710
740
|
io_uring_sqe_set_data(sqe, arguments->waiting->completion);
|
741
|
+
IO_Event_Selector_URing_submit_sqe(sqe);
|
711
742
|
io_uring_submit_pending(selector);
|
712
743
|
|
713
744
|
IO_Event_Selector_fiber_transfer(selector->backend.loop, 0, NULL);
|
@@ -723,15 +754,17 @@ io_write_ensure(VALUE _argument)
|
|
723
754
|
|
724
755
|
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
725
756
|
|
726
|
-
if (DEBUG) fprintf(stderr, "
|
757
|
+
if (DEBUG) fprintf(stderr, "io_write_ensure:io_uring_prep_cancel(waiting=%p, completion=%p)\n", (void*)arguments->waiting, (void*)arguments->waiting->completion);
|
727
758
|
|
728
|
-
|
729
|
-
|
759
|
+
// If the operation is still in progress, cancel it:
|
760
|
+
if (arguments->waiting->completion) {
|
761
|
+
io_uring_prep_cancel(sqe, (void*)arguments->waiting->completion, 0);
|
730
762
|
io_uring_sqe_set_data(sqe, NULL);
|
763
|
+
IO_Event_Selector_URing_submit_sqe(sqe);
|
731
764
|
io_uring_submit_now(selector);
|
732
765
|
}
|
733
766
|
|
734
|
-
IO_Event_Selector_URing_Waiting_cancel(arguments->
|
767
|
+
IO_Event_Selector_URing_Waiting_cancel(arguments->waiting);
|
735
768
|
|
736
769
|
return Qnil;
|
737
770
|
}
|
@@ -829,6 +862,7 @@ VALUE IO_Event_Selector_URing_io_close(VALUE self, VALUE io) {
|
|
829
862
|
|
830
863
|
io_uring_prep_close(sqe, descriptor);
|
831
864
|
io_uring_sqe_set_data(sqe, NULL);
|
865
|
+
IO_Event_Selector_URing_submit_sqe(sqe);
|
832
866
|
io_uring_submit_now(selector);
|
833
867
|
} else {
|
834
868
|
close(descriptor);
|
@@ -919,32 +953,38 @@ unsigned select_process_completions(struct IO_Event_Selector_URing *selector) {
|
|
919
953
|
unsigned head;
|
920
954
|
struct io_uring_cqe *cqe;
|
921
955
|
|
956
|
+
if (DEBUG) fprintf(stderr, "select_process_completions...\n");
|
957
|
+
|
922
958
|
io_uring_for_each_cqe(ring, head, cqe) {
|
959
|
+
if (DEBUG) fprintf(stderr, "select_process_completions: cqe res=%d user_data=%p\n", cqe->res, (void*)cqe->user_data);
|
960
|
+
|
923
961
|
++completed;
|
924
962
|
|
925
|
-
// If the operation was cancelled, or the operation has no user data
|
963
|
+
// If the operation was cancelled, or the operation has no user data:
|
926
964
|
if (cqe->user_data == 0 || cqe->user_data == LIBURING_UDATA_TIMEOUT) {
|
927
965
|
io_uring_cq_advance(ring, 1);
|
928
966
|
continue;
|
929
967
|
}
|
930
968
|
|
931
|
-
if (DEBUG) fprintf(stderr, "cqe res=%d user_data=%p\n", cqe->res, (void*)cqe->user_data);
|
932
|
-
|
933
969
|
struct IO_Event_Selector_URing_Completion *completion = (void*)cqe->user_data;
|
934
970
|
struct IO_Event_Selector_URing_Waiting *waiting = completion->waiting;
|
935
971
|
|
972
|
+
if (DEBUG) fprintf(stderr, "select_process_completions: completion=%p waiting=%p\n", (void*)completion, (void*)waiting);
|
973
|
+
|
936
974
|
if (waiting) {
|
937
975
|
waiting->result = cqe->res;
|
938
976
|
waiting->flags = cqe->flags;
|
939
977
|
}
|
940
978
|
|
941
|
-
io_uring_cq_advance(ring, 1);
|
942
|
-
|
943
979
|
if (waiting && waiting->fiber) {
|
980
|
+
assert(waiting->result != -ECANCELED);
|
981
|
+
|
944
982
|
IO_Event_Selector_fiber_transfer(waiting->fiber, 0, NULL);
|
945
983
|
}
|
946
984
|
|
985
|
+
// This marks the waiting operation as "complete":
|
947
986
|
IO_Event_Selector_URing_Completion_release(selector, completion);
|
987
|
+
io_uring_cq_advance(ring, 1);
|
948
988
|
}
|
949
989
|
|
950
990
|
if (DEBUG && completed > 0) fprintf(stderr, "select_process_completions(completed=%d)\n", completed);
|
data/lib/io/event/selector.rb
CHANGED
data/lib/io/event/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-event
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
|
-
- Bruno Sutic
|
9
8
|
- Math Ieu
|
9
|
+
- Bruno Sutic
|
10
10
|
- Alex Matchneer
|
11
11
|
- Benoit Daloze
|
12
12
|
- Delton Ding
|
metadata.gz.sig
CHANGED
Binary file
|