io-event 1.1.6 → 1.1.7

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: c2b1d6d29aedc2b375fa708f5f3518fb39dae6ee0b5c675a4ff571192f3c00ef
4
- data.tar.gz: 6e9b9589ef99c97a287d20e4f60f501d87ca163897d21bdd59eb03aa71085ffd
3
+ metadata.gz: 0202b38104b1b6254a15fc12f687f9102509ba75592b1584d3dd5d0e44c497fb
4
+ data.tar.gz: 925de8b198ea2a9fca99b7c02c5262dd691a9864601c7db109a79c332804b944
5
5
  SHA512:
6
- metadata.gz: 6447991710738ba24577100220b4ca322d79179d736ba3101bdd5fd2a2d8a23aa8983d527ebc13cdde5b038601c17d6a860ed21394a2f3d584ddd68772f505b6
7
- data.tar.gz: e8a0232a3f36be1bfab1a1ca8a9e0a68e761d89d9f1576449ea23644eddc2643f89c9963186376d1211f25fb96853cadef82c673ca81af7430cdacb45d3f37ea
6
+ metadata.gz: d0bb87512e17c8be8ca0b04390466b0c3de198c6ee4a4a0a074b31d8e2f3bb0f482ece3378d0d9653b9219d36f06d41882f4c78631b27f6c0fb02e4143688d33
7
+ data.tar.gz: 4403550628403eccfb92d60e44ccf096ecb2dee1f2e78917fbef65b8c49cc71b15db96b3074e5b16f0ce005f826db928e4a95fd1214973cf33509659195a2e9a
checksums.yaml.gz.sig CHANGED
Binary file
data/ext/extconf.rb CHANGED
@@ -33,7 +33,7 @@ extension_name = 'IO_Event'
33
33
 
34
34
  # dir_config(extension_name)
35
35
 
36
- $CFLAGS << " -Wall -std=c99"
36
+ $CFLAGS << " -Wall -Wno-unknown-pragmas -std=c99"
37
37
 
38
38
  $srcs = ["io/event/event.c", "io/event/selector/selector.c"]
39
39
  $VPATH << "$(srcdir)/io/event"
@@ -39,6 +39,8 @@ static VALUE IO_Event_Selector_URing = Qnil;
39
39
 
40
40
  enum {URING_ENTRIES = 64};
41
41
 
