event 0.2.3 → 0.4.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: 9a363339a1d384ea4d844450be2ff46cbc091bc0aca240e869491bf6a5d61300
4
- data.tar.gz: b1b3c431481f4499bf6605010392283acfb6f54a59aed232f25217d2cce4a221
3
+ metadata.gz: db1ee17a5921d3aa6c3ff4314099a1879d4c7ff76f43c3001f6f7872501d1f4c
4
+ data.tar.gz: 3fda0f1769bfc7b489425b9b432d6225772011c8bbaaa34f0dfd5193c8ed940a
5
5
  SHA512:
6
- metadata.gz: 3321631a8be1353038cdc9c63a2b6b17f02ea66924b11f5fb9126f9db1072ea4ee59141858f26e8879e1b52fe265471a2552afcab56cddd84b1e28d1611235d9
7
- data.tar.gz: 7196977bd770153c5be35d16701e32a635c84cf53edf2880b4c5f095b8644825c7dcd1254a4da8f72655fb48e3ac3ec529d2ae2496691fb9ead30bb595cae357
6
+ metadata.gz: 768501ac864f0436b95050721b14cbf4ce0ba6a3b79d2f0d8e244523477f55fd71f82ae3e7ab088c94aa40a6d0200acc4138caff472c95426a01fa784a50911c
7
+ data.tar.gz: f876ffe91ed99aa0e013ddaed5e2c4e6a72724891cc3bdceae9cb3bb1b30909716c92b8d551d23a171870b2e548dec32455de028bf5ea60964969d4aed919a9a
data/ext/event/Makefile CHANGED
@@ -139,8 +139,8 @@ target_prefix = /event
139
139
  LOCAL_LIBS =
140
140
  LIBS =
141
141
  ORIG_SRCS = event.c
142
- SRCS = $(ORIG_SRCS) event.c kqueue.c
143
- OBJS = event.o kqueue.o
142
+ SRCS = $(ORIG_SRCS) event.c backend.c kqueue.c
143
+ OBJS = event.o backend.o kqueue.o
144
144
  HDRS = $(srcdir)/event.h $(srcdir)/extconf.h
145
145
  LOCAL_HDRS =
146
146
  TARGET = event
Binary file
@@ -0,0 +1,39 @@
1
+ // Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ //
3
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ // of this software and associated documentation files (the "Software"), to deal
5
+ // in the Software without restriction, including without limitation the rights
6
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ // copies of the Software, and to permit persons to whom the Software is
8
+ // furnished to do so, subject to the following conditions:
9
+ //
10
+ // The above copyright notice and this permission notice shall be included in
11
+ // all copies or substantial portions of the Software.
12
+ //
13
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ // THE SOFTWARE.
20
+
21
+ #include "backend.h"
22
+
23
+ static ID id_transfer, id_alive_p;
24
+
25
+ void Init_Event_Backend(VALUE Event_Backend) {
26
+ id_transfer = rb_intern("transfer");
27
+ id_alive_p = rb_intern("alive?");
28
+ }
29
+
30
+ VALUE
31
+ Event_Backend_resume_safe(VALUE fiber, VALUE result) {
32
+ VALUE alive = rb_funcall(fiber, id_alive_p, 0);
33
+
34
+ if (RTEST(alive)) {
35
+ return rb_funcall(fiber, id_transfer, 1, result);
36
+ } else {
37
+ return Qnil;
38
+ }
39
+ }
@@ -18,6 +18,9 @@
18
18
  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
19
  // THE SOFTWARE.
20
20
 
21
+ #include <ruby.h>
22
+ #include <ruby/thread.h>
23
+
21
24
  enum Event {
22
25
  READABLE = 1,
23
26
  PRIORITY = 2,
@@ -26,4 +29,8 @@ enum Event {
26
29
  HANGUP = 16
27
30
  };
28
31
 
29
- #include <ruby/thread.h>
32
+ void
33
+ Init_Event_Backend();
34
+
35
+ VALUE
36
+ Event_Backend_resume_safe(VALUE fiber, VALUE argument);
@@ -41,13 +41,19 @@ void Event_Backend_EPoll_Type_mark(void *_data)
41
41
  rb_gc_mark(data->loop);
42
42
  }
43
43
 
44
+ static
45
+ void close_internal(struct Event_Backend_EPoll *data) {
46
+ if (data->descriptor >= 0) {
47
+ close(data->descriptor);
48
+ data->descriptor = -1;
49
+ }
50
+ }
51
+
44
52
  void Event_Backend_EPoll_Type_free(void *_data)
