Project

General

Profile

Actions

Feature #18411

open

Introduce `Fiber.blocking` for disabling scheduler.

Added by ioquatix (Samuel Williams) 5 months ago. Updated 5 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:106707]

Description

When implementing pure-ruby IO scheduler, we may need to invoke some Ruby IO operations without entering the scheduler.

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.

Updated by ioquatix (Samuel Williams) 5 months ago

@matz (Yukihiro Matsumoto) this isn't strictly necessary but makes pure Ruby implementation of IO read/write hooks more efficient. I'm not sure if there is valid case for general user code. Can we consider it for Ruby 3.1?

Actions #2

Updated by ioquatix (Samuel Williams) 5 months ago

  • Description updated (diff)
Actions #3

Updated by jeremyevans0 (Jeremy Evans) 5 months ago

  • Backport deleted (2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN)
  • Tracker changed from Bug to Feature
Actions

Also available in: Atom PDF