io-event 1.1.7 → 1.2.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: 0202b38104b1b6254a15fc12f687f9102509ba75592b1584d3dd5d0e44c497fb
4
- data.tar.gz: 925de8b198ea2a9fca99b7c02c5262dd691a9864601c7db109a79c332804b944
3
+ metadata.gz: 02cbd4beff5335467997d91cbdc8e3bbf509947a15e2f36636b3e4e29b7cd91e
4
+ data.tar.gz: 9ca1138136d115d1fdfd4e41446f6f7b684de878ec6a7834f27a9ea6ba210896
5
5
  SHA512:
6
- metadata.gz: d0bb87512e17c8be8ca0b04390466b0c3de198c6ee4a4a0a074b31d8e2f3bb0f482ece3378d0d9653b9219d36f06d41882f4c78631b27f6c0fb02e4143688d33
7
- data.tar.gz: 4403550628403eccfb92d60e44ccf096ecb2dee1f2e78917fbef65b8c49cc71b15db96b3074e5b16f0ce005f826db928e4a95fd1214973cf33509659195a2e9a
6
+ metadata.gz: 5fe958c76100f346101702b285b140bebe3a149525288cf8e83a1a1806a710928627e8c2d5ae4d8ec716836c264d6f645daa77b944ce1d59a5aaef6ac572e7aa
7
+ data.tar.gz: 9ce5953f7c6c3fba1e41e61fcc4ae7e24a294624a004fc532724fd49c707afc14a837359547df45611e0df6ab35e9d954e6f8e09eed748c845ad6ed8a6b61076
checksums.yaml.gz.sig CHANGED
Binary file
data/ext/extconf.rb CHANGED
@@ -63,6 +63,7 @@ have_func("rb_io_descriptor")
63
63
  have_func("&rb_process_status_wait")
64
64
  have_func("rb_fiber_current")
65
65
  have_func("&rb_fiber_raise")
66
+ have_func("epoll_pwait2")
66
67
 
67
68
  have_header('ruby/io/buffer.h')
68
69
 