45
53
  {
46
54
  struct Event_Backend_EPoll *data = _data;
47
55
 
48
- if (data->descriptor >= 0) {
49
- close(data->descriptor);
50
- }
56
+ close_internal(data);
51
57
 
52
58
  free(data);
53
59
  }
@@ -96,6 +102,15 @@ VALUE Event_Backend_EPoll_initialize(VALUE self, VALUE loop) {
96
102
  return self;
97
103
  }
98
104
 
105
+ VALUE Event_Backend_EPoll_close(VALUE self) {
106
+ struct Event_Backend_EPoll *data = NULL;
107
+ TypedData_Get_Struct(self, struct Event_Backend_EPoll, &Event_Backend_EPoll_Type, data);
108
+
109
+ close_internal(data);
110
+
111
+ return Qnil;
112
+ }
113
+
99
114
  static inline
100
115
  uint32_t epoll_flags_from_events(int events) {
101
116
  uint32_t flags = 0;
@@ -257,13 +272,13 @@ VALUE Event_Backend_EPoll_select(VALUE self, VALUE duration) {
257
272
  .timeout = 0
258
273
  };
259
274
 
260
- select_internal_without_gvl(&arguments);
275
+ select_internal_with_gvl(&arguments);
261
276
 
262
277
  if (arguments.count == 0) {
263
278
  arguments.timeout = make_timeout(duration);
264
279
 
265
280
  if (arguments.timeout != 0) {
266
- select_internal_with_gvl(&arguments);
281
+ select_internal_without_gvl(&arguments);
267
282
  }
268
283
  }
269
284
 
@@ -273,7 +288,7 @@ VALUE Event_Backend_EPoll_select(VALUE self, VALUE duration) {
273
288
 
274
289
  // fprintf(stderr, "-> fiber=%p descriptor=%d\n", (void*)fiber, events[i].data.fd);
275
290
 
276
- rb_funcall(fiber, id_transfer, 1, result);
291
+ Event_Backend_resume_safe(fiber, result);
277
292
  }
278
293
 
279
294
  return INT2NUM(arguments.count);
@@ -287,6 +302,7 @@ void Init_Event_Backend_EPoll(VALUE Event_Backend) {
287
302
 
288
303
  rb_define_alloc_func(Event_Backend_EPoll, Event_Backend_EPoll_allocate);
289
304
  rb_define_method(Event_Backend_EPoll, "initialize", Event_Backend_EPoll_initialize, 1);
305
+ rb_define_method(Event_Backend_EPoll, "close", Event_Backend_EPoll_close, 0);
290
306
 
291
307
  rb_define_method(Event_Backend_EPoll, "io_wait", Event_Backend_EPoll_io_wait, 3);
292
308
  rb_define_method(Event_Backend_EPoll, "select", Event_Backend_EPoll_select, 1);
@@ -41,13 +41,19 @@ void Event_Backend_KQueue_Type_mark(void *_data)
41
41
  rb_gc_mark(data->loop);
42
42
  }
43
43
 
44
+ static
45
+ void close_internal(struct Event_Backend_KQueue *data) {
46
+ if (data->descriptor >= 0) {
47
+ close(data->descriptor);
48
+ data->descriptor = -1;
49
+ }
50
+ }
51
+
44
52
  void Event_Backend_KQueue_Type_free(void *_data)
45
53
  {
46
54
  struct Event_Backend_KQueue *data = _data;
47
55
 
48
- if (data->descriptor >= 0) {
49
- close(data->descriptor);
50
- }
56
+ close_internal(data);
51
57
 
52
58
  free(data);
53
59
  }
@@ -97,6 +103,15 @@ VALUE Event_Backend_KQueue_initialize(VALUE self, VALUE loop) {
97
103
  return self;
98
104
  }
99
105
 
106
+ VALUE Event_Backend_KQueue_close(VALUE self) {
107
+ struct Event_Backend_KQueue *data = NULL;
108
+ TypedData_Get_Struct(self, struct Event_Backend_KQueue, &Event_Backend_KQueue_Type, data);
109
+
110
+ close_internal(data);
111
+
112
+ return Qnil;
113
+ }
114
+
100
115
  static
101
116
  int io_add_filters(int descriptor, int ident, int events, VALUE fiber) {
102
117
  int count = 0;
@@ -310,7 +325,8 @@ VALUE Event_Backend_KQueue_select(VALUE self, VALUE duration) {
310
325
  for (int i = 0; i < arguments.count; i += 1) {
311
326
  VALUE fiber = (VALUE)arguments.events[i].udata;
312
327
  VALUE result = INT2NUM(arguments.events[i].filter);
313
- rb_funcall(fiber, id_transfer, 1, result);
328
+
329
+ Event_Backend_resume_safe(fiber, result);
314
330
  }
315
331
 
316
332
  return INT2NUM(arguments.count);
@@ -324,6 +340,7 @@ void Init_Event_Backend_KQueue(VALUE Event_Backend) {
324
340
 
325
341
  rb_define_alloc_func(Event_Backend_KQueue, Event_Backend_KQueue_allocate);
326
342
  rb_define_method(Event_Backend_KQueue, "initialize", Event_Backend_KQueue_initialize, 1);
343
+ rb_define_method(Event_Backend_KQueue, "close", Event_Backend_KQueue_close, 0);
327
344
 
328
345
  rb_define_method(Event_Backend_KQueue, "io_wait", Event_Backend_KQueue_io_wait, 3);
329
346
  rb_define_method(Event_Backend_KQueue, "select", Event_Backend_KQueue_select, 1);
@@ -28,8 +28,8 @@
28
28
  static VALUE Event_Backend_URing = Qnil;
29
29
  static ID id_fileno, id_transfer;
30
30
 
31
- enum {URING_ENTRIES = 64};
32
- enum {URING_MAX_EVENTS = 64};
31
+ enum {URING_ENTRIES = 128};
32
+ enum {URING_MAX_EVENTS = 128};
33
33
 
34
34
  struct Event_Backend_URing {
35
35
  VALUE loop;
@@ -42,14 +42,19 @@ void Event_Backend_URing_Type_mark(void *_data)
42
42
  rb_gc_mark(data->loop);
43
43
  }
44
44
 
45
- void Event_Backend_URing_Type_free(void *_data)
46
- {
47
- struct Event_Backend_URing *data = _data;
48
-
45
+ static
46
+ void close_internal(struct Event_Backend_URing *data) {
49
47
  if (data->ring.ring_fd >= 0) {
50
48
  io_uring_queue_exit(&data->ring);
51
49
  data->ring.ring_fd = -1;
52
50
  }
51
+ }
52
+
53
+ void Event_Backend_URing_Type_free(void *_data)
54
+ {
55
+ struct Event_Backend_URing *data = _data;
56
+
57
+ close_internal(data);
53
58
 
54
59
  free(data);
55
60
  }
@@ -97,6 +102,15 @@ VALUE Event_Backend_URing_initialize(VALUE self, VALUE loop) {
97
102
  return self;
98
103
  }
99
104
 
105
+ VALUE Event_Backend_URing_close(VALUE self) {
106
+ struct Event_Backend_URing *data = NULL;
107
+ TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
108
+
109
+ close_internal(data);
110
+
111
+ return Qnil;
112
+ }
113
+
100
114
  static inline
101
115
  short poll_flags_from_events(int events) {
102
116
  short flags = 0;
@@ -128,12 +142,22 @@ struct io_wait_arguments {
128
142
  short flags;
129
143
  };
130
144
 
145
+ struct io_uring_sqe * io_get_sqe(struct Event_Backend_URing *data) {
146
+ struct io_uring_sqe *sqe = io_uring_get_sqe(&data->ring);
147
+
148
+ while (sqe == NULL) {
149
+ sqe = io_uring_get_sqe(&data->ring);
150
+ }
151
+
152
+ return sqe;
153
+ }
154
+
131
155
  static
132
156
  VALUE io_wait_rescue(VALUE _arguments, VALUE exception) {
133
157
  struct io_wait_arguments *arguments = (struct io_wait_arguments *)_arguments;
134
158
  struct Event_Backend_URing *data = arguments->data;
135
159
 
136
- struct io_uring_sqe *sqe = Event_Backend_URing_io_uring_get_sqe(data);
160
+ struct io_uring_sqe *sqe = io_get_sqe(data);
137
161
 
138
162
  // fprintf(stderr, "poll_remove(%p, %p)\n", sqe, (void*)arguments->fiber);
139
163
 
@@ -157,25 +181,14 @@ VALUE io_wait_transfer(VALUE _arguments) {
157
181
  return INT2NUM(events_from_poll_flags(flags));
158
182
  };
159
183
 
160
- struct io_uring_sqe *Event_Backend_URing_io_uring_get_sqe(struct Event_Backend_URing *data) {
161
- struct io_uring_sqe *sqe = NULL;
162
-
163
- while (true) {
164
- sqe = io_uring_get_sqe(&data->ring);
165
- if (sqe != NULL) {
166
- return sqe;
167
- }
168
- // The sqe is full, we need to poll before submitting more events.
169
- Event_Backend_URing_select(self, INT2NUM(0));
170
- }
171
- }
172
-
173
184
  VALUE Event_Backend_URing_io_wait(VALUE self, VALUE fiber, VALUE io, VALUE events) {
174
185
  struct Event_Backend_URing *data = NULL;
175
186
  TypedData_Get_Struct(self, struct Event_Backend_URing, &Event_Backend_URing_Type, data);
176
187
 
177
188
  int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
178
- struct io_uring_sqe *sqe = Event_Backend_URing_io_uring_get_sqe(data);
189
+ struct io_uring_sqe *sqe = io_get_sqe(data);
190
+
191
+ if (!sqe) return INT2NUM(0);
179
192
 
180
193
  short flags = poll_flags_from_events(NUM2INT(events));
181
194
 
@@ -224,7 +237,7 @@ VALUE Event_Backend_URing_io_read(VALUE self, VALUE fiber, VALUE io, VALUE buffe
224
237
  resize_to_capacity(buffer, NUM2SIZET(offset), NUM2SIZET(length));
225
238
 
226
239
  int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
227
- struct io_uring_sqe *sqe = Event_Backend_URing_io_uring_get_sqe(data);
240
+ struct io_uring_sqe *sqe = io_get_sqe(data);
228
241
 
229
242
  struct iovec iovecs[1];
230
243
  iovecs[0].iov_base = RSTRING_PTR(buffer) + NUM2SIZET(offset);
@@ -256,7 +269,7 @@ VALUE Event_Backend_URing_io_write(VALUE self, VALUE fiber, VALUE io, VALUE buff
256
269
  }
257
270
 
258
271
  int descriptor = NUM2INT(rb_funcall(io, id_fileno, 0));
259
- struct io_uring_sqe *sqe = Event_Backend_URing_io_uring_get_sqe(data);
272
+ struct io_uring_sqe *sqe = io_get_sqe(data);
260
273
 
261
274
  struct iovec iovecs[1];
262
275
  iovecs[0].iov_base = RSTRING_PTR(buffer) + NUM2SIZET(offset);
@@ -384,7 +397,7 @@ VALUE Event_Backend_URing_select(VALUE self, VALUE duration) {
384
397
 
385
398
  io_uring_cqe_seen(&data->ring, cqes[i]);
386
399
 
387
- rb_funcall(fiber, id_transfer, 1, result);
400
+ Event_Backend_resume_safe(fiber, result);
388
401
  }
389
402
 
390
403
  return INT2NUM(result);
@@ -398,6 +411,7 @@ void Init_Event_Backend_URing(VALUE Event_Backend) {
398
411
 
399
412
  rb_define_alloc_func(Event_Backend_URing, Event_Backend_URing_allocate);
400
413
  rb_define_method(Event_Backend_URing, "initialize", Event_Backend_URing_initialize, 1);
414
+ rb_define_method(Event_Backend_URing, "close", Event_Backend_URing_close, 0);
401
415
 
402
416
  rb_define_method(Event_Backend_URing, "io_wait", Event_Backend_URing_io_wait, 3);
403
417
  rb_define_method(Event_Backend_URing, "select", Event_Backend_URing_select, 1);
Binary file
data/ext/event/event.c CHANGED
@@ -19,6 +19,7 @@
19
19
  // THE SOFTWARE.
20
20
 
21
21
  #include "event.h"
22
+ #include "backend/backend.h"
22
23
 
23
24
  VALUE Event = Qnil;
24
25
  VALUE Event_Backend = Qnil;
@@ -32,6 +33,8 @@ void Init_event()
32
33
  Event = rb_define_module("Event");
33
34
  Event_Backend = rb_define_module_under(Event, "Backend");
34
35
 
36
+ Init_Event_Backend(Event_Backend);
37
+
35
38
  #ifdef EVENT_BACKEND_URING
36
39
  Init_Event_Backend_URing(Event_Backend);
37
40
  #endif
data/ext/event/event.o CHANGED
Binary file
data/ext/event/extconf.rb CHANGED
@@ -30,7 +30,7 @@ dir_config(extension_name)
30
30
 
31
31
  $CFLAGS << " -Wall"
32
32
 
33
- $srcs = ["event.c"]
33
+ $srcs = ["event.c", "backend/backend.c"]
34
34
  $VPATH << "$(srcdir)/backend"
35
35
 
36
36
  if have_library('uring') and have_header('liburing.h')
data/ext/event/kqueue.o CHANGED
Binary file
data/lib/event.rb CHANGED
@@ -19,7 +19,7 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  require_relative 'event/version'
22
- require_relative 'event/backend/select'
22
+ require_relative 'event/backend'
23
23
 
24
24
  module Event
25
25
  # These constants are the same as those defined in IO.
@@ -0,0 +1,49 @@
1
+ # Copyright, 2021, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'backend/select'
22
+
23
+ module Event
24
+ module Backend
25
+ def self.default(env = ENV)
26
+ if backend = env['EVENT_BACKEND']&.to_sym
27
+ if Event::Backend.const_defined?(backend)
28
+ return Event::Backend.const_get(backend)
29
+ else
30
+ warn "Could not find EVENT_BACKEND=#{backend}!"
31
+ end
32
+ end
33
+
34
+ if self.const_defined?(:URing)
35
+ return Event::Backend::URing
36
+ elsif self.const_defined?(:KQueue)
37
+ return Event::Backend::KQueue
38
+ elsif self.const_defined?(:EPoll)
39
+ return Event::Backend::EPoll
40
+ else
41
+ return Event::Backend::Select
42
+ end
43
+ end
44
+
45
+ def self.new(...)
46
+ default.new(...)
47
+ end
48
+ end
49
+ end
@@ -28,6 +28,12 @@ module Event
28
28
  @writable = {}
29
29
  end
30
30
 
31
+ def close
32
+ @loop = nil
33
+ @readable = nil
34
+ @writable = nil
35
+ end
36
+
31
37
  def io_wait(fiber, io, events)
32
38
  remove_readable = remove_writable = false
33
39
 
@@ -42,7 +48,6 @@ module Event
42
48
  end
43
49
 
44
50
  @loop.transfer
45
-
46
51
  ensure
47
52
  @readable.delete(io) if remove_readable
48
53
  @writable.delete(io) if remove_writable
@@ -64,7 +69,7 @@ module Event
64
69
  end
65
70
 
66
71
  ready.each do |fiber, events|
67
- fiber.transfer(events)
72
+ fiber.transfer(events) if fiber.alive?
68
73
  end
69
74
  end
70
75
  end
@@ -31,6 +31,15 @@ module Event
31
31
  @priority = {}
32
32
  end
33
33
 
34
+ def close
35
+ if @selector.nil?
36
+ raise "Selector already closed!"
37
+ end
38
+
39
+ @selector.close
40
+ @selector = nil
41
+ end
42
+
34
43
  def io_wait(fiber, io, events)
35
44
  register_readable(fiber, io, events)
36
45
  end
data/lib/event/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Event
2
- VERSION = "0.2.3"
2
+ VERSION = "0.4.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: event
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.4.3
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-05-03 00:00:00.000000000 Z
11
+ date: 2021-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bake
@@ -74,6 +74,8 @@ extensions:
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - ext/event/Makefile
77
+ - ext/event/backend.o
78
+ - ext/event/backend/backend.c
77
79
  - ext/event/backend/backend.h
78
80
  - ext/event/backend/epoll.c
79
81
  - ext/event/backend/epoll.h
@@ -90,6 +92,7 @@ files:
90
92
  - ext/event/kqueue.o
91
93
  - ext/event/mkmf.log
92
94
  - lib/event.rb
95
+ - lib/event/backend.rb
93
96
  - lib/event/backend/select.rb
94
97
  - lib/event/debug/selector.rb
95
98
  - lib/event/selector.rb
@@ -113,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
116
  - !ruby/object:Gem::Version
114
117
  version: '0'
115
118
  requirements: []
116
- rubygems_version: 3.2.15
119
+ rubygems_version: 3.2.3
117
120
  signing_key:
118
121
  specification_version: 4
119
122
  summary: An event loop.