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