io-event 1.2.3 → 1.3.0

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.
@@ -165,8 +165,8 @@ module IO::Event
165
165
  total = 0
166
166
 
167
167
  Selector.nonblock(io) do
168
- while true
169
- maximum_size = buffer.size - offset
168
+ maximum_size = buffer.size - offset
169
+ while maximum_size > 0
170
170
  result = Fiber.blocking{buffer.read(io, maximum_size, offset)}
171
171
 
172
172
  if again?(result)
@@ -182,6 +182,8 @@ module IO::Event
182
182
  offset += result
183
183
  break if total >= length
184
184
  end
185
+
186
+ maximum_size = buffer.size - offset
185
187
  end
186
188
  end
187
189
 
@@ -192,8 +194,8 @@ module IO::Event
192
194
  total = 0
193
195
 
194
196
  Selector.nonblock(io) do
195
- while true
196
- maximum_size = buffer.size - offset
197
+ maximum_size = buffer.size - offset
198
+ while maximum_size > 0
197
199
  result = Fiber.blocking{buffer.write(io, maximum_size, offset)}
198
200
 
199
201
  if again?(result)
@@ -209,6 +211,8 @@ module IO::Event
209
211
  offset += result
210
212
  break if total >= length
211
213
  end
214
+
215
+ maximum_size = buffer.size - offset
212
216
  end
213
217
  end
214
218
 
@@ -219,9 +223,8 @@ module IO::Event
219
223
  io = IO.for_fd(_io.fileno, autoclose: false)
220
224
  total = 0
221
225
 
222
- while true
223
- maximum_size = buffer.size - offset
224
-
226
+ maximum_size = buffer.size - offset
227
+ while maximum_size > 0
225
228
  case result = blocking{io.read_nonblock(maximum_size, exception: false)}
226
229
  when :wait_readable
227
230
  if length > 0
@@ -246,6 +249,8 @@ module IO::Event
246
249
  break if size >= length
247
250
  length -= size
248
251
  end
252
+
253
+ maximum_size = buffer.size - offset
249
254
  end
250
255
 
251
256
  return total
@@ -259,9 +264,8 @@ module IO::Event
259
264
  io = IO.for_fd(_io.fileno, autoclose: false)
260
265
  total = 0
261
266
 
262
- while true
263
- maximum_size = buffer.size - offset
264
-
267
+ maximum_size = buffer.size - offset
268
+ while maximum_size > 0
265
269
  chunk = buffer.get_string(offset, maximum_size)
266
270
  case result = blocking{io.write_nonblock(chunk, exception: false)}
267
271
  when :wait_readable
@@ -282,6 +286,8 @@ module IO::Event
282
286
  break if result >= length
283
287
  length -= result
284
288
  end
289
+
290
+ maximum_size = buffer.size - offset
285
291
  end
286
292
 
287
293
  return total
@@ -342,12 +348,26 @@ module IO::Event
342
348
  end
343
349
  end
344
350
 
345
- @blocked = true
346
351
  duration = 0 unless @ready.empty?
347
- readable, writable, priority = ::IO.select(readable, writable, priority, duration)
348
- @blocked = false
352
+ error = nil
353
+
354
+ # We need to handle interrupts on blocking IO. Every other implementation uses EINTR, but that doesn't work with `::IO.select` as it will retry the call on EINTR.
355
+ Thread.handle_interrupt(::Exception => :on_blocking) do
356
+ @blocked = true
357
+ readable, writable, priority = ::IO.select(readable, writable, priority, duration)
358
+ rescue ::Exception => error
359
+ # Requeue below...
360
+ ensure
361
+ @blocked = false
362
+ end
363
+
364
+ if error
365
+ # Requeue the error into the pending exception queue:
366
+ Thread.current.raise(error)
367
+ return 0
368
+ end
349
369
 
350
- ready = Hash.new(0)
370
+ ready = Hash.new(0).compare_by_identity
351
371
 
352
372
  readable&.each do |io|
353
373
  ready[io] |= IO::READABLE
@@ -11,11 +11,7 @@ module IO::Event
11
11
  module Selector
12
12
  def self.default(env = ENV)
13
13
  if name = env['IO_EVENT_SELECTOR']&.to_sym
14
- if const_defined?(name)
15
- return const_get(name)
16
- else
17
- warn "Could not find IO_EVENT_SELECTOR=#{name}!"
18
- end
14
+ return const_get(name)
19
15
  end
20
16
 
21
17
  if self.const_defined?(:URing)
@@ -5,6 +5,6 @@
5
5
 
6
6
  class IO
7
7
  module Event
8
- VERSION = "1.2.3"
8
+ VERSION = "1.3.0"
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.2.3
4
+ version: 1.3.0
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-07-26 00:00:00.000000000 Z
45
+ date: 2023-08-23 00:00:00.000000000 Z
46
46
  dependencies: []
47
47
  description:
48
48
  email:
@@ -57,10 +57,12 @@ files:
57
57
  - ext/io/event/event.h
58
58
  - ext/io/event/interrupt.c
59
59
  - ext/io/event/interrupt.h
60
+ - ext/io/event/selector/array.h
60
61
  - ext/io/event/selector/epoll.c
61
62
  - ext/io/event/selector/epoll.h
62
63
  - ext/io/event/selector/kqueue.c
63
64
  - ext/io/event/selector/kqueue.h
65
+ - ext/io/event/selector/list.h
64
66
  - ext/io/event/selector/pidfd.c
65
67
  - ext/io/event/selector/selector.c
66
68
  - ext/io/event/selector/selector.h
metadata.gz.sig CHANGED
Binary file