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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/context/getting-started.md +31 -5
- data/ext/io/event/selector/epoll.c +71 -12
- data/ext/io/event/selector/kqueue.c +71 -8
- data/ext/io/event/selector/selector.h +4 -0
- data/ext/io/event/selector/uring.c +296 -53
- data/ext/io/event/worker_pool.c +45 -34
- data/lib/io/event/debug/selector.rb +6 -6
- data/lib/io/event/selector/select.rb +93 -59
- data/lib/io/event/version.rb +1 -1
- data/readme.md +8 -8
- data/releases.md +8 -0
- data.tar.gz.sig +0 -0
- metadata +1 -1
- metadata.gz.sig +0 -0
|
@@ -197,78 +197,112 @@ module IO::Event
|
|
|
197
197
|
errno == EAGAIN or errno == EWOULDBLOCK
|
|
198
198
|
end
|
|
199
199
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
|
|
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
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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
|
-
|
|
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.
|
data/lib/io/event/version.rb
CHANGED
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
metadata.gz.sig
CHANGED
|
Binary file
|