module Selector
Nested
Definitions
def self.nonblock(io, &block)
Execute the given block in non-blocking mode.
Signature
-
parameter
ioIO The IO object to operate on.
-
yields
{...} The block to execute.
Implementation
def self.nonblock(io, &block)
io.nonblock(&block)
rescue Errno::EBADF
# Windows.
yield
end
def self.default(env = ENV)
The default selector implementation, which is chosen based on the environment and available implementations.
Signature
-
parameter
envHash The environment to read configuration from.
-
returns
Class The default selector implementation.
Implementation
def self.default(env = ENV)
if name = env["IO_EVENT_SELECTOR"]&.to_sym
return const_get(name)
else
BEST
end
end
def self.new(loop, env = ENV)
Create a new selector instance, according to the best available implementation.
Signature
-
parameter
loopFiber The event loop fiber.
-
parameter
envHash The environment to read configuration from.
-
returns
Selector The new selector instance.
Implementation
def self.new(loop, env = ENV)
selector = default(env).new(loop)
if debug = env["IO_EVENT_DEBUG_SELECTOR"]
selector = Debug::Selector.wrap(selector, env)
end
return selector
end
def self.process_wait(pid, flags)
Wait for a process to change state, for the cases a selector cannot represent natively (e.g. pid <= 0: any child, or a process group). The native selectors integrate process waiting with the event loop using per-process primitives (pidfd_open, EVFILT_PROC) which can only refer to a single, specific process, and delegate here otherwise.
The wait is performed on a separate thread, which has no fiber scheduler and therefore blocks. Joining it via Thread#value is fiber-scheduler aware, so the calling fiber yields to the event loop and the reactor keeps running other fibers.
Signature
-
parameter
pidInteger The process ID (or process group) to wait for.
-
parameter
flagsInteger Flags to pass to
Process::Status.wait.-
returns
Process::Status The status of the waited process.
Implementation
def self.process_wait(pid, flags)
thread = ::Thread.new do
::Process::Status.wait(pid, flags)
end
thread.value
ensure
# If the calling fiber was interrupted before the wait completed, don't leave the thread running:
thread&.kill
end