io-event 1.6.5 → 1.6.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53b1f32affa83ac713eaaf8fba4b9a1c9d2f25421908759dde9b5adec11c498f
4
- data.tar.gz: 6504222eab182d55f2b56ef91c4de9f301f509a69fff17f286c03f0ef0315786
3
+ metadata.gz: 53bb3bfd2bffe7db8d43a4dd2d136a2ec9b62df30b78f90894b816a33a855765
4
+ data.tar.gz: 151b806b36724b5f210e28a59949ca4c4550a79a15e29174b6c7bdf9e5e4ba7d
5
5
  SHA512:
6
- metadata.gz: ac5f863272fb2a532d1adbe16e2960f78dd6f4ce52891e391f301d40bb28ad74e2775348d55610f1f308f7a69b0b362e93f794b44fe94b4ec6e91331a2e851d5
7
- data.tar.gz: 042a1a3ba4ec1a3e438d823b9d9348eeebc86be2464030744a9a01ff50654aeeb229fb79729083d3f1bdb2feb968dcee8ec320d33de7083196eb1afd887c5ef6
6
+ metadata.gz: ef219c25c4acc91a0fb56bfb3a36275b131d71e594682c0f6d383e0d66657ecd286b711bf90323e661d83be0961fa0baaf4368c0e3c2309b0e3376f9c006fefc
7
+ data.tar.gz: 56112593370c044238ee9198ef1ee608e0be69507a37dd380c9a54d03948074b1ec89e692308f4b6e58096730398be1fd2a3efee4c9e055977e543058716aaec
checksums.yaml.gz.sig CHANGED
Binary file
data/ext/extconf.rb CHANGED
@@ -2,21 +2,23 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # Released under the MIT License.
5
- # Copyright, 2021-2023, by Samuel Williams.
5
+ # Copyright, 2021-2024, by Samuel Williams.
6
6
  # Copyright, 2023, by Math Ieu.
7
7
 
8
8
  return if RUBY_DESCRIPTION =~ /jruby/
9
9
 
10
- require 'mkmf'
10
+ require "mkmf"
11
11
 
12
12
  gem_name = File.basename(__dir__)
13
- extension_name = 'IO_Event'
13
+ extension_name = "IO_Event"
14
14
 
15
15
  # dir_config(extension_name)
16
16
 
17
17
  $CFLAGS << " -Wall -Wno-unknown-pragmas -std=c99"
18
18
 
19
- if ENV.key?('RUBY_DEBUG')
19
+ if ENV.key?("RUBY_DEBUG")
20
+ $stderr.puts "Enabling debug mode..."
21
+
20
22
  $CFLAGS << " -DRUBY_DEBUG -O0"
21
23
  end
22
24
 
@@ -24,24 +26,24 @@ $srcs = ["io/event/event.c", "io/event/selector/selector.c"]
24
26
  $VPATH << "$(srcdir)/io/event"
25
27
  $VPATH << "$(srcdir)/io/event/selector"
26
28
 
27
- have_func('rb_ext_ractor_safe')
28
- have_func('&rb_fiber_transfer')
29
+ have_func("rb_ext_ractor_safe")
30
+ have_func("&rb_fiber_transfer")
29
31
 
30
- if have_library('uring') and have_header('liburing.h')
32
+ if have_library("uring") and have_header("liburing.h")
31
33
  $srcs << "io/event/selector/uring.c"
32
34
  end
33
35
 
34
- if have_header('sys/epoll.h')
36
+ if have_header("sys/epoll.h")
35
37
  $srcs << "io/event/selector/epoll.c"
36
38
  end
37
39
 
38
- if have_header('sys/event.h')
40
+ if have_header("sys/event.h")
39
41
  $srcs << "io/event/selector/kqueue.c"
40
42
  end
41
43
 
42
- have_header('sys/wait.h')
44
+ have_header("sys/wait.h")
43
45
 
44
- have_header('sys/eventfd.h')
46
+ have_header("sys/eventfd.h")
45
47
  $srcs << "io/event/interrupt.c"
46
48
 
47
49
  have_func("rb_io_descriptor")
@@ -50,7 +52,15 @@ have_func("rb_fiber_current")
50
52
  have_func("&rb_fiber_raise")
51
53
  have_func("epoll_pwait2")
52
54
 
