io-event 1.19.4 → 1.20.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.
@@ -197,78 +197,112 @@ module IO::Event
197
197
  errno == EAGAIN or errno == EWOULDBLOCK
198
198
  end
199
199
 
200
- # Read from the given IO to the buffer.
201
- #
202
- # @parameter length [Integer] The minimum number of bytes to read.
203
- # @parameter offset [Integer] The offset into the buffer to read to.
204
- def io_read(fiber, io, buffer, length, offset = 0)
205
- # Ensure offset is within the bounds of the buffer to avoid ArgumentError
206
- if offset > buffer.size
207
- return -Errno::EINVAL::Errno
208
- elsif offset == buffer.size
209
- return 0
200
+ if defined?(IO::Buffer::VERSION) && IO::Buffer::VERSION >= 3
201
+ # Read at most `length` bytes from the given IO to the buffer in one operation.
202
+ #
203
+ # @parameter offset [Integer] The offset into the buffer to read to.
204
+ # @parameter length [Integer] The maximum number of bytes to read.
205
+ def io_read(fiber, io, buffer, offset, length)
206
+ if offset > buffer.size || length > buffer.size - offset
207
+ return -Errno::EINVAL::Errno
208
+ elsif length == 0
209
+ return 0
210
+ end
211
+
212
+ Selector.nonblock(io) do
213
+ return Fiber.blocking{buffer.read(io, offset, length)}
214
+ end
210
215
  end
211
216
 
212
- total = 0
213
-
214
- Selector.nonblock(io) do
215
- while true
216
- result = Fiber.blocking{buffer.read(io, 0, offset)}
217
-
218
- if result < 0
219
- if length > 0 and again?(result)
220
- self.io_wait(fiber, io, IO::READABLE)
217
+ # Write at most `length` bytes to the given IO from the buffer in one operation.
218
+ #
219
+ # @parameter offset [Integer] The offset into the buffer to write from.
220
+ # @parameter length [Integer] The maximum number of bytes to write.
221
+ def io_write(fiber, io, buffer, offset, length)
222
+ if offset > buffer.size || length > buffer.size - offset
223
+ return -Errno::EINVAL::Errno
224
+ elsif length == 0
225
+ return 0
226
+ end
227
+
228
+ Selector.nonblock(io) do
229
+ return Fiber.blocking{buffer.write(io, offset, length)}
230
+ end
231
+ end
232
+ else
233
+ # Read from the given IO to the buffer.
234
+ #
235
+ # @parameter length [Integer] The minimum number of bytes to read.
236
+ # @parameter offset [Integer] The offset into the buffer to read to.
237
+ def io_read(fiber, io, buffer, length, offset = 0)
238
+ # Ensure offset is within the bounds of the buffer to avoid `ArgumentError`:
239
+ if offset > buffer.size
240
+ return -Errno::EINVAL::Errno
241
+ elsif offset == buffer.size
242
+ return 0
243
+ end
244
+
245
+ total = 0
246
+
247
+ Selector.nonblock(io) do
248
+ while true
249
+ result = Fiber.blocking{buffer.read(io, 0, offset)}
250
+
251
+ if result < 0
252
+ if length > 0 and again?(result)
253
+ self.io_wait(fiber, io, IO::READABLE)
254
+ else
255
+ return result
256
+ end
257
+ elsif result == 0
258
+ break
221
259
  else
222
- return result
260
+ total += result
261
+ break if total >= length
262
+ offset += result
223
263
  end
224
- elsif result == 0
225
- break
226
- else
227
- total += result
228
- break if total >= length
229
- offset += result
230
264
  end
231
265
  end
266
+
267
+ return total
232
268
  end
233
269
 
