Module: IO::Event::Selector
- Defined in:
- lib/io/event/selector.rb,
lib/io/event/selector/select.rb,
lib/io/event/selector/nonblock.rb,
ext/io/event/event.c
Defined Under Namespace
Classes: EPoll, KQueue, Select, URing
Class Method Summary collapse
-
.default(env = ENV) ⇒ Object
The default selector implementation, which is chosen based on the environment and available implementations.
-
.new(loop, env = ENV) ⇒ Object
Create a new selector instance, according to the best available implementation.
-
.nonblock(io) ⇒ Object
Execute the given block in non-blocking mode.
-
.process_wait(pid, flags) ⇒ Object
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).
Class Method Details
.default(env = ENV) ⇒ Object
The default selector implementation, which is chosen based on the environment and available implementations.
21 22 23 24 25 26 27 |
# File 'lib/io/event/selector.rb', line 21 def self.default(env = ENV) if name = env["IO_EVENT_SELECTOR"]&.to_sym return const_get(name) else BEST end end |
.new(loop, env = ENV) ⇒ Object
Create a new selector instance, according to the best available implementation.
34 35 36 37 38 39 40 41 42 |
# File 'lib/io/event/selector.rb', line 34 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 |
.nonblock(io) ⇒ Object
Execute the given block in non-blocking mode.
14 15 16 17 18 19 |
# File 'lib/io/event/selector/nonblock.rb', line 14 def self.nonblock(io, &block) io.nonblock(&block) rescue Errno::EBADF # Windows. yield end |
.process_wait(pid, flags) ⇒ Object
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.
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/io/event/selector.rb', line 51 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 |