class Async::Scheduler

def io_wait(io, events, timeout = nil)

@parameter timeout [Float | Nil] The maximum time to wait, or if nil, indefinitely.
@parameter events [Integer] The events to wait for, e.g. `IO::READABLE`, `IO::WRITABLE`, etc.
@parameter io [IO] The IO object to wait on.

@asynchronous May be non-blocking.
@public Since *Async v2*.

Wait for the specified IO to become ready for the specified events.
def io_wait(io, events, timeout = nil)
	fiber = Fiber.current
	
	if timeout
		# If an explicit timeout is specified, we expect that the user will handle it themselves:
		timer = @timers.after(timeout) do
			fiber.transfer
		end
	elsif timeout = get_timeout(io)
		# Otherwise, if we default to the io's timeout, we raise an exception:
		timer = @timers.after(timeout) do
			fiber.raise(::IO::TimeoutError, "Timeout (#{timeout}s) while waiting for IO to become ready!")
		end
	end
	
	return @selector.io_wait(fiber, io, events)
ensure
	timer&.cancel!
end