io-event 1.3.0 → 1.3.1
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 -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
|