53
- have_header('ruby/io/buffer.h')
55
+ have_header("ruby/io/buffer.h")
56
+
57
+ if ENV.key?("RUBY_SANITIZE")
58
+ $stderr.puts "Enabling sanitizers..."
59
+
60
+ # Add address and undefined behaviour sanitizers:
61
+ $CFLAGS << " -fsanitize=address -fsanitize=undefined -fno-omit-frame-pointer"
62
+ $LDFLAGS << " -fsanitize=address -fsanitize=undefined"
63
+ end
54
64
 
55
65
  create_header
56
66
 
@@ -29,6 +29,8 @@ inline static void IO_Event_Array_allocate(struct IO_Event_Array *array, size_t
29
29
  {
30
30
  if (count) {
31
31
  array->base = (void**)calloc(count, sizeof(void*));
32
+ assert(array->base);
33
+
32
34
  array->count = count;
33
35
  } else {
34
36
  array->base = NULL;
@@ -51,6 +53,7 @@ inline static void IO_Event_Array_free(struct IO_Event_Array *array)
51
53
  void *element = array->base[i];
52
54
  if (element) {
53
55
  array->element_free(element);
56
+
54
57
  free(element);
55
58
  }
56
59
  }
@@ -107,6 +110,7 @@ inline static void* IO_Event_Array_lookup(struct IO_Event_Array *array, size_t i
107
110
  // Allocate the element if it doesn't exist:
108
111
  if (*element == NULL) {
109
112
  *element = malloc(array->element_size);
113
+ assert(*element);
110
114
 
111
115
  if (array->element_initialize) {
112
116
  array->element_initialize(*element);
@@ -184,7 +184,7 @@ static const rb_data_type_t IO_Event_Selector_EPoll_Type = {
184
184
  .dsize = IO_Event_Selector_EPoll_Type_size,
185
185
  },
186
186
  .data = NULL,
187
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
187
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
188
188
  };
189
189
 
190
190
  inline static
@@ -333,7 +333,7 @@ VALUE IO_Event_Selector_EPoll_allocate(VALUE self) {
333
333
  struct IO_Event_Selector_EPoll *selector = NULL;
334
334
  VALUE instance = TypedData_Make_Struct(self, struct IO_Event_Selector_EPoll, &IO_Event_Selector_EPoll_Type, selector);
335
335
 
336
- IO_Event_Selector_initialize(&selector->backend, Qnil);
336
+ IO_Event_Selector_initialize(&selector->backend, self, Qnil);
337
337
  selector->descriptor = -1;
338
338
  selector->blocked = 0;
339
339
 
@@ -363,7 +363,7 @@ VALUE IO_Event_Selector_EPoll_initialize(VALUE self, VALUE loop) {
363
363
  struct IO_Event_Selector_EPoll *selector = NULL;
364
364
  TypedData_Get_Struct(self, struct IO_Event_Selector_EPoll, &IO_Event_Selector_EPoll_Type, selector);
365
365
 
366
- IO_Event_Selector_initialize(&selector->backend, loop);
366
+ IO_Event_Selector_initialize(&selector->backend, self, loop);
367
367
  int result = epoll_create1(EPOLL_CLOEXEC);
368
368
 
369
369
  if (result == -1) {
@@ -183,7 +183,7 @@ static const rb_data_type_t IO_Event_Selector_KQueue_Type = {
183
183
  .dsize = IO_Event_Selector_KQueue_Type_size,
184
184
  },
185
185
  .data = NULL,
186
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
186
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
187
187
  };
188
188
 
189
189
  inline static
@@ -307,7 +307,7 @@ VALUE IO_Event_Selector_KQueue_allocate(VALUE self) {
307
307
  struct IO_Event_Selector_KQueue *selector = NULL;
308
308
  VALUE instance = TypedData_Make_Struct(self, struct IO_Event_Selector_KQueue, &IO_Event_Selector_KQueue_Type, selector);
309
309
 
310
- IO_Event_Selector_initialize(&selector->backend, Qnil);
310
+ IO_Event_Selector_initialize(&selector->backend, self, Qnil);
311
311
  selector->descriptor = -1;
312
312
  selector->blocked = 0;
313
313
 
@@ -340,7 +340,7 @@ VALUE IO_Event_Selector_KQueue_initialize(VALUE self, VALUE loop) {
340
340
  struct IO_Event_Selector_KQueue *selector = NULL;
341
341
  TypedData_Get_Struct(self, struct IO_Event_Selector_KQueue, &IO_Event_Selector_KQueue_Type, selector);
342
342
 
343
- IO_Event_Selector_initialize(&selector->backend, loop);
343
+ IO_Event_Selector_initialize(&selector->backend, self, loop);
344
344
  int result = kqueue();
345
345
 
346
346
  if (result == -1) {
@@ -172,24 +172,35 @@ static void queue_pop(struct IO_Event_Selector *backend, struct IO_Event_Selecto
172
172
  if (waiting->head) {
173
173
  waiting->head->tail = waiting->tail;
174
174
  } else {
175
+ // We must have been at the head of the queue:
175
176
  backend->waiting = waiting->tail;
176
177
  }
177
178
 
178
179
  if (waiting->tail) {
179
180
  waiting->tail->head = waiting->head;
180
181
  } else {
182
+ // We must have been at the tail of the queue:
181
183
  backend->ready = waiting->head;
182
184
  }
185
+
186
+ waiting->head = NULL;
187
+ waiting->tail = NULL;
183
188
  }
184
189
 
185
190
  static void queue_push(struct IO_Event_Selector *backend, struct IO_Event_Selector_Queue *waiting) {
191
+ assert(waiting->head == NULL);
192
+ assert(waiting->tail == NULL);
193
+
186
194
  if (backend->waiting) {
195
+ // If there was an item in the queue already, we shift it along:
187
196
  backend->waiting->head = waiting;
188
197
  waiting->tail = backend->waiting;
189
198
  } else {
199
+ // If the queue was empty, we update the tail too:
190
200
  backend->ready = waiting;
191
201
  }
192
202
 
203
+ // We always push to the front/head:
193
204
  backend->waiting = waiting;
194
205
  }
195
206
 
@@ -270,11 +281,14 @@ VALUE IO_Event_Selector_raise(struct IO_Event_Selector *backend, int argc, VALUE
270
281
  void IO_Event_Selector_queue_push(struct IO_Event_Selector *backend, VALUE fiber)
271
282
  {
272
283
  struct IO_Event_Selector_Queue *waiting = malloc(sizeof(struct IO_Event_Selector_Queue));
284
+ assert(waiting);
273
285
 
274
286
  waiting->head = NULL;
275
287
  waiting->tail = NULL;
276
288
  waiting->flags = IO_EVENT_SELECTOR_QUEUE_INTERNAL;
289
+
277
290
  waiting->fiber = fiber;
291
+ RB_OBJ_WRITTEN(backend->self, Qundef, fiber);
278
292
 
279
293
  queue_push(backend, waiting);
280
294
  }
@@ -283,9 +297,10 @@ static inline
283
297
  void IO_Event_Selector_queue_pop(struct IO_Event_Selector *backend, struct IO_Event_Selector_Queue *ready)
284
298
  {
285
299
  if (DEBUG) fprintf(stderr, "IO_Event_Selector_queue_pop -> %p\n", (void*)ready->fiber);
300
+
286
301
  if (ready->flags & IO_EVENT_SELECTOR_QUEUE_FIBER) {
287
302
  IO_Event_Selector_fiber_transfer(ready->fiber, 0, NULL);
288
- } else {
303
+ } else if (ready->flags & IO_EVENT_SELECTOR_QUEUE_INTERNAL) {
289
304
  VALUE fiber = ready->fiber;
290
305
  queue_pop(backend, ready);
291
306
  free(ready);
@@ -293,6 +308,8 @@ void IO_Event_Selector_queue_pop(struct IO_Event_Selector *backend, struct IO_Ev
293
308
  if (RTEST(rb_funcall(fiber, id_alive_p, 0))) {
294
309
  rb_funcall(fiber, id_transfer, 0);
295
310
  }
311
+ } else {
312
+ rb_raise(rb_eRuntimeError, "Unknown queue type!");
296
313
  }
297
314
  }
298
315
 
@@ -300,6 +317,8 @@ int IO_Event_Selector_queue_flush(struct IO_Event_Selector *backend)
300
317
  {
301
318
  int count = 0;
302
319
 
320
+ // During iteration of the queue, the same item may be re-queued. If we don't handle this correctly, we may end up in an infinite loop. So, to avoid this situation, we keep note of the current head of the queue and break the loop if we reach the same item again.
321
+
303
322
  // Get the current tail and head of the queue:
304
323
  struct IO_Event_Selector_Queue *waiting = backend->waiting;
305
324
  if (DEBUG) fprintf(stderr, "IO_Event_Selector_queue_flush waiting = %p\n", waiting);
@@ -95,27 +95,31 @@ struct IO_Event_Selector_Queue {
95
95
  };
96
96
 
97
97
  struct IO_Event_Selector {
98
+ VALUE self;
98
99
  VALUE loop;
99
100
 
100
101
  struct IO_Event_Selector_Queue *free;
101
102
 
102
- // Append to waiting.
103
+ // Append to waiting (front/head of queue).
103
104
  struct IO_Event_Selector_Queue *waiting;
104
- // Process from ready.
105
+ // Process from ready (back/tail of queue).
105
106
  struct IO_Event_Selector_Queue *ready;
106
107
  };
107
108
 
108
109
  static inline
109
- void IO_Event_Selector_initialize(struct IO_Event_Selector *backend, VALUE loop) {
110
- backend->loop = loop;
110
+ void IO_Event_Selector_initialize(struct IO_Event_Selector *backend, VALUE self, VALUE loop) {
111
+ RB_OBJ_WRITE(self, &backend->self, self);
112
+ RB_OBJ_WRITE(self, &backend->loop, loop);
111
113
  backend->waiting = NULL;
112
114
  backend->ready = NULL;
113
115
  }
114
116
 
115
117
  static inline
116
118
  void IO_Event_Selector_mark(struct IO_Event_Selector *backend) {
119
+ rb_gc_mark_movable(backend->self);
117
120
  rb_gc_mark_movable(backend->loop);
118
121
 
122
+ // Walk backwards through the ready queue:
119
123
  struct IO_Event_Selector_Queue *ready = backend->ready;
120
124
  while (ready) {
121
125
  rb_gc_mark_movable(ready->fiber);
@@ -125,6 +129,7 @@ void IO_Event_Selector_mark(struct IO_Event_Selector *backend) {
125
129
 
126
130
  static inline
127
131
  void IO_Event_Selector_compact(struct IO_Event_Selector *backend) {
132
+ backend->self = rb_gc_location(backend->self);
128
133
  backend->loop = rb_gc_location(backend->loop);
129
134
 
130
135
  struct IO_Event_Selector_Queue *ready = backend->ready;
@@ -152,7 +152,7 @@ static const rb_data_type_t IO_Event_Selector_URing_Type = {
152
152
  .dsize = IO_Event_Selector_URing_Type_size,
153
153
  },
154
154
  .data = NULL,
155
- .flags = RUBY_TYPED_FREE_IMMEDIATELY,
155
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
156
156
  };
157
157
 
158
158
  inline static
@@ -228,7 +228,7 @@ VALUE IO_Event_Selector_URing_allocate(VALUE self) {
228
228
  struct IO_Event_Selector_URing *selector = NULL;
229
229
  VALUE instance = TypedData_Make_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, selector);
230
230
 
231
- IO_Event_Selector_initialize(&selector->backend, Qnil);
231
+ IO_Event_Selector_initialize(&selector->backend, self, Qnil);
232
232
  selector->ring.ring_fd = -1;
233
233
 
234
234
  selector->pending = 0;
@@ -249,7 +249,7 @@ VALUE IO_Event_Selector_URing_initialize(VALUE self, VALUE loop) {
249
249
  struct IO_Event_Selector_URing *selector = NULL;
250
250
  TypedData_Get_Struct(self, struct IO_Event_Selector_URing, &IO_Event_Selector_URing_Type, selector);
251
251
 
252
- IO_Event_Selector_initialize(&selector->backend, loop);
252
+ IO_Event_Selector_initialize(&selector->backend, self, loop);
253
253
  int result = io_uring_queue_init(URING_ENTRIES, &selector->ring, 0);
254
254
 
255
255
  if (result < 0) {
@@ -3,7 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2021-2024, by Samuel Williams.
5
5
 
6
- require_relative '../support'
6
+ require_relative "../support"
7
7
 
8
8
  module IO::Event
9
9
  module Debug
@@ -12,8 +12,8 @@ module IO::Event
12
12
  def self.wrap(selector, env = ENV)
13
13
  log = nil
14
14
 
15
- if log_path = env['IO_EVENT_DEBUG_SELECTOR_LOG']
16
- log = File.open(log_path, 'w')
15
+ if log_path = env["IO_EVENT_DEBUG_SELECTOR_LOG"]
16
+ log = File.open(log_path, "w")
17
17
  end
18
18
 
19
19
  return self.new(selector, log: log)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2021-2023, by Samuel Williams.
4
+ # Copyright, 2021-2024, by Samuel Williams.
5
5
 
6
6
  module IO::Event
7
7
  # A thread safe synchronisation primative.
@@ -27,7 +27,7 @@ module IO::Event
27
27
 
28
28
  # Send a sigle byte interrupt.
29
29
  def signal
30
- @output.write('.')
30
+ @output.write(".")
31
31
  @output.flush
32
32
  rescue IOError
33
33
  # Ignore.
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2022-2023, by Samuel Williams.
4
+ # Copyright, 2022-2024, by Samuel Williams.
5
5
 
6
- require 'io/nonblock'
6
+ require "io/nonblock"
7
7
 
8
8
  module IO::Event
9
9
  module Selector
@@ -4,8 +4,8 @@
4
4
  # Copyright, 2021-2024, by Samuel Williams.
5
5
  # Copyright, 2023, by Math Ieu.
6
6
 
7
- require_relative '../interrupt'
8
- require_relative '../support'
7
+ require_relative "../interrupt"
8
+ require_relative "../support"
9
9
 
10
10
  module IO::Event
11
11
  module Selector
@@ -168,6 +168,8 @@ module IO::Event
168
168
  if Support.fiber_scheduler_v3?
169
169
  # Ruby 3.3+, full IO::Buffer support.
170
170
 
171
+ # Read from the given IO to the buffer.
172
+ #
171
173
  # @parameter length [Integer] The minimum number of bytes to read.
172
174
  # @parameter offset [Integer] The offset into the buffer to read to.
173
175
  def io_read(fiber, io, buffer, length, offset = 0)
@@ -196,6 +198,8 @@ module IO::Event
196
198
  return total
197
199
  end
198
200
 
201
+ # Write to the given IO from the buffer.
202
+ #
199
203
  # @parameter length [Integer] The minimum number of bytes to write.
200
204
  # @parameter offset [Integer] The offset into the buffer to write from.
201
205
  def io_write(fiber, io, buffer, length, offset = 0)
@@ -3,14 +3,14 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2021-2024, by Samuel Williams.
5
5
 
6
- require_relative 'selector/select'
7
- require_relative 'debug/selector'
8
- require_relative 'support'
6
+ require_relative "selector/select"
7
+ require_relative "debug/selector"
8
+ require_relative "support"
9
9
 
10
10
  module IO::Event
11
11
  module Selector
12
12
  def self.default(env = ENV)
13
- if name = env['IO_EVENT_SELECTOR']&.to_sym
13
+ if name = env["IO_EVENT_SELECTOR"]&.to_sym
14
14
  return const_get(name)
15
15
  end
16
16
 
@@ -28,7 +28,7 @@ module IO::Event
28
28
  def self.new(loop, env = ENV)
29
29
  selector = default(env).new(loop)
30
30
 
31
- if debug = env['IO_EVENT_DEBUG_SELECTOR']
31
+ if debug = env["IO_EVENT_DEBUG_SELECTOR"]
32
32
  selector = Debug::Selector.wrap(selector, env)
33
33
  end
34
34
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Released under the MIT License.
4
- # Copyright, 2022-2023, by Samuel Williams.
4
+ # Copyright, 2022-2024, by Samuel Williams.
5
5
 
6
6
  class IO
7
7
  module Event
@@ -10,14 +10,23 @@ class IO
10
10
  IO.const_defined?(:Buffer)
11
11
  end
12
12
 
13
+ # To be removed on 31 Mar 2025.
13
14
  def self.fiber_scheduler_v1?
14
- IO.const_defined?(:Buffer) and !Fiber.respond_to?(:blocking)
15
+ IO.const_defined?(:Buffer)
15
16
  end
16
17
 
18
+ # To be removed on 31 Mar 2026.
17
19
  def self.fiber_scheduler_v2?
20
+ # Some interface changes were back-ported incorrectly:
21
+ # https://github.com/ruby/ruby/pull/10778
22
+ # Specifically "Improvements to IO::Buffer read/write/pread/pwrite."
23
+ # Missing correct size calculation.
24
+ return false if RUBY_VERSION >= "3.2.5"
25
+
18
26
  IO.const_defined?(:Buffer) and Fiber.respond_to?(:blocking) and IO::Buffer.instance_method(:read).arity == -1
19
27
  end
20
28
 
29
+ # To become the default 31 Mar 2026.
21
30
  def self.fiber_scheduler_v3?
22
31
  if fiber_scheduler_v2?
23
32
  return true if RUBY_VERSION >= "3.3"
@@ -3,7 +3,7 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2024, by Samuel Williams.
5
5
 
6
- require_relative 'priority_heap'
6
+ require_relative "priority_heap"
7
7
 
8
8
  class IO
9
9
  module Event
@@ -5,6 +5,6 @@
5
5
 
6
6
  class IO
7
7
  module Event
8
- VERSION = "1.6.5"
8
+ VERSION = "1.6.7"
9
9
  end
10
10
  end
data/lib/io/event.rb CHANGED
@@ -3,13 +3,13 @@
3
3
  # Released under the MIT License.
4
4
  # Copyright, 2021-2024, by Samuel Williams.
5
5
 
6
- require_relative 'event/version'
7
- require_relative 'event/selector'
8
- require_relative 'event/timers'
6
+ require_relative "event/version"
7
+ require_relative "event/selector"
8
+ require_relative "event/timers"
9
9
 
10
10
  begin
11
- require 'IO_Event'
11
+ require "IO_Event"
12
12
  rescue LoadError => error
13
13
  warn "Could not load native event selector: #{error}"
14
- require_relative 'event/selector/nonblock'
14
+ require_relative "event/selector/nonblock"
15
15
  end
data/license.md CHANGED
@@ -8,6 +8,7 @@ Copyright, 2022, by Alex Matchneer.
8
8
  Copyright, 2022, by Bruno Sutic.
9
9
  Copyright, 2023, by Math Ieu.
10
10
  Copyright, 2024, by Pavel Rosický.
11
+ Copyright, 2024, by Anthony Ross.
11
12
 
12
13
  Permission is hereby granted, free of charge, to any person obtaining a copy
13
14
  of this software and associated documentation files (the "Software"), to deal
data/readme.md CHANGED
@@ -24,8 +24,8 @@ We welcome contributions to this project.
24
24
 
25
25
  ### Developer Certificate of Origin
26
26
 
27
- This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
27
+ In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
28
28
 
29
- ### Contributor Covenant
29
+ ### Community Guidelines
30
30
 
31
- This project is governed by the [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
31
+ This project is best served by a collaborative and respectful environment. Treat each other professionally, respect differing viewpoints, and engage constructively. Harassment, discrimination, or harmful behavior is not tolerated. Communicate clearly, listen actively, and support one another. If any issues arise, please inform the project maintainers.
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.6.5
4
+ version: 1.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -10,6 +10,7 @@ authors:
10
10
  - Benoit Daloze
11
11
  - Bruno Sutic
12
12
  - Alex Matchneer
13
+ - Anthony Ross
13
14
  - Delton Ding
14
15
  - Pavel Rosický
15
16
  autorequire:
@@ -44,7 +45,7 @@ cert_chain:
44
45
  Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
45
46
  voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
46
47
  -----END CERTIFICATE-----
47
- date: 2024-06-23 00:00:00.000000000 Z
48
+ date: 2024-10-03 00:00:00.000000000 Z
48
49
  dependencies: []
49
50
  description:
50
51
  email:
@@ -85,7 +86,9 @@ files:
85
86
  homepage: https://github.com/socketry/io-event
86
87
  licenses:
87
88
  - MIT
88
- metadata: {}
89
+ metadata:
90
+ documentation_uri: https://socketry.github.io/io-event/
91
+ source_code_uri: https://github.com/socketry/io-event.git
89
92
  post_install_message:
90
93
  rdoc_options: []
91
94
  require_paths:
@@ -101,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
104
  - !ruby/object:Gem::Version
102
105
  version: '0'
103
106
  requirements: []
104
- rubygems_version: 3.5.11
107
+ rubygems_version: 3.4.19
105
108
  signing_key:
106
109
  specification_version: 4
107
110
  summary: An event loop.
metadata.gz.sig CHANGED
Binary file