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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0743271de82b1b4324953fadd2f5da09cb79609c1153ae8637e4f23f31f0615c
4
- data.tar.gz: e90309751d3bc2716362d596b07a477a0f9b1c6ef27443f06469547bce10cb40
3
+ metadata.gz: de2b826a00b27006568dad0139dd9d695ce8708882607fd1e1e4c4eda7d727cd
4
+ data.tar.gz: 3c34946c623e2c03d31c05f7e62283b005d8e8c8d1a6dd78d80a9cf847e7231c
5
5
  SHA512:
6
- metadata.gz: f1fe9c27d9ed25969eaca758565f99346dea63f397e32e8bec027312b0936b61b6677a520cbacb4f0c3e976979ff3ee4cfac93ea766d92cd8b88fa19cab1ad7c
7
- data.tar.gz: 4c476754268f03564134fc461bdeee26c0989fc6673cd27235ccc6d1a6df4d03b680f677469db531e8b1613622bd356ffa762d35b2b39ab455d522c6d624d45e
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 IO_Event_Selector_URing *selector, struct IO_Event_Selector_URing_Waiting *waiting)
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->selector, arguments->waiting);
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
- // We may want to consider cancellation. Be aware that the order of operations is important here:
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
- IO_Event_Selector_URing_Waiting_cancel(arguments->selector, arguments->waiting);
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(fiber=%p, descriptor=%d, buffer=%p, length=%ld)\n", (void*)arguments->waiting, arguments->descriptor, arguments->buffer, arguments->length);
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, "io_read_cancel:io_uring_prep_cancel(fiber=%p)\n", (void*)arguments->waiting);
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 has already completed, we don't need to cancel it:
606
- if (!arguments->waiting->result) {
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->selector, arguments->waiting);
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(fiber=%p, descriptor=%d, buffer=%p, length=%ld)\n", (void*)arguments->waiting, arguments->descriptor, arguments->buffer, arguments->length);
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, "io_wait_rescue:io_uring_prep_cancel(%p)\n", (void*)arguments->waiting);
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
- if (!arguments->waiting->result) {
729
- io_uring_prep_cancel(sqe, (void*)arguments->waiting, 0);
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->selector, arguments->waiting);
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 (fiber):
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);
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2021-2022, by Samuel Williams.
4
+ # Copyright, 2021-2023, by Samuel Williams.
5
5
 
6
6
  require_relative 'selector/select'
7
7
  require_relative 'debug/selector'
@@ -5,6 +5,6 @@
5
5
 
6
6
  class IO
7
7
  module Event
8
- VERSION = "1.3.0"
8
+ VERSION = "1.3.1"
9
9
  end
10
10
  end
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.0
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