io-event 1.3.0 → 1.3.2
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 +91 -41
- data/lib/io/event/selector/select.rb +61 -1
- data/lib/io/event/selector.rb +1 -1
- data/lib/io/event/support.rb +11 -0
- data/lib/io/event/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +4 -4
- 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: 9e419e583855ca1efed750b1ae61bc6fb7b4524cf30cec819a7461eecdb78d45
|
4
|
+
data.tar.gz: 7c64477599375b9612004acb9e725e7af260a51d404b071e209e866d734a083a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9b63cafbb56b9eac0f01edd180a70a38de6465ff4624b07360df135d0eeeab984c5348b0981d9c41ce943248af2a554528914e0cb9ae4606737d4ece2b96a8b
|
7
|
+
data.tar.gz: 1fecec388e9a5c517c83dc233a107cd86121a7e88f3cf5275e0ac00dd7a43aa826ae616b815b556c73ec13e5fc108f9c7cbe1bca1215fb0eb8bfed9daadb048b
|
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)
|
@@ -314,6 +326,32 @@ VALUE IO_Event_Selector_URing_ready_p(VALUE self) {
|
|
314
326
|
|
315
327
|
#pragma mark - Submission Queue
|
316
328
|
|
329
|
+
static
|
330
|
+
void IO_Event_Selector_URing_dump_completion_queue(struct IO_Event_Selector_URing *selector)
|
331
|
+
{
|
332
|
+
struct io_uring *ring = &selector->ring;
|
333
|
+
unsigned head;
|
334
|
+
struct io_uring_cqe *cqe;
|
335
|
+
|
336
|
+
if (DEBUG) {
|
337
|
+
int first = 1;
|
338
|
+
io_uring_for_each_cqe(ring, head, cqe) {
|
339
|
+
if (!first) {
|
340
|
+
fprintf(stderr, ", ");
|
341
|
+
}
|
342
|
+
else {
|
343
|
+
fprintf(stderr, "CQ: [");
|
344
|
+
first = 0;
|
345
|
+
}
|
346
|
+
|
347
|
+
fprintf(stderr, "%d:%p", (int)cqe->res, (void*)cqe->user_data);
|
348
|
+
}
|
349
|
+
if (!first) {
|
350
|
+
fprintf(stderr, "]\n");
|
351
|
+
}
|
352
|
+
}
|
353
|
+
}
|
354
|
+
|
317
355
|
// Flush the submission queue if pending operations are present.
|
318
356
|
static
|
319
357
|
int io_uring_submit_flush(struct IO_Event_Selector_URing *selector) {
|
@@ -333,19 +371,24 @@ int io_uring_submit_flush(struct IO_Event_Selector_URing *selector) {
|
|
333
371
|
return result;
|
334
372
|
}
|
335
373
|
|
374
|
+
if (DEBUG) {
|
375
|
+
IO_Event_Selector_URing_dump_completion_queue(selector);
|
376
|
+
}
|
377
|
+
|
336
378
|
return 0;
|
337
379
|
}
|
338
380
|
|
339
381
|
// Immediately flush the submission queue, yielding to the event loop if it was not successful.
|
340
382
|
static
|
341
383
|
int io_uring_submit_now(struct IO_Event_Selector_URing *selector) {
|
342
|
-
if (DEBUG
|
343
|
-
|
384
|
+
if (DEBUG) fprintf(stderr, "io_uring_submit_now(pending=%ld)\n", selector->pending);
|
385
|
+
|
344
386
|
while (true) {
|
345
387
|
int result = io_uring_submit(&selector->ring);
|
346
388
|
|
347
389
|
if (result >= 0) {
|
348
390
|
selector->pending = 0;
|
391
|
+
if (DEBUG) IO_Event_Selector_URing_dump_completion_queue(selector);
|
349
392
|
return result;
|
350
393
|
}
|
351
394
|
|
@@ -407,7 +450,7 @@ VALUE process_wait_ensure(VALUE _arguments) {
|
|
407
450
|
|
408
451
|
close(arguments->descriptor);
|
409
452
|
|
410
|
-
IO_Event_Selector_URing_Waiting_cancel(arguments->
|
453
|
+
IO_Event_Selector_URing_Waiting_cancel(arguments->waiting);
|
411
454
|
|
412
455
|
return Qnil;
|
413
456
|
}
|
@@ -437,9 +480,8 @@ VALUE IO_Event_Selector_URing_process_wait(VALUE self, VALUE fiber, VALUE _pid,
|
|
437
480
|
.descriptor = descriptor,
|
438
481
|
};
|
439
482
|
|
440
|
-
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
441
|
-
|
442
483
|
if (DEBUG) fprintf(stderr, "IO_Event_Selector_URing_process_wait:io_uring_prep_poll_add(%p)\n", (void*)fiber);
|
484
|
+
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
443
485
|
io_uring_prep_poll_add(sqe, descriptor, POLLIN|POLLHUP|POLLERR);
|
444
486
|
io_uring_sqe_set_data(sqe, completion);
|
445
487
|
io_uring_submit_pending(selector);
|
@@ -485,12 +527,16 @@ static
|
|
485
527
|
VALUE io_wait_ensure(VALUE _arguments) {
|
486
528
|
struct io_wait_arguments *arguments = (struct io_wait_arguments *)_arguments;
|
487
529
|
|
488
|
-
//
|
489
|
-
|
490
|
-
|
491
|
-
|
530
|
+
// If the operation is still in progress, cancel it:
|
531
|
+
if (arguments->waiting->completion) {
|
532
|
+
if (DEBUG) fprintf(stderr, "io_wait_ensure:io_uring_prep_cancel(waiting=%p, completion=%p)\n", (void*)arguments->waiting, (void*)arguments->waiting->completion);
|
533
|
+
struct io_uring_sqe *sqe = io_get_sqe(arguments->selector);
|
534
|
+
io_uring_prep_cancel(sqe, (void*)arguments->waiting->completion, 0);
|
535
|
+
io_uring_sqe_set_data(sqe, NULL);
|
536
|
+
io_uring_submit_now(arguments->selector);
|
537
|
+
}
|
492
538
|
|
493
|
-
IO_Event_Selector_URing_Waiting_cancel(arguments->
|
539
|
+
IO_Event_Selector_URing_Waiting_cancel(arguments->waiting);
|
494
540
|
|
495
541
|
return Qnil;
|
496
542
|
};
|
@@ -502,6 +548,8 @@ VALUE io_wait_transfer(VALUE _arguments) {
|
|
502
548
|
|
503
549
|
IO_Event_Selector_fiber_transfer(selector->backend.loop, 0, NULL);
|
504
550
|
|
551
|
+
if (DEBUG) fprintf(stderr, "io_wait_transfer:waiting=%p, result=%d\n", (void*)arguments->waiting, arguments->waiting->result);
|
552
|
+
|
505
553
|
if (arguments->waiting->result) {
|
506
554
|
// We explicitly filter the resulting events based on the requested events.
|
507
555
|
// In some cases, poll will report events we didn't ask for.
|
@@ -516,22 +564,20 @@ VALUE IO_Event_Selector_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE e
|
|
516
564
|
TypedData_Get_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, selector);
|
517
565
|
|
518
566
|
int descriptor = IO_Event_Selector_io_descriptor(io);
|
519
|
-
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
520
567
|
|
521
568
|
short flags = poll_flags_from_events(NUM2INT(events));
|
522
569
|
|
523
570
|
if (DEBUG) fprintf(stderr, "IO_Event_Selector_URing_io_wait:io_uring_prep_poll_add(descriptor=%d, flags=%d, fiber=%p)\n", descriptor, flags, (void*)fiber);
|
524
571
|
|
525
|
-
io_uring_prep_poll_add(sqe, descriptor, flags);
|
526
|
-
|
527
572
|
struct IO_Event_Selector_URing_Waiting waiting = {
|
528
573
|
.fiber = fiber,
|
529
574
|
};
|
530
575
|
|
531
576
|
struct IO_Event_Selector_URing_Completion *completion = IO_Event_Selector_URing_Completion_acquire(selector, &waiting);
|
532
577
|
|
578
|
+
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
579
|
+
io_uring_prep_poll_add(sqe, descriptor, flags);
|
533
580
|
io_uring_sqe_set_data(sqe, completion);
|
534
|
-
|
535
581
|
// If we are going to wait, we assume that we are waiting for a while:
|
536
582
|
io_uring_submit_pending(selector);
|
537
583
|
|
@@ -579,10 +625,10 @@ io_read_submit(VALUE _arguments)
|
|
579
625
|
{
|
580
626
|
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
581
627
|
struct IO_Event_Selector_URing *selector = arguments->selector;
|
582
|
-
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
583
628
|
|
584
|
-
if (DEBUG) fprintf(stderr, "io_read_submit:io_uring_prep_read(
|
629
|
+
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
630
|
|
631
|
+
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
586
632
|
io_uring_prep_read(sqe, arguments->descriptor, arguments->buffer, arguments->length, io_seekable(arguments->descriptor));
|
587
633
|
io_uring_sqe_set_data(sqe, arguments->waiting->completion);
|
588
634
|
io_uring_submit_now(selector);
|
@@ -598,18 +644,16 @@ io_read_ensure(VALUE _arguments)
|
|
598
644
|
struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
|
599
645
|
struct IO_Event_Selector_URing *selector = arguments->selector;
|
600
646
|
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
if (!arguments->waiting->result) {
|
607
|
-
io_uring_prep_cancel(sqe, (void*)arguments->waiting, 0);
|
647
|
+
// If the operation is still in progress, cancel it:
|
648
|
+
if (arguments->waiting->completion) {
|
649
|
+
if (DEBUG) fprintf(stderr, "io_read_ensure:io_uring_prep_cancel(waiting=%p, completion=%p)\n", (void*)arguments->waiting, (void*)arguments->waiting->completion);
|
650
|
+
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
651
|
+
io_uring_prep_cancel(sqe, (void*)arguments->waiting->completion, 0);
|
608
652
|
io_uring_sqe_set_data(sqe, NULL);
|
609
653
|
io_uring_submit_now(selector);
|
610
654
|
}
|
611
655
|
|
612
|
-
IO_Event_Selector_URing_Waiting_cancel(arguments->
|
656
|
+
IO_Event_Selector_URing_Waiting_cancel(arguments->waiting);
|
613
657
|
|
614
658
|
return Qnil;
|
615
659
|
}
|
@@ -702,10 +746,9 @@ io_write_submit(VALUE _argument)
|
|
702
746
|
struct io_write_arguments *arguments = (struct io_write_arguments*)_argument;
|
703
747
|
struct IO_Event_Selector_URing *selector = arguments->selector;
|
704
748
|
|
705
|
-
|
706
|
-
|
707
|
-
if (DEBUG) fprintf(stderr, "io_write_submit:io_uring_prep_write(fiber=%p, descriptor=%d, buffer=%p, length=%ld)\n", (void*)arguments->waiting, arguments->descriptor, arguments->buffer, arguments->length);
|
749
|
+
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
750
|
|
751
|
+
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
709
752
|
io_uring_prep_write(sqe, arguments->descriptor, arguments->buffer, arguments->length, io_seekable(arguments->descriptor));
|
710
753
|
io_uring_sqe_set_data(sqe, arguments->waiting->completion);
|
711
754
|
io_uring_submit_pending(selector);
|
@@ -721,17 +764,16 @@ io_write_ensure(VALUE _argument)
|
|
721
764
|
struct io_write_arguments *arguments = (struct io_write_arguments*)_argument;
|
722
765
|
struct IO_Event_Selector_URing *selector = arguments->selector;
|
723
766
|
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
io_uring_prep_cancel(sqe, (void*)arguments->waiting, 0);
|
767
|
+
// If the operation is still in progress, cancel it:
|
768
|
+
if (arguments->waiting->completion) {
|
769
|
+
if (DEBUG) fprintf(stderr, "io_write_ensure:io_uring_prep_cancel(waiting=%p, completion=%p)\n", (void*)arguments->waiting, (void*)arguments->waiting->completion);
|
770
|
+
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
771
|
+
io_uring_prep_cancel(sqe, (void*)arguments->waiting->completion, 0);
|
730
772
|
io_uring_sqe_set_data(sqe, NULL);
|
731
773
|
io_uring_submit_now(selector);
|
732
774
|
}
|
733
775
|
|
734
|
-
IO_Event_Selector_URing_Waiting_cancel(arguments->
|
776
|
+
IO_Event_Selector_URing_Waiting_cancel(arguments->waiting);
|
735
777
|
|
736
778
|
return Qnil;
|
737
779
|
}
|
@@ -826,7 +868,6 @@ VALUE IO_Event_Selector_URing_io_close(VALUE self, VALUE io) {
|
|
826
868
|
|
827
869
|
if (ASYNC_CLOSE) {
|
828
870
|
struct io_uring_sqe *sqe = io_get_sqe(selector);
|
829
|
-
|
830
871
|
io_uring_prep_close(sqe, descriptor);
|
831
872
|
io_uring_sqe_set_data(sqe, NULL);
|
832
873
|
io_uring_submit_now(selector);
|
@@ -919,32 +960,41 @@ unsigned select_process_completions(struct IO_Event_Selector_URing *selector) {
|
|
919
960
|
unsigned head;
|
920
961
|
struct io_uring_cqe *cqe;
|
921
962
|
|
963
|
+
if (DEBUG) {
|
964
|
+
fprintf(stderr, "select_process_completions: selector=%p\n", (void*)selector);
|
965
|
+
IO_Event_Selector_URing_dump_completion_queue(selector);
|
966
|
+
}
|
967
|
+
|
922
968
|
io_uring_for_each_cqe(ring, head, cqe) {
|
969
|
+
if (DEBUG) fprintf(stderr, "select_process_completions: cqe res=%d user_data=%p\n", cqe->res, (void*)cqe->user_data);
|
970
|
+
|
923
971
|
++completed;
|
924
972
|
|
925
|
-
// If the operation was cancelled, or the operation has no user data
|
973
|
+
// If the operation was cancelled, or the operation has no user data:
|
926
974
|
if (cqe->user_data == 0 || cqe->user_data == LIBURING_UDATA_TIMEOUT) {
|
927
975
|
io_uring_cq_advance(ring, 1);
|
928
976
|
continue;
|
929
977
|
}
|
930
978
|
|
931
|
-
if (DEBUG) fprintf(stderr, "cqe res=%d user_data=%p\n", cqe->res, (void*)cqe->user_data);
|
932
|
-
|
933
979
|
struct IO_Event_Selector_URing_Completion *completion = (void*)cqe->user_data;
|
934
980
|
struct IO_Event_Selector_URing_Waiting *waiting = completion->waiting;
|
935
981
|
|
982
|
+
if (DEBUG) fprintf(stderr, "select_process_completions: completion=%p waiting=%p\n", (void*)completion, (void*)waiting);
|
983
|
+
|
936
984
|
if (waiting) {
|
937
985
|
waiting->result = cqe->res;
|
938
986
|
waiting->flags = cqe->flags;
|
939
987
|
}
|
940
988
|
|
941
989
|
io_uring_cq_advance(ring, 1);
|
990
|
+
// This marks the waiting operation as "complete":
|
991
|
+
IO_Event_Selector_URing_Completion_release(selector, completion);
|
942
992
|
|
943
993
|
if (waiting && waiting->fiber) {
|
994
|
+
assert(waiting->result != -ECANCELED);
|
995
|
+
|
944
996
|
IO_Event_Selector_fiber_transfer(waiting->fiber, 0, NULL);
|
945
997
|
}
|
946
|
-
|
947
|
-
IO_Event_Selector_URing_Completion_release(selector, completion);
|
948
998
|
}
|
949
999
|
|
950
1000
|
if (DEBUG && completed > 0) fprintf(stderr, "select_process_completions(completed=%d)\n", completed);
|
@@ -160,7 +160,66 @@ module IO::Event
|
|
160
160
|
errno == EAGAIN or errno == EWOULDBLOCK
|
161
161
|
end
|
162
162
|
|
163
|
-
if Support.
|
163
|
+
if Support.fiber_scheduler_v3?
|
164
|
+
# Ruby 3.3+, full IO::Buffer support.
|
165
|
+
|
166
|
+
# @parameter length [Integer] The minimum number of bytes to read.
|
167
|
+
# @parameter offset [Integer] The offset into the buffer to read to.
|
168
|
+
def io_read(fiber, io, buffer, length, offset = 0)
|
169
|
+
total = 0
|
170
|
+
|
171
|
+
Selector.nonblock(io) do
|
172
|
+
while true
|
173
|
+
result = Fiber.blocking{buffer.read(io, 0, offset)}
|
174
|
+
|
175
|
+
if result < 0
|
176
|
+
if again?(result)
|
177
|
+
self.io_wait(fiber, io, IO::READABLE)
|
178
|
+
else
|
179
|
+
return result
|
180
|
+
end
|
181
|
+
elsif result == 0
|
182
|
+
break
|
183
|
+
else
|
184
|
+
total += result
|
185
|
+
break if total >= length
|
186
|
+
offset += result
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
return total
|
192
|
+
end
|
193
|
+
|
194
|
+
# @parameter length [Integer] The minimum number of bytes to write.
|
195
|
+
# @parameter offset [Integer] The offset into the buffer to write from.
|
196
|
+
def io_write(fiber, io, buffer, length, offset = 0)
|
197
|
+
total = 0
|
198
|
+
|
199
|
+
Selector.nonblock(io) do
|
200
|
+
while true
|
201
|
+
result = Fiber.blocking{buffer.write(io, 0, offset)}
|
202
|
+
|
203
|
+
if result < 0
|
204
|
+
if again?(result)
|
205
|
+
self.io_wait(fiber, io, IO::READABLE)
|
206
|
+
else
|
207
|
+
return result
|
208
|
+
end
|
209
|
+
elsif result == 0
|
210
|
+
break result
|
211
|
+
else
|
212
|
+
total += result
|
213
|
+
break if total >= length
|
214
|
+
offset += result
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
return total
|
220
|
+
end
|
221
|
+
elsif Support.fiber_scheduler_v2?
|
222
|
+
# Ruby 3.2, most IO::Buffer support, but slightly clunky read/write methods.
|
164
223
|
def io_read(fiber, io, buffer, length, offset = 0)
|
165
224
|
total = 0
|
166
225
|
|
@@ -219,6 +278,7 @@ module IO::Event
|
|
219
278
|
return total
|
220
279
|
end
|
221
280
|
elsif Support.fiber_scheduler_v1?
|
281
|
+
# Ruby <= 3.1, limited IO::Buffer support.
|
222
282
|
def io_read(fiber, _io, buffer, length, offset = 0)
|
223
283
|
io = IO.for_fd(_io.fileno, autoclose: false)
|
224
284
|
total = 0
|
data/lib/io/event/selector.rb
CHANGED
data/lib/io/event/support.rb
CHANGED
@@ -17,6 +17,17 @@ class IO
|
|
17
17
|
def self.fiber_scheduler_v2?
|
18
18
|
IO.const_defined?(:Buffer) and Fiber.respond_to?(:blocking) and IO::Buffer.instance_method(:read).arity == -1
|
19
19
|
end
|
20
|
+
|
21
|
+
def self.fiber_scheduler_v3?
|
22
|
+
if fiber_scheduler_v2?
|
23
|
+
begin
|
24
|
+
IO::Buffer.new.slice(0, 0).write(STDOUT)
|
25
|
+
return true
|
26
|
+
rescue
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
20
31
|
end
|
21
32
|
end
|
22
33
|
end
|
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.2
|
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
|
@@ -42,7 +42,7 @@ cert_chain:
|
|
42
42
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
43
43
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
44
44
|
-----END CERTIFICATE-----
|
45
|
-
date: 2023-08-
|
45
|
+
date: 2023-08-24 00:00:00.000000000 Z
|
46
46
|
dependencies: []
|
47
47
|
description:
|
48
48
|
email:
|
@@ -97,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
97
|
- !ruby/object:Gem::Version
|
98
98
|
version: '0'
|
99
99
|
requirements: []
|
100
|
-
rubygems_version: 3.
|
100
|
+
rubygems_version: 3.5.0.dev
|
101
101
|
signing_key:
|
102
102
|
specification_version: 4
|
103
103
|
summary: An event loop.
|
metadata.gz.sig
CHANGED
Binary file
|