io-event 1.3.2 → 1.3.3

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: 9e419e583855ca1efed750b1ae61bc6fb7b4524cf30cec819a7461eecdb78d45
4
- data.tar.gz: 7c64477599375b9612004acb9e725e7af260a51d404b071e209e866d734a083a
3
+ metadata.gz: 3362ef0fb1bd825601c2476c06e99d32aa911a4e66b189b1518f40b6246b1ab6
4
+ data.tar.gz: a41015ab836dd0e28656427001882a87ba26a424395babb81aecd0e6d07d5fdd
5
5
  SHA512:
6
- metadata.gz: c9b63cafbb56b9eac0f01edd180a70a38de6465ff4624b07360df135d0eeeab984c5348b0981d9c41ce943248af2a554528914e0cb9ae4606737d4ece2b96a8b
7
- data.tar.gz: 1fecec388e9a5c517c83dc233a107cd86121a7e88f3cf5275e0ac00dd7a43aa826ae616b815b556c73ec13e5fc108f9c7cbe1bca1215fb0eb8bfed9daadb048b
6
+ metadata.gz: e1563b616697985daed4bb585bfdeaec00f6dfbaa9f377e99b278a9070f5ee32b475136e0f8f7626e4238a0d623a0bdb745ef03a612ec0de4b7f2eb9ef2f4510
7
+ data.tar.gz: d061bea14bd722ae77eddc68e81d0c4138a5de1b1b12e6fce22a45bc62391c7bf3d9dd25cf0f876361309b04d9e480a06c9752128103c999a504d01e6ffb78d3
checksums.yaml.gz.sig CHANGED
Binary file
@@ -446,6 +446,7 @@ struct process_wait_arguments {
446
446
  struct IO_Event_Selector_EPoll *selector;
447
447
  struct IO_Event_Selector_EPoll_Waiting *waiting;
448
448
  int pid;
449
+ int flags;
449
450
  int descriptor;
450
451
  };
451
452
 