@@ -570,38 +570,87 @@ VALUE IO_Event_Selector_EPoll_io_write_compatible(int argc, VALUE *argv, VALUE s
570
570
  #endif
571
571
 
572
572
  static
573
- int make_timeout(VALUE duration) {
573
+ struct timespec * make_timeout(VALUE duration, struct timespec * storage) {
574
574
  if (duration == Qnil) {
575
- return -1;
575
+ return NULL;
576
576
  }
577
577
 
578
578
  if (FIXNUM_P(duration)) {
579
- return NUM2LONG(duration) * 1000L;
579
+ storage->tv_sec = NUM2TIMET(duration);
580
+ storage->tv_nsec = 0;
581
+
582
+ return storage;
580
583
  }
581
584
 
582
585
  else if (RB_FLOAT_TYPE_P(duration)) {
583
586
  double value = RFLOAT_VALUE(duration);
587
+ time_t seconds = value;
584
588
 
585
- return value * 1000;
589
+ storage->tv_sec = seconds;
590
+ storage->tv_nsec = (value - seconds) * 1000000000L;
591
+
592
+ return storage;
586
593
  }
587
594
 
588
595
  rb_raise(rb_eRuntimeError, "unable to convert timeout");
589
596
  }
590
597
 
598
+ static
599
+ int timeout_nonblocking(struct timespec * timespec) {
600
+ return timespec && timespec->tv_sec == 0 && timespec->tv_nsec == 0;
601
+ }
602
+
591
603
  struct select_arguments {
592
604
  struct IO_Event_Selector_EPoll *data;
593
605
 
594
606
  int count;
595
607
  struct epoll_event events[EPOLL_MAX_EVENTS];
596
-
597
- int timeout;
608
+
609
+ struct timespec * timeout;
610
+ struct timespec storage;
598
611
  };
599
612
 
613
+ static int make_timeout_ms(struct timespec * timeout) {
614
+ if (timeout == NULL) {
615
+ return -1;
616
+ }
617
+
618
+ if (timeout_nonblocking(timeout)) {
619
+ return 0;
620
+ }
621
+
622
+ return (timeout->tv_sec * 1000) + (timeout->tv_nsec / 1000000);
623
+ }
624
+
625
+ static
626
+ int enosys_error(int result) {
627
+ if (result == -1) {
628
+ return errno == ENOSYS;
629
+ }
630
+
631
+ return 0;
632
+ }
633
+
600
634
  static
601
635
  void * select_internal(void *_arguments) {
602
636
  struct select_arguments * arguments = (struct select_arguments *)_arguments;
603
637
 
604
- arguments->count = epoll_wait(arguments->data->descriptor, arguments->events, EPOLL_MAX_EVENTS, arguments->timeout);
638
+ #if defined(HAVE_EPOLL_PWAIT2)
639
+ arguments->count = epoll_pwait2(arguments->data->descriptor, arguments->events, EPOLL_MAX_EVENTS, arguments->timeout, NULL);
640
+
641
+ // Comment out the above line and enable the below lines to test ENOSYS code path.
642
+ // arguments->count = -1;
643
+ // errno = ENOSYS;
644
+
645
+ if (!enosys_error(arguments->count)) {
646
+ return NULL;
647
+ }
648
+ else {
649
+ // Fall through and execute epoll_wait fallback.
650
+ }
651
+ #endif
652
+
653
+ arguments->count = epoll_wait(arguments->data->descriptor, arguments->events, EPOLL_MAX_EVENTS, make_timeout_ms(arguments->timeout));
605
654
 
606
655
  return NULL;
607
656
  }
@@ -642,9 +691,14 @@ VALUE IO_Event_Selector_EPoll_select(VALUE self, VALUE duration) {
642
691
 
643
692
  struct select_arguments arguments = {
644
693
  .data = data,
645
- .timeout = 0
694
+ .storage = {
695
+ .tv_sec = 0,
696
+ .tv_nsec = 0
697
+ },
646
698
  };
647
-
699
+
700
+ arguments.timeout = &arguments.storage;
701
+
648
702
  // Process any currently pending events:
649
703
  select_internal_with_gvl(&arguments);
650
704
 
@@ -654,9 +708,9 @@ VALUE IO_Event_Selector_EPoll_select(VALUE self, VALUE duration) {
654
708
  // 3. There are no items in the ready list,
655
709
  // then we can perform a blocking select.
656
710
  if (!ready && !arguments.count && !data->backend.ready) {
657
- arguments.timeout = make_timeout(duration);
711
+ arguments.timeout = make_timeout(duration, &arguments.storage);
658
712
 
659
- if (arguments.timeout != 0) {
713
+ if (!timeout_nonblocking(arguments.timeout)) {
660
714
  // Wait for events to occur
661
715
  select_internal_without_gvl(&arguments);
662
716
  }
@@ -43,7 +43,7 @@ enum IO_Event {
43
43
  IO_EVENT_HANGUP = 16
44
44
  };
45
45
 
46
- void Init_IO_Event_Selector();
46
+ void Init_IO_Event_Selector(VALUE IO_Event_Selector);
47
47
 
48
48
  static inline int IO_Event_try_again(int error) {
49
49
  return error == EAGAIN || error == EWOULDBLOCK;
@@ -5,6 +5,6 @@
5
5
 
6
6
  class IO
7
7
  module Event
8
- VERSION = "1.1.7"
8
+ VERSION = "1.2.1"
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.7
4
+ version: 1.2.1
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-03-11 00:00:00.000000000 Z
44
+ date: 2023-05-13 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.6
153
+ rubygems_version: 3.4.7
154
154
  signing_key:
155
155
  specification_version: 4
156
156
  summary: An event loop.
metadata.gz.sig CHANGED
Binary file