io-event 0.3.3 → 1.0.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: 889604c87afea8f1d84e1ee40ada077792e84cfa77d074d695bf6cc1f27b69e1
4
- data.tar.gz: c46aada520c6a8ba41918c7c3f794922befc5012fc9fe5954be6a4b15b920a20
3
+ metadata.gz: 92c441dcc5d0c1c052d12cca378cb86ed81ce156bbff09b8d699699424acb3e6
4
+ data.tar.gz: bd971d884cd6decd4b6e2b0de10248255d17161acb556a709f24aa732594eb32
5
5
  SHA512:
6
- metadata.gz: 98050d505cf276b82824ab4c4371f632609c24fa06249feffbce10eeb8a3d8f45760c4472d4046b473a3da61ab75c60ddbbe93f0e9671d9bd5411abc705558a9
7
- data.tar.gz: dc127c772d0f48fd2710e399aa5f59150724c37f5599b63c2aaba45804fdf1d68075b7808c679158ff7579fc85f5d7e987f7ee92e02493342dd7d2f29b2f5cb8
6
+ metadata.gz: b296a4cabf9c7db248139f23821bd9f43894269494c9f831dd0e56a67ab4b89e7346dcb7bb20c510a5067a2309e0372a743a862c548a7f781c84e3f6a51e4287
7
+ data.tar.gz: fd8df36184a53e494ec16e378721f0d35305c97b561e393821eae88d0c7b8775f04f9f883821530f07a2584525978a4c1c14912dba4f35cfe366638f396a82db
data/ext/IO_Event.bundle CHANGED
Binary file
data/ext/event.o CHANGED
Binary file
data/ext/interrupt.o CHANGED
Binary file
@@ -299,6 +299,11 @@ VALUE io_wait_transfer(VALUE _arguments) {
299
299
 
300
300
  VALUE result = IO_Event_Selector_fiber_transfer(arguments->data->backend.loop, 0, NULL);
301
301
 
302
+ // If the fiber is being cancelled, it might be resumed with nil:
303
+ if (!RTEST(result)) {
304
+ return Qfalse;
305
+ }
306
+
302
307
  return INT2NUM(events_from_epoll_flags(NUM2INT(result)));
303
308
  };
304
309
 