42
+ #pragma mark - Data Type
43
+
42
44
  struct IO_Event_Selector_URing {
43
45
  struct IO_Event_Selector backend;
44
46
  struct io_uring ring;
@@ -98,6 +100,8 @@ VALUE IO_Event_Selector_URing_allocate(VALUE self) {
98
100
  return instance;
99
101
  }
100
102
 
103
+ #pragma mark - Methods
104
+
101
105
  VALUE IO_Event_Selector_URing_initialize(VALUE self, VALUE loop) {
102
106
  struct IO_Event_Selector_URing *data = NULL;
103
107
  TypedData_Get_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, data);
@@ -179,6 +183,8 @@ VALUE IO_Event_Selector_URing_ready_p(VALUE self) {
179
183
  return data->backend.ready ? Qtrue : Qfalse;
180
184
  }
181
185
 
186
+ #pragma mark - Submission Queue
187
+
182
188
  // Flush the submission queue if pending operations are present.
183
189
  static
184
190
  int io_uring_submit_flush(struct IO_Event_Selector_URing *data) {
@@ -204,6 +210,8 @@ int io_uring_submit_flush(struct IO_Event_Selector_URing *data) {
204
210
  // Immediately flush the submission queue, yielding to the event loop if it was not successful.
205
211
  static
206
212
  int io_uring_submit_now(struct IO_Event_Selector_URing *data) {
213
+ if (DEBUG && data->pending) fprintf(stderr, "io_uring_submit_now(pending=%ld)\n", data->pending);
214
+
207
215
  while (true) {
208
216
  int result = io_uring_submit(&data->ring);
209
217
 
@@ -220,9 +228,12 @@ int io_uring_submit_now(struct IO_Event_Selector_URing *data) {
220
228
  }
221
229
  }
222
230
 
231
+ // 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.
223
232
  static
224
233
  void io_uring_submit_pending(struct IO_Event_Selector_URing *data) {
225
234
  data->pending += 1;
235
+
236
+ if (DEBUG) fprintf(stderr, "io_uring_submit_pending(ring=%p, pending=%ld)\n", &data->ring, data->pending);
226
237
  }
227
238
 
228
239
  struct io_uring_sqe * io_get_sqe(struct IO_Event_Selector_URing *data) {
@@ -238,6 +249,8 @@ struct io_uring_sqe * io_get_sqe(struct IO_Event_Selector_URing *data) {
238
249
  return sqe;
239
250
  }
240
251
 
252
+ #pragma mark - Process.wait
253
+
241
254
  struct process_wait_arguments {
242
255
  struct IO_Event_Selector_URing *data;
243
256
  pid_t pid;
@@ -286,6 +299,8 @@ VALUE IO_Event_Selector_URing_process_wait(VALUE self, VALUE fiber, VALUE pid, V
286
299
  return rb_ensure(process_wait_transfer, (VALUE)&process_wait_arguments, process_wait_ensure, (VALUE)&process_wait_arguments);
287
300
  }
288
301
 
302
+ #pragma mark - IO#wait
303
+
289
304
  static inline
290
305
  short poll_flags_from_events(int events) {
291
306
  short flags = 0;
@@ -381,6 +396,8 @@ VALUE IO_Event_Selector_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE e
381
396
 
382
397
  #ifdef HAVE_RUBY_IO_BUFFER_H
383
398
 
399
+ #pragma mark - IO#read
400
+
384
401
  #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
385
402
  static inline off_t io_seekable(int descriptor) {
386
403
  return -1;
@@ -397,19 +414,67 @@ static inline off_t io_seekable(int descriptor)
397
414
  }
398
415
  #endif
399
416
 
400
- static int io_read(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length) {
401
- struct io_uring_sqe *sqe = io_get_sqe(data);
417
+ #pragma mark - IO#read
402
418
 
403
- if (DEBUG) fprintf(stderr, "io_read:io_uring_prep_read(fiber=%p)\n", (void*)fiber);
419
+ struct io_read_arguments {
420
+ struct IO_Event_Selector_URing *data;
421
+ VALUE fiber;
422
+ int descriptor;
423
+ char *buffer;
424
+ size_t length;
425
+ };
404
426
 
405
- io_uring_prep_read(sqe, descriptor, buffer, length, io_seekable(descriptor));
406
- io_uring_sqe_set_data(sqe, (void*)fiber);
427
+ static VALUE
428
+ io_read_submit(VALUE _arguments)
429
+ {
430
+ struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
431
+ struct IO_Event_Selector_URing *data = arguments->data;
432
+ struct io_uring_sqe *sqe = io_get_sqe(data);
433
+
434
+ if (DEBUG) fprintf(stderr, "io_read_submit:io_uring_prep_read(fiber=%p, descriptor=%d, buffer=%p, length=%ld)\n", (void*)arguments->fiber, arguments->descriptor, arguments->buffer, arguments->length);
435
+
436
+ io_uring_prep_read(sqe, arguments->descriptor, arguments->buffer, arguments->length, io_seekable(arguments->descriptor));
437
+ io_uring_sqe_set_data(sqe, (void*)arguments->fiber);
407
438
  io_uring_submit_now(data);
408
439
 
409
- VALUE result = IO_Event_Selector_fiber_transfer(data->backend.loop, 0, NULL);
410
- if (DEBUG) fprintf(stderr, "io_read:IO_Event_Selector_fiber_transfer -> %d\n", RB_NUM2INT(result));
440
+ return IO_Event_Selector_fiber_transfer(data->backend.loop, 0, NULL);
441
+ }
411
442
 
412
- return RB_NUM2INT(result);
443
+ static VALUE
444
+ io_read_cancel(VALUE _arguments, VALUE exception)
445
+ {
446
+ struct io_read_arguments *arguments = (struct io_read_arguments *)_arguments;
447
+ struct IO_Event_Selector_URing *data = arguments->data;
448
+
449
+ struct io_uring_sqe *sqe = io_get_sqe(data);
450
+
451
+ if (DEBUG) fprintf(stderr, "io_read_cancel:io_uring_prep_cancel(fiber=%p)\n", (void*)arguments->fiber);
452
+
453
+ io_uring_prep_cancel(sqe, (void*)arguments->fiber, 0);
454
+ io_uring_sqe_set_data(sqe, NULL);
455
+ io_uring_submit_now(data);
456
+
457
+ rb_exc_raise(exception);
458
+ }
459
+
460
+ static int
461
+ io_read(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length)
462
+ {
463
+ struct io_read_arguments io_read_arguments = {
464
+ .data = data,
465
+ .fiber = fiber,
466
+ .descriptor = descriptor,
467
+ .buffer = buffer,
468
+ .length = length
469
+ };
470
+
471
+ int result = RB_NUM2INT(
472
+ rb_rescue(io_read_submit, (VALUE)&io_read_arguments, io_read_cancel, (VALUE)&io_read_arguments)
473
+ );
474
+
475
+ if (DEBUG) fprintf(stderr, "io_read:IO_Event_Selector_fiber_transfer -> %d\n", result);
476
+
477
+ return result;
413
478
  }
414
479
 
415
480
  VALUE IO_Event_Selector_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffer, VALUE _length, VALUE _offset) {
@@ -460,19 +525,67 @@ static VALUE IO_Event_Selector_URing_io_read_compatible(int argc, VALUE *argv, V
460
525
  return IO_Event_Selector_URing_io_read(self, argv[0], argv[1], argv[2], argv[3], _offset);
461
526
  }
462
527
 
463
- static
464
- int io_write(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length) {
528
+ #pragma mark - IO#write
529
+
530
+ struct io_write_arguments {
531
+ struct IO_Event_Selector_URing *data;
532
+ VALUE fiber;
533
+ int descriptor;
534
+ char *buffer;
535
+ size_t length;
536
+ };
537
+
538
+ static VALUE
539
+ io_write_submit(VALUE _argument)
540
+ {
541
+ struct io_write_arguments *arguments = (struct io_write_arguments*)_argument;
542
+ struct IO_Event_Selector_URing *data = arguments->data;
543
+
465
544
  struct io_uring_sqe *sqe = io_get_sqe(data);
466
545
 
467
- if (DEBUG) fprintf(stderr, "io_write:io_uring_prep_write(fiber=%p)\n", (void*)fiber);
468
-
469
- io_uring_prep_write(sqe, descriptor, buffer, length, io_seekable(descriptor));
470
- io_uring_sqe_set_data(sqe, (void*)fiber);
546
+ if (DEBUG) fprintf(stderr, "io_write_submit:io_uring_prep_write(fiber=%p, descriptor=%d, buffer=%p, length=%ld)\n", (void*)arguments->fiber, arguments->descriptor, arguments->buffer, arguments->length);
547
+
548
+ io_uring_prep_write(sqe, arguments->descriptor, arguments->buffer, arguments->length, io_seekable(arguments->descriptor));
549
+ io_uring_sqe_set_data(sqe, (void*)arguments->fiber);
471
550
  io_uring_submit_pending(data);
472
551
 
473
- int result = RB_NUM2INT(IO_Event_Selector_fiber_transfer(data->backend.loop, 0, NULL));
474
- if (DEBUG) fprintf(stderr, "io_write:IO_Event_Selector_fiber_transfer -> %d\n", result);
552
+ return IO_Event_Selector_fiber_transfer(data->backend.loop, 0, NULL);
553
+ }
554
+
555
+ static VALUE
556
+ io_write_cancel(VALUE _argument, VALUE exception)
557
+ {
558
+ struct io_write_arguments *arguments = (struct io_write_arguments*)_argument;
559
+ struct IO_Event_Selector_URing *data = arguments->data;
560
+
561
+ struct io_uring_sqe *sqe = io_get_sqe(data);
562
+
563
+ if (DEBUG) fprintf(stderr, "io_wait_rescue:io_uring_prep_cancel(%p)\n", (void*)arguments->fiber);
564
+
565
+ io_uring_prep_cancel(sqe, (void*)arguments->fiber, 0);
566
+ io_uring_sqe_set_data(sqe, NULL);
567
+ io_uring_submit_now(data);
568
+
569
+ rb_exc_raise(exception);
570
+ }
475
571
 
572
+ static int
573
+ io_write(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length)
574
+ {
575
+ struct io_write_arguments arguments = {
576
+ .data = data,
577
+ .fiber = fiber,
578
+ .descriptor = descriptor,
579
+ .buffer = buffer,
580
+ .length = length,
581
+ };
582
+
583
+ int result = RB_NUM2INT(
584
+ rb_rescue(io_write_submit, (VALUE)&arguments, io_write_cancel, (VALUE)&arguments)
585
+ );
586
+
587
+ if (DEBUG) fprintf(stderr, "io_write:IO_Event_Selector_fiber_transfer -> %d\n", result);
588
+
476
589
  return result;
477
590
  }
478
591
 
@@ -528,6 +641,8 @@ static VALUE IO_Event_Selector_URing_io_write_compatible(int argc, VALUE *argv,
528
641
 
529
642
  #endif
530
643
 
644
+ #pragma mark - IO#close
645
+
531
646
  static const int ASYNC_CLOSE = 1;
532
647
 
533
648
  VALUE IO_Event_Selector_URing_io_close(VALUE self, VALUE io) {
@@ -550,6 +665,8 @@ VALUE IO_Event_Selector_URing_io_close(VALUE self, VALUE io) {
550
665
  return Qtrue;
551
666
  }
552
667
 
668
+ #pragma mark - Event Loop
669
+
553
670
  static
554
671
  struct __kernel_timespec * make_timeout(VALUE duration, struct __kernel_timespec *storage) {
555
672
  if (duration == Qnil) {
@@ -649,7 +766,7 @@ unsigned select_process_completions(struct io_uring *ring) {
649
766
 
650
767
  // io_uring_cq_advance(ring, completed);
651
768
 
652
- if (DEBUG) fprintf(stderr, "select_process_completions(completed=%d)\n", completed);
769
+ if (DEBUG && completed > 0) fprintf(stderr, "select_process_completions(completed=%d)\n", completed);
653
770
 
654
771
  return completed;
655
772
  }
@@ -720,6 +837,8 @@ VALUE IO_Event_Selector_URing_wakeup(VALUE self) {
720
837
  return Qfalse;
721
838
  }
722
839
 
840
+ #pragma mark - Native Methods
841
+
723
842
  void Init_IO_Event_Selector_URing(VALUE IO_Event_Selector) {
724
843
  IO_Event_Selector_URing = rb_define_class_under(IO_Event_Selector, "URing", rb_cObject);
725
844
  rb_gc_register_mark_object(IO_Event_Selector_URing);
@@ -236,6 +236,10 @@ module IO::Event
236
236
  end
237
237
 
238
238
  return total
239
+ rescue IOError => error
240
+ return -Errno::EBADF::Errno
241
+ rescue SystemCallError => error
242
+ return -error.errno
239
243
  end
240
244
 
241
245
  def io_write(fiber, _io, buffer, length, offset = 0)
@@ -268,6 +272,10 @@ module IO::Event
268
272
  end
269
273
 
270
274
  return total
275
+ rescue IOError => error
276
+ return -Errno::EBADF::Errno
277
+ rescue SystemCallError => error
278
+ return -error.errno
271
279
  end
272
280
 
273
281
  def blocking(&block)
@@ -5,6 +5,6 @@
5
5
 
6
6
  class IO
7
7
  module Event
8
- VERSION = "1.1.6"
8
+ VERSION = "1.1.7"
9
9
  end
10
10
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io-event
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.6
4
+ version: 1.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -41,7 +41,7 @@ cert_chain:
41
41
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
42
42
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
43
43
  -----END CERTIFICATE-----
44
- date: 2023-01-10 00:00:00.000000000 Z
44
+ date: 2023-03-11 00:00:00.000000000 Z
45
45
  dependencies:
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: bake
@@ -150,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
150
  - !ruby/object:Gem::Version
151
151
  version: '0'
152
152
  requirements: []
153
- rubygems_version: 3.4.1
153
+ rubygems_version: 3.4.6
154
154
  signing_key:
155
155
  specification_version: 4
156
156
  summary: An event loop.
metadata.gz.sig CHANGED
Binary file