Feature #18411
Updated by ioquatix (Samuel Williams) almost 3 years ago
When implementing pure-ruby IO scheduler, we may need to invoke some Ruby IO operations without entering the scheduler.
```ruby
def io_write(fiber, io, buffer, length)
offset = 0
while length > 0
# From offset until the end:
chunk = buffer.to_str(offset, length)
case result = io.write_nonblock(chunk, exception: false)
when :wait_readable
self.io_wait(fiber, io, IO::READABLE)
when :wait_writable
self.io_wait(fiber, io, IO::WRITABLE)
else
offset += result
length -= result
end
end
return offset
end
```
There are some cases where even in this code `read_nonblock` can invoke fiber scheduler creating infinite recursion.
Therefore, I propose to introduce `Fiber.blocking{...}` which has almost identical implementation to `Fiber.new(blocking: true) {}.resume`.
In the above code, we change the line:
```
case result = io.write_nonblock(chunk, exception: false)
```
to
```
case result = Fiber.blocking{io.write_nonblock(chunk, exception: false)}
```
This ensures that `write_nonblock` can never enter the scheduler again.