@@ -365,7 +370,7 @@ VALUE io_read_loop(VALUE _arguments) {
365
370
 
366
371
  void *base;
367
372
  size_t size;
368
- rb_io_buffer_get_mutable(arguments->buffer, &base, &size);
373
+ rb_io_buffer_get_bytes_for_writing(arguments->buffer, &base, &size);
369
374
 
370
375
  size_t offset = 0;
371
376
  size_t length = arguments->length;
@@ -437,7 +442,7 @@ VALUE io_write_loop(VALUE _arguments) {
437
442
 
438
443
  const void *base;
439
444
  size_t size;
440
- rb_io_buffer_get_immutable(arguments->buffer, &base, &size);
445
+ rb_io_buffer_get_bytes_for_reading(arguments->buffer, &base, &size);
441
446
 
442
447
  size_t offset = 0;
443
448
  size_t length = arguments->length;
@@ -540,7 +545,11 @@ void select_internal_without_gvl(struct select_arguments *arguments) {
540
545
  arguments->data->blocked = 0;
541
546
 
542
547
  if (arguments->count == -1) {
543
- rb_sys_fail("select_internal_without_gvl:epoll_wait");
548
+ if (errno != EINTR) {
549
+ rb_sys_fail("select_internal_without_gvl:epoll_wait");
550
+ } else {
551
+ arguments->count = 0;
552
+ }
544
553
  }
545
554
  }
546
555
 
@@ -549,7 +558,11 @@ void select_internal_with_gvl(struct select_arguments *arguments) {
549
558
  select_internal((void *)arguments);
550
559
 
551
560
  if (arguments->count == -1) {
552
- rb_sys_fail("select_internal_with_gvl:epoll_wait");
561
+ if (errno != EINTR) {
562
+ rb_sys_fail("select_internal_with_gvl:epoll_wait");
563
+ } else {
564
+ arguments->count = 0;
565
+ }
553
566
  }
554
567
  }
555
568
 
@@ -355,6 +355,11 @@ VALUE io_wait_transfer(VALUE _arguments) {
355
355
 
356
356
  VALUE result = IO_Event_Selector_fiber_transfer(arguments->data->backend.loop, 0, NULL);
357
357
 
358
+ // If the fiber is being cancelled, it might be resumed with nil:
359
+ if (!RTEST(result)) {
360
+ return Qfalse;
361
+ }
362
+
358
363
  return INT2NUM(events_from_kqueue_filter(RB_NUM2INT(result)));
359
364
  }
360
365
 
@@ -396,7 +401,7 @@ VALUE io_read_loop(VALUE _arguments) {
396
401
 
397
402
  void *base;
398
403
  size_t size;
399
- rb_io_buffer_get_mutable(arguments->buffer, &base, &size);
404
+ rb_io_buffer_get_bytes_for_writing(arguments->buffer, &base, &size);
400
405
 
401
406
  size_t offset = 0;
402
407
  size_t length = arguments->length;
@@ -478,7 +483,7 @@ VALUE io_write_loop(VALUE _arguments) {
478
483
 
479
484
  const void *base;
480
485
  size_t size;
481
- rb_io_buffer_get_immutable(arguments->buffer, &base, &size);
486
+ rb_io_buffer_get_bytes_for_reading(arguments->buffer, &base, &size);
482
487
 
483
488
  size_t offset = 0;
484
489
  size_t length = arguments->length;
@@ -605,7 +610,11 @@ void select_internal_without_gvl(struct select_arguments *arguments) {
605
610
  arguments->data->blocked = 0;
606
611
 
607
612
  if (arguments->count == -1) {
608
- rb_sys_fail("select_internal_without_gvl:kevent");
613
+ if (errno != EINTR) {
614
+ rb_sys_fail("select_internal_without_gvl:kevent");
615
+ } else {
616
+ arguments->count = 0;
617
+ }
609
618
  }
610
619
  }
611
620
 
@@ -614,7 +623,11 @@ void select_internal_with_gvl(struct select_arguments *arguments) {
614
623
  select_internal((void *)arguments);
615
624
 
616
625
  if (arguments->count == -1) {
617
- rb_sys_fail("select_internal_with_gvl:kevent");
626
+ if (errno != EINTR) {
627
+ rb_sys_fail("select_internal_with_gvl:kevent");
628
+ } else {
629
+ arguments->count = 0;
630
+ }
618
631
  }
619
632
  }
620
633
 
@@ -27,6 +27,8 @@
27
27
 
28
28
  #include "pidfd.c"
29
29
 
30
+ #include <linux/version.h>
31
+
30
32
  enum {
31
33
  DEBUG = 0,
32
34
  DEBUG_IO_READ = 0,
@@ -336,6 +338,10 @@ VALUE io_wait_transfer(VALUE _arguments) {
336
338
  VALUE result = IO_Event_Selector_fiber_transfer(data->backend.loop, 0, NULL);
337
339
  if (DEBUG) fprintf(stderr, "io_wait:IO_Event_Selector_fiber_transfer -> %d\n", RB_NUM2INT(result));
338
340
 
341
+ if (!RTEST(result)) {
342
+ return Qfalse;
343
+ }
344
+
339
345
  // We explicitly filter the resulting events based on the requested events.
340
346
  // In some cases, poll will report events we didn't ask for.
341
347
  short flags = arguments->flags & NUM2INT(result);
@@ -371,12 +377,28 @@ VALUE IO_Event_Selector_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE e
371
377
 
372
378
  #ifdef HAVE_RUBY_IO_BUFFER_H
373
379
 
380
+ #if LINUX_VERSION_CODE >= KERNEL_VERSION(5,16,0)
381
+ static inline off_t io_seekable(int descriptor) {
382
+ return -1;
383
+ }
384
+ #else
385
+ #warning Upgrade your kernel to 5.16! io_uring bugs prevent efficient io_read/io_write hooks.
386
+ static inline off_t io_seekable(int descriptor)
387
+ {
388
+ if (lseek(descriptor, 0, SEEK_CUR) == -1) {
389
+ return 0;
390
+ } else {
391
+ return -1;
392
+ }
393
+ }
394
+ #endif
395
+
374
396
  static int io_read(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor, char *buffer, size_t length) {
375
397
  struct io_uring_sqe *sqe = io_get_sqe(data);
376
398
 
377
399
  if (DEBUG) fprintf(stderr, "io_read:io_uring_prep_read(fiber=%p)\n", (void*)fiber);
378
400
 
379
- io_uring_prep_read(sqe, descriptor, buffer, length, -1);
401
+ io_uring_prep_read(sqe, descriptor, buffer, length, io_seekable(descriptor));
380
402
  io_uring_sqe_set_data(sqe, (void*)fiber);
381
403
  io_uring_submit_now(data);
382
404
 
@@ -394,7 +416,7 @@ VALUE IO_Event_Selector_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE b
394
416
 
395
417
  void *base;
396
418
  size_t size;
397
- rb_io_buffer_get_mutable(buffer, &base, &size);
419
+ rb_io_buffer_get_bytes_for_writing(buffer, &base, &size);
398
420
 
399
421
  size_t offset = 0;
400
422
  size_t length = NUM2SIZET(_length);
@@ -427,7 +449,7 @@ int io_write(struct IO_Event_Selector_URing *data, VALUE fiber, int descriptor,
427
449
 
428
450
  if (DEBUG) fprintf(stderr, "io_write:io_uring_prep_write(fiber=%p)\n", (void*)fiber);
429
451
 
430
- io_uring_prep_write(sqe, descriptor, buffer, length, -1);
452
+ io_uring_prep_write(sqe, descriptor, buffer, length, io_seekable(descriptor));
431
453
  io_uring_sqe_set_data(sqe, (void*)fiber);
432
454
  io_uring_submit_pending(data);
433
455
 
@@ -445,7 +467,7 @@ VALUE IO_Event_Selector_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE
445
467
 
446
468
  const void *base;
447
469
  size_t size;
448
- rb_io_buffer_get_immutable(buffer, &base, &size);
470
+ rb_io_buffer_get_bytes_for_reading(buffer, &base, &size);
449
471
 
450
472
  size_t offset = 0;
451
473
  size_t length = NUM2SIZET(_length);
@@ -558,6 +580,8 @@ int select_internal_without_gvl(struct select_arguments *arguments) {
558
580
 
559
581
  if (arguments->result == -ETIME) {
560
582
  arguments->result = 0;
583
+ } else if (arguments->result == -EINTR) {
584
+ arguments->result = 0;
561
585
  } else if (arguments->result < 0) {
562
586
  rb_syserr_fail(-arguments->result, "select_internal_without_gvl:io_uring_wait_cqe_timeout");
563
587
  } else {
@@ -568,8 +592,6 @@ int select_internal_without_gvl(struct select_arguments *arguments) {
568
592
  return arguments->result;
569
593
  }
570
594
 
571
- // #define IO_EVENT_SELECTOR_URING_UDATA_INTERRUPT ((__u64) -2)
572
-
573
595
  static inline
574
596
  unsigned select_process_completions(struct io_uring *ring) {
575
597
  unsigned completed = 0;
@@ -585,10 +607,6 @@ unsigned select_process_completions(struct io_uring *ring) {
585
607
  continue;
586
608
  }
587
609
 
588
- // if (cqe->user_data == IO_EVENT_SELECTOR_URING_UDATA_INTERRUPT) {
589
- // io_uring_cq_advance(ring, 1);
590
- // }
591
-
592
610
  VALUE fiber = (VALUE)cqe->user_data;
593
611
  VALUE result = RB_INT2NUM(cqe->res);
594
612
 
data/ext/kqueue.o CHANGED
Binary file
data/ext/selector.o CHANGED
Binary file
@@ -158,7 +158,7 @@ module IO::Event
158
158
  else
159
159
  break unless result
160
160
 
161
- buffer.copy(result, offset)
161
+ buffer.set_string(result, offset)
162
162
 
163
163
  size = result.bytesize
164
164
  offset += size
@@ -176,7 +176,7 @@ module IO::Event
176
176
  while true
177
177
  maximum_size = buffer.size - offset
178
178
 
179
- chunk = buffer.to_str(offset, maximum_size)
179
+ chunk = buffer.get_string(offset, maximum_size)
180
180
  case result = blocking{io.write_nonblock(chunk, exception: false)}
181
181
  when :wait_readable
182
182
  if length > 0
@@ -31,12 +31,10 @@ module IO::Event
31
31
  end
32
32
  end
33
33
 
34
- if self.const_defined?(:URing)
35
- return URing
34
+ if self.const_defined?(:EPoll)
35
+ return EPoll
36
36
  elsif self.const_defined?(:KQueue)
37
37
  return KQueue
38
- elsif self.const_defined?(:EPoll)
39
- return EPoll
40
38
  else
41
39
  return Select
42
40
  end
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module IO::Event
22
- VERSION = "0.3.3"
22
+ VERSION = "1.0.1"
23
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: io-event
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-18 00:00:00.000000000 Z
11
+ date: 2021-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bake
@@ -113,14 +113,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - ">="
115
115
  - !ruby/object:Gem::Version
116
- version: '0'
116
+ version: '3.0'
117
117
  required_rubygems_version: !ruby/object:Gem::Requirement
118
118
  requirements:
119
119
  - - ">="
120
120
  - !ruby/object:Gem::Version
121
121
  version: '0'
122
122
  requirements: []
123
- rubygems_version: 3.3.0.dev
123
+ rubygems_version: 3.3.2
124
124
  signing_key:
125
125
  specification_version: 4
126
126
  summary: An event loop.