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 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