234
- return total
235
- end
236
-
237
- # Write to the given IO from the buffer.
238
- #
239
- # @parameter length [Integer] The minimum number of bytes to write.
240
- # @parameter offset [Integer] The offset into the buffer to write from.
241
- def io_write(fiber, io, buffer, length, offset = 0)
242
- # Ensure offset is within the bounds of the buffer to avoid ArgumentError
243
- if offset > buffer.size
244
- return -Errno::EINVAL::Errno
245
- elsif offset == buffer.size
246
- return 0
247
- end
248
-
249
- total = 0
250
-
251
- Selector.nonblock(io) do
252
- while true
253
- result = Fiber.blocking{buffer.write(io, 0, offset)}
254
-
255
- if result < 0
256
- if length > 0 and again?(result)
257
- self.io_wait(fiber, io, IO::WRITABLE)
270
+ # Write to the given IO from the buffer.
271
+ #
272
+ # @parameter length [Integer] The minimum number of bytes to write.
273
+ # @parameter offset [Integer] The offset into the buffer to write from.
274
+ def io_write(fiber, io, buffer, length, offset = 0)
275
+ # Ensure offset is within the bounds of the buffer to avoid `ArgumentError`:
276
+ if offset > buffer.size
277
+ return -Errno::EINVAL::Errno
278
+ elsif offset == buffer.size
279
+ return 0
280
+ end
281
+
282
+ total = 0
283
+
284
+ Selector.nonblock(io) do
285
+ while true
286
+ result = Fiber.blocking{buffer.write(io, 0, offset)}
287
+
288
+ if result < 0
289
+ if length > 0 and again?(result)
290
+ self.io_wait(fiber, io, IO::WRITABLE)
291
+ else
292
+ return result
293
+ end
294
+ elsif result == 0
295
+ break result
258
296
  else
259
- return result
297
+ total += result
298
+ break if total >= length
299
+ offset += result
260
300
  end
261
- elsif result == 0
262
- break result
263
- else
264
- total += result
265
- break if total >= length
266
- offset += result
267
301
  end
268
302
  end
303
+
304
+ return total
269
305
  end
270
-
271
- return total
272
306
  end
273
307
 
274
308
  # Wait for a process to change state.
@@ -7,6 +7,6 @@
7
7
  class IO
8
8
  # @namespace
9
9
  module Event
10
- VERSION = "1.19.4"
10
+ VERSION = "1.20.0"
11
11
  end
12
12
  end
data/readme.md CHANGED
@@ -18,6 +18,14 @@ Please see the [project documentation](https://socketry.github.io/io-event/) for
18
18
 
19
19
  Please see the [project releases](https://socketry.github.io/io-event/releases/index) for all releases.
20
20
 
21
+ ### v1.20.0
22
+
23
+ - Add compatibility with Ruby 4.1's fiber scheduler interface version 4. Buffered IO operations now use `(offset, length)`, perform a single transfer of at most `length` bytes, return short transfers directly, and report `-EAGAIN` without waiting. Earlier Ruby versions retain the existing minimum-progress behavior.
24
+
25
+ ### v1.19.5
26
+
27
+ - Preserve the original exception or non-local control flow when `IO::Event::WorkerPool` cancellation interrupts a blocked fiber, while still cancelling and draining the in-flight blocking operation before returning control to Ruby.
28
+
21
29
  ### v1.19.4
22
30
 
23
31
  - Capture `errno` immediately after `epoll_wait` / `kevent`, preventing stale or subsequently clobbered values from raising a spurious `Errno::*` when a native selector wait is interrupted or skipped.
@@ -51,14 +59,6 @@ Please see the [project releases](https://socketry.github.io/io-event/releases/i
51
59
 
52
60
  - Correctly implement `Interrupt#signal` so that it is robust enough to be called by `Scheduler#unblock`.
53
61
 
54
- ### v1.16.3
55
-
56
- - Handle `IOError` raised while shutting down the pure Ruby interrupt pipe, so `IO::Event::Interrupt#close` does not leak expected shutdown errors from the interrupt fiber.
57
-
58
- ### v1.16.2
59
-
60
- - Improve timer heap performance by batching scheduled timer insertion, compacting cancelled timers during flush, and avoiding unnecessary heap rebuilds for small incremental inserts.
61
-
62
62
  ## Contributing
63
63
 
64
64
  We welcome contributions to this project.
data/releases.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Releases
2
2
 
3
+ ## v1.20.0
4
+
5
+ - Add compatibility with Ruby 4.1's fiber scheduler interface version 4. Buffered IO operations now use `(offset, length)`, perform a single transfer of at most `length` bytes, return short transfers directly, and report `-EAGAIN` without waiting. Earlier Ruby versions retain the existing minimum-progress behavior.
6
+
7
+ ## v1.19.5
8
+
9
+ - Preserve the original exception or non-local control flow when `IO::Event::WorkerPool` cancellation interrupts a blocked fiber, while still cancelling and draining the in-flight blocking operation before returning control to Ruby.
10
+
3
11
  ## v1.19.4
4
12
 
5
13
  - Capture `errno` immediately after `epoll_wait` / `kevent`, preventing stale or subsequently clobbered values from raising a spurious `Errno::*` when a native selector wait is interrupted or skipped.
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.19.4
4
+ version: 1.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
metadata.gz.sig CHANGED
Binary file