@@ -456,7 +457,7 @@ VALUE process_wait_transfer(VALUE _arguments) {
456
457
  IO_Event_Selector_fiber_transfer(arguments->selector->backend.loop, 0, NULL);
457
458
 
458
459
  if (arguments->waiting->ready) {
459
- return IO_Event_Selector_process_status_wait(arguments->pid);
460
+ return IO_Event_Selector_process_status_wait(arguments->pid, arguments->flags);
460
461
  } else {
461
462
  return Qfalse;
462
463
  }
@@ -480,7 +481,7 @@ VALUE IO_Event_Selector_EPoll_process_wait(VALUE self, VALUE fiber, VALUE _pid,
480
481
  TypedData_Get_Struct(self, struct IO_Event_Selector_EPoll, &IO_Event_Selector_EPoll_Type, selector);
481
482
 
482
483
  pid_t pid = NUM2PIDT(_pid);
483
- // int flags = NUM2INT(_flags);
484
+ int flags = NUM2INT(_flags);
484
485
 
485
486
  int descriptor = pidfd_open(pid, 0);
486
487
 
@@ -506,6 +507,7 @@ VALUE IO_Event_Selector_EPoll_process_wait(VALUE self, VALUE fiber, VALUE _pid,
506
507
  struct process_wait_arguments process_wait_arguments = {
507
508
  .selector = selector,
508
509
  .pid = pid,
510
+ .flags = flags,
509
511
  .descriptor = descriptor,
510
512
  .waiting = &waiting,
511
513
  };
@@ -802,9 +804,11 @@ struct select_arguments {
802
804
 
803
805
  int count;
804
806
  struct epoll_event events[EPOLL_MAX_EVENTS];
805
-
807
+
806
808
  struct timespec * timeout;
807
809
  struct timespec storage;
810
+
811
+ struct IO_Event_List saved;
808
812
  };
809
813
 
810
814
  static int make_timeout_ms(struct timespec * timeout) {
@@ -881,7 +885,7 @@ void select_internal_with_gvl(struct select_arguments *arguments) {
881
885
  }
882
886
 
883
887
  static
884
- int IO_Event_Selector_EPoll_handle(struct IO_Event_Selector_EPoll *selector, const struct epoll_event *event)
888
+ int IO_Event_Selector_EPoll_handle(struct IO_Event_Selector_EPoll *selector, const struct epoll_event *event, struct IO_Event_List *saved)
885
889
  {
886
890
  int descriptor = event->data.fd;
887
891
 
@@ -891,29 +895,32 @@ int IO_Event_Selector_EPoll_handle(struct IO_Event_Selector_EPoll *selector, con
891
895
  struct IO_Event_Selector_EPoll_Descriptor *epoll_descriptor = IO_Event_Selector_EPoll_Descriptor_lookup(selector, descriptor);
892
896
  struct IO_Event_List *list = &epoll_descriptor->list;
893
897
  struct IO_Event_List *node = list->tail;
894
- struct IO_Event_List saved = {NULL, NULL};
895
898
 
896
899
  // Reset the events back to 0 so that we can re-arm if necessary:
897
900
  epoll_descriptor->waiting_events = 0;
898
901
 
902
+ if (DEBUG) fprintf(stderr, "IO_Event_Selector_EPoll_handle: descriptor=%d, ready_events=%d epoll_descriptor=%p\n", descriptor, ready_events, epoll_descriptor);
903
+
899
904
  // It's possible (but unlikely) that the address of list will changing during iteration.
900
905
  while (node != list) {
906
+ if (DEBUG) fprintf(stderr, "IO_Event_Selector_EPoll_handle: node=%p list=%p type=%p\n", node, list, node->type);
907
+
901
908
  struct IO_Event_Selector_EPoll_Waiting *waiting = (struct IO_Event_Selector_EPoll_Waiting *)node;
902
909
 
903
910
  // Compute the intersection of the events we are waiting for and the events that occured:
904
911
  enum IO_Event matching_events = waiting->events & ready_events;
905
912
 
906
- if (DEBUG) fprintf(stderr, "IO_Event_Selector_EPoll_handle: descriptor=%d, ready_events=%d, matching_events=%d\n", descriptor, ready_events, matching_events);
913
+ if (DEBUG) fprintf(stderr, "IO_Event_Selector_EPoll_handle: descriptor=%d, ready_events=%d, waiting_events=%d, matching_events=%d\n", descriptor, ready_events, waiting->events, matching_events);
907
914
 
908
915
  if (matching_events) {
909
- IO_Event_List_append(node, &saved);
916
+ IO_Event_List_append(node, saved);
910
917
 
911
918
  // Resume the fiber:
912
919
  waiting->ready = matching_events;
913
920
  IO_Event_Selector_fiber_transfer(waiting->fiber, 0, NULL);
914
921
 
915
- node = saved.tail;
916
- IO_Event_List_pop(&saved);
922
+ node = saved->tail;
923
+ IO_Event_List_pop(saved);
917
924
  } else {
918
925
  // We are still waiting for the events:
919
926
  epoll_descriptor->waiting_events |= waiting->events;
@@ -924,6 +931,36 @@ int IO_Event_Selector_EPoll_handle(struct IO_Event_Selector_EPoll *selector, con
924
931
  return IO_Event_Selector_EPoll_Descriptor_update(selector, epoll_descriptor->io, descriptor, epoll_descriptor);
925
932
  }
926
933
 
934
+ static
935
+ VALUE select_handle_events(VALUE _arguments)
936
+ {
937
+ struct select_arguments *arguments = (struct select_arguments *)_arguments;
938
+ struct IO_Event_Selector_EPoll *selector = arguments->selector;
939
+
940
+ for (int i = 0; i < arguments->count; i += 1) {
941
+ const struct epoll_event *event = &arguments->events[i];
942
+ if (DEBUG) fprintf(stderr, "-> fd=%d events=%d\n", event->data.fd, event->events);
943
+
944
+ if (event->data.fd >= 0) {
945
+ IO_Event_Selector_EPoll_handle(selector, event, &arguments->saved);
946
+ } else {
947
+ IO_Event_Interrupt_clear(&selector->interrupt);
948
+ }
949
+ }
950
+
951
+ return INT2NUM(arguments->count);
952
+ }
953
+
954
+ static
955
+ VALUE select_handle_events_ensure(VALUE _arguments)
956
+ {
957
+ struct select_arguments *arguments = (struct select_arguments *)_arguments;
958
+
959
+ IO_Event_List_free(&arguments->saved);
960
+
961
+ return Qnil;
962
+ }
963
+
927
964
  // TODO This function is not re-entrant and we should document and assert as such.
928
965
  VALUE IO_Event_Selector_EPoll_select(VALUE self, VALUE duration) {
929
966
  struct IO_Event_Selector_EPoll *selector = NULL;
@@ -937,6 +974,7 @@ VALUE IO_Event_Selector_EPoll_select(VALUE self, VALUE duration) {
937
974
  .tv_sec = 0,
938
975
  .tv_nsec = 0
939
976
  },
977
+ .saved = {},
940
978
  };
941
979
 
942
980
  arguments.timeout = &arguments.storage;
@@ -958,18 +996,11 @@ VALUE IO_Event_Selector_EPoll_select(VALUE self, VALUE duration) {
958
996
  }
959
997
  }
960
998
 
961
- for (int i = 0; i < arguments.count; i += 1) {
962
- const struct epoll_event *event = &arguments.events[i];
963
- if (DEBUG) fprintf(stderr, "-> ptr=%p events=%d\n", event->data.ptr, event->events);
964
-
965
- if (event->data.fd >= 0) {
966
- IO_Event_Selector_EPoll_handle(selector, event);
967
- } else {
968
- IO_Event_Interrupt_clear(&selector->interrupt);
969
- }
999
+ if (arguments.count) {
1000
+ return rb_ensure(select_handle_events, (VALUE)&arguments, select_handle_events_ensure, (VALUE)&arguments);
1001
+ } else {
1002
+ return RB_INT2NUM(0);
970
1003
  }
971
-
972
- return INT2NUM(arguments.count);
973
1004
  }
974
1005
 
975
1006
  VALUE IO_Event_Selector_EPoll_wakeup(VALUE self) {
@@ -433,6 +433,7 @@ struct process_wait_arguments {
433
433
  struct IO_Event_Selector_KQueue *selector;
434
434
  struct IO_Event_Selector_KQueue_Waiting *waiting;
435
435
  pid_t pid;
436
+ int flags;
436
437
  };
437
438
 
438
439
  static
@@ -461,7 +462,7 @@ VALUE process_wait_transfer(VALUE _arguments) {
461
462
 
462
463
  if (arguments->waiting->ready) {
463
464
  process_prewait(arguments->pid);
464
- return IO_Event_Selector_process_status_wait(arguments->pid);
465
+ return IO_Event_Selector_process_status_wait(arguments->pid, arguments->flags);
465
466
  } else {
466
467
  return Qfalse;
467
468
  }
@@ -483,6 +484,7 @@ VALUE IO_Event_Selector_KQueue_process_wait(VALUE self, VALUE fiber, VALUE _pid,
483
484
  TypedData_Get_Struct(self, struct IO_Event_Selector_KQueue, &IO_Event_Selector_KQueue_Type, selector);
484
485
 
485
486
  pid_t pid = NUM2PIDT(_pid);
487
+ int flags = NUM2INT(_flags);
486
488
 
487
489
  struct IO_Event_Selector_KQueue_Waiting waiting = {
488
490
  .list = {.type = &IO_Event_Selector_KQueue_process_wait_list_type},
@@ -494,6 +496,7 @@ VALUE IO_Event_Selector_KQueue_process_wait(VALUE self, VALUE fiber, VALUE _pid,
494
496
  .selector = selector,
495
497
  .waiting = &waiting,
496
498
  .pid = pid,
499
+ .flags = flags,
497
500
  };
498
501
 
499
502
  int result = IO_Event_Selector_KQueue_Waiting_register(selector, pid, &waiting);
@@ -502,7 +505,7 @@ VALUE IO_Event_Selector_KQueue_process_wait(VALUE self, VALUE fiber, VALUE _pid,
502
505
  if (errno == ESRCH) {
503
506
  process_prewait(pid);
504
507
 
505
- return IO_Event_Selector_process_status_wait(pid);
508
+ return IO_Event_Selector_process_status_wait(pid, flags);
506
509
  }
507
510
 
508
511
  rb_sys_fail("IO_Event_Selector_KQueue_process_wait:IO_Event_Selector_KQueue_Waiting_register");
@@ -818,6 +821,8 @@ struct select_arguments {
818
821
 
819
822
  struct timespec storage;
820
823
  struct timespec *timeout;
824
+
825
+ struct IO_Event_List saved;
821
826
  };
822
827
 
823
828
  static
@@ -859,7 +864,7 @@ void select_internal_with_gvl(struct select_arguments *arguments) {
859
864
  }
860
865
 
861
866
  static
862
- int IO_Event_Selector_KQueue_handle(struct IO_Event_Selector_KQueue *selector, uintptr_t identifier, struct IO_Event_Selector_KQueue_Descriptor *kqueue_descriptor)
867
+ int IO_Event_Selector_KQueue_handle(struct IO_Event_Selector_KQueue *selector, uintptr_t identifier, struct IO_Event_Selector_KQueue_Descriptor *kqueue_descriptor, struct IO_Event_List *saved)
863
868
  {
864
869
  // This is the mask of all events that occured for the given descriptor:
865
870
  enum IO_Event ready_events = kqueue_descriptor->ready_events;
@@ -874,7 +879,6 @@ int IO_Event_Selector_KQueue_handle(struct IO_Event_Selector_KQueue *selector, u
874
879
 
875
880
  struct IO_Event_List *list = &kqueue_descriptor->list;
876
881
  struct IO_Event_List *node = list->tail;
877
- struct IO_Event_List saved = {NULL, NULL};
878
882
 
879
883
  // Reset the events back to 0 so that we can re-arm if necessary:
880
884
  kqueue_descriptor->waiting_events = 0;
@@ -888,13 +892,13 @@ int IO_Event_Selector_KQueue_handle(struct IO_Event_Selector_KQueue *selector, u
888
892
  if (DEBUG) fprintf(stderr, "IO_Event_Selector_KQueue_handle: identifier=%lu, ready_events=%d, matching_events=%d\n", identifier, ready_events, matching_events);
889
893
 
890
894
  if (matching_events) {
891
- IO_Event_List_append(node, &saved);
895
+ IO_Event_List_append(node, saved);
892
896
 
893
897
  waiting->ready = matching_events;
894
898
  IO_Event_Selector_fiber_transfer(waiting->fiber, 0, NULL);
895
899
 
896
- node = saved.tail;
897
- IO_Event_List_pop(&saved);
900
+ node = saved->tail;
901
+ IO_Event_List_pop(saved);
898
902
  } else {
899
903
  kqueue_descriptor->waiting_events |= waiting->events;
900
904
  node = node->tail;
@@ -904,6 +908,43 @@ int IO_Event_Selector_KQueue_handle(struct IO_Event_Selector_KQueue *selector, u
904
908
  return IO_Event_Selector_KQueue_Descriptor_update(selector, identifier, kqueue_descriptor);
905
909
  }
906
910
 
911
+ static
912
+ VALUE select_handle_events(VALUE _arguments)
913
+ {
914
+ struct select_arguments *arguments = (struct select_arguments *)_arguments;
915
+ struct IO_Event_Selector_KQueue *selector = arguments->selector;
916
+
917
+ for (int i = 0; i < arguments->count; i += 1) {
918
+ if (arguments->events[i].udata) {
919
+ struct IO_Event_Selector_KQueue_Descriptor *kqueue_descriptor = arguments->events[i].udata;
920
+ kqueue_descriptor->ready_events |= events_from_kevent_filter(arguments->events[i].filter);
921
+ }
922
+ }
923
+
924
+ for (int i = 0; i < arguments->count; i += 1) {
925
+ if (arguments->events[i].udata) {
926
+ struct IO_Event_Selector_KQueue_Descriptor *kqueue_descriptor = arguments->events[i].udata;
927
+ IO_Event_Selector_KQueue_handle(selector, arguments->events[i].ident, kqueue_descriptor, &arguments->saved);
928
+ } else {
929
+ #ifdef IO_EVENT_SELECTOR_KQUEUE_USE_INTERRUPT
930
+ IO_Event_Interrupt_clear(&selector->interrupt);
931
+ #endif
932
+ }
933
+ }
934
+
935
+ return RB_INT2NUM(arguments->count);
936
+ }
937
+
938
+ static
939
+ VALUE select_handle_events_ensure(VALUE _arguments)
940
+ {
941
+ struct select_arguments *arguments = (struct select_arguments *)_arguments;
942
+
943
+ IO_Event_List_free(&arguments->saved);
944
+
945
+ return Qnil;
946
+ }
947
+
907
948
  VALUE IO_Event_Selector_KQueue_select(VALUE self, VALUE duration) {
908
949
  struct IO_Event_Selector_KQueue *selector = NULL;
909
950
  TypedData_Get_Struct(self, struct IO_Event_Selector_KQueue, &IO_Event_Selector_KQueue_Type, selector);
@@ -916,7 +957,8 @@ VALUE IO_Event_Selector_KQueue_select(VALUE self, VALUE duration) {
916
957
  .storage = {
917
958
  .tv_sec = 0,
918
959
  .tv_nsec = 0
919
- }
960
+ },
961
+ .saved = {},
920
962
  };
921
963
 
922
964
  arguments.timeout = &arguments.storage;
@@ -948,25 +990,11 @@ VALUE IO_Event_Selector_KQueue_select(VALUE self, VALUE duration) {
948
990
  }
949
991
  }
950
992
 
951
- for (int i = 0; i < arguments.count; i += 1) {
952
- if (arguments.events[i].udata) {
953
- struct IO_Event_Selector_KQueue_Descriptor *kqueue_descriptor = arguments.events[i].udata;
954
- kqueue_descriptor->ready_events |= events_from_kevent_filter(arguments.events[i].filter);
955
- }
956
- }
957
-
958
- for (int i = 0; i < arguments.count; i += 1) {
959
- if (arguments.events[i].udata) {
960
- struct IO_Event_Selector_KQueue_Descriptor *kqueue_descriptor = arguments.events[i].udata;
961
- IO_Event_Selector_KQueue_handle(selector, arguments.events[i].ident, kqueue_descriptor);
962
- } else {
963
- #ifdef IO_EVENT_SELECTOR_KQUEUE_USE_INTERRUPT
964
- IO_Event_Interrupt_clear(&selector->interrupt);
965
- #endif
966
- }
993
+ if (arguments.count) {
994
+ return rb_ensure(select_handle_events, (VALUE)&arguments, select_handle_events_ensure, (VALUE)&arguments);
995
+ } else {
996
+ return RB_INT2NUM(0);
967
997
  }
968
-
969
- return RB_INT2NUM(arguments.count);
970
998
  }
971
999
 
972
1000
  VALUE IO_Event_Selector_KQueue_wakeup(VALUE self) {
@@ -21,6 +21,7 @@ inline static void IO_Event_List_initialize(struct IO_Event_List *list)
21
21
  inline static void IO_Event_List_clear(struct IO_Event_List *list)
22
22
  {
23
23
  list->head = list->tail = NULL;
24
+ list->type = 0;
24
25
  }
25
26
 
26
27
  // Append an item to the end of the list.
@@ -64,7 +65,7 @@ inline static void IO_Event_List_pop(struct IO_Event_List *node)
64
65
 
65
66
  inline static void IO_Event_List_free(struct IO_Event_List *node)
66
67
  {
67
- if (node->head != node->tail) {
68
+ if (node->head && node->tail) {
68
69
  IO_Event_List_pop(node);
69
70
  }
70
71
  }
@@ -25,10 +25,6 @@ static const int DEBUG = 0;
25
25
 
26
26
  static ID id_transfer, id_alive_p;
27
27
 
28
- #ifndef HAVE_RB_PROCESS_STATUS_WAIT
29
- static VALUE process_wnohang;
30
- #endif
31
-
32
28
  VALUE IO_Event_Selector_fiber_transfer(VALUE fiber, int argc, VALUE *argv) {
33
29
  // TODO Consider introducing something like `rb_fiber_scheduler_transfer(...)`.
34
30
  #ifdef HAVE__RB_FIBER_TRANSFER
@@ -76,9 +72,9 @@ int IO_Event_Selector_io_descriptor(VALUE io) {
76
72
  static ID id_wait;
77
73
  static VALUE rb_Process_Status = Qnil;
78
74
 
79
- VALUE IO_Event_Selector_process_status_wait(rb_pid_t pid)
75
+ VALUE IO_Event_Selector_process_status_wait(rb_pid_t pid, int flags)
80
76
  {
81
- return rb_funcall(rb_Process_Status, id_wait, 2, PIDT2NUM(pid), process_wnohang);
77
+ return rb_funcall(rb_Process_Status, id_wait, 2, PIDT2NUM(pid), INT2NUM(flags | WNOHANG));
82
78
  }
83
79
  #endif
84
80
 
@@ -157,7 +153,6 @@ void Init_IO_Event_Selector(VALUE IO_Event_Selector) {
157
153
 
158
154
  #ifndef HAVE_RB_PROCESS_STATUS_WAIT
159
155
  id_wait = rb_intern("wait");
160
- process_wnohang = rb_const_get(rb_mProcess, rb_intern("WNOHANG"));
161
156
  rb_Process_Status = rb_const_get_at(rb_mProcess, rb_intern("Status"));
162
157
  rb_gc_register_mark_object(rb_Process_Status);
163
158
  #endif
@@ -66,10 +66,11 @@ VALUE IO_Event_Selector_fiber_raise(VALUE fiber, int argc, VALUE *argv);
66
66
  int IO_Event_Selector_io_descriptor(VALUE io);
67
67
  #endif
68
68
 
69
+ // Reap a process without hanging.
69
70
  #ifdef HAVE_RB_PROCESS_STATUS_WAIT
70
- #define IO_Event_Selector_process_status_wait(pid) rb_process_status_wait(pid)
71
+ #define IO_Event_Selector_process_status_wait(pid, flags) rb_process_status_wait(pid, flags | WNOHANG)
71
72
  #else
72
- VALUE IO_Event_Selector_process_status_wait(rb_pid_t pid);
73
+ VALUE IO_Event_Selector_process_status_wait(rb_pid_t pid, int flags);
73
74
  #endif
74
75
 
75
76
  int IO_Event_Selector_nonblock_set(int file_descriptor);
@@ -428,6 +428,7 @@ struct process_wait_arguments {
428
428
  struct IO_Event_Selector_URing_Waiting *waiting;
429
429
 
430
430
  pid_t pid;
431
+ int flags;
431
432
  int descriptor;
432
433
  };
433
434
 
@@ -438,7 +439,7 @@ VALUE process_wait_transfer(VALUE _arguments) {
438
439
  IO_Event_Selector_fiber_transfer(arguments->selector->backend.loop, 0, NULL);
439
440
 
440
441
  if (arguments->waiting->result) {
441
- return IO_Event_Selector_process_status_wait(arguments->pid);
442
+ return IO_Event_Selector_process_status_wait(arguments->pid, arguments->flags);
442
443
  } else {
443
444
  return Qfalse;
444
445
  }
@@ -460,6 +461,7 @@ VALUE IO_Event_Selector_URing_process_wait(VALUE self, VALUE fiber, VALUE _pid,
460
461
  TypedData_Get_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, selector);
461
462
 
462
463
  pid_t pid = NUM2PIDT(_pid);
464
+ int flags = NUM2INT(_flags);
463
465
 
464
466
  int descriptor = pidfd_open(pid, 0);
465
467
  if (descriptor < 0) {
@@ -477,6 +479,7 @@ VALUE IO_Event_Selector_URing_process_wait(VALUE self, VALUE fiber, VALUE _pid,
477
479
  .selector = selector,
478
480
  .waiting = &waiting,
479
481
  .pid = pid,
482
+ .flags = flags,
480
483
  .descriptor = descriptor,
481
484
  };
482
485
 
@@ -280,7 +280,9 @@ module IO::Event
280
280
  elsif Support.fiber_scheduler_v1?
281
281
  # Ruby <= 3.1, limited IO::Buffer support.
282
282
  def io_read(fiber, _io, buffer, length, offset = 0)
283
+ # We need to avoid any internal buffering, so we use a duplicated IO object:
283
284
  io = IO.for_fd(_io.fileno, autoclose: false)
285
+
284
286
  total = 0
285
287
 
286
288
  maximum_size = buffer.size - offset
@@ -321,7 +323,9 @@ module IO::Event
321
323
  end
322
324
 
323
325
  def io_write(fiber, _io, buffer, length, offset = 0)
326
+ # We need to avoid any internal buffering, so we use a duplicated IO object:
324
327
  io = IO.for_fd(_io.fileno, autoclose: false)
328
+
325
329
  total = 0
326
330
 
327
331
  maximum_size = buffer.size - offset
@@ -5,6 +5,6 @@
5
5
 
6
6
  class IO
7
7
  module Event
8
- VERSION = "1.3.2"
8
+ VERSION = "1.3.3"
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.3.2
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -42,7 +42,7 @@ cert_chain:
42
42
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
43
43
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
44
44
  -----END CERTIFICATE-----
45
- date: 2023-08-24 00:00:00.000000000 Z
45
+ date: 2023-10-24 00:00:00.000000000 Z
46
46
  dependencies: []
47
47
  description:
48
48
  email:
@@ -97,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
97
  - !ruby/object:Gem::Version
98
98
  version: '0'
99
99
  requirements: []
100
- rubygems_version: 3.5.0.dev
100
+ rubygems_version: 3.4.10
101
101
  signing_key:
102
102
  specification_version: 4
103
103
  summary: An event loop.
metadata.gz.sig CHANGED
Binary file