class Async::Wrapper

Represents an asynchronous IO within a reactor.

def close

Close the io and monitor.
def close
	if @monitor
		@monitor.close 
		@monitor = nil
	end
	
	@io.close
end

def initialize(io, reactor = nil)

Parameters:
  • bound (Boolean) -- whether the underlying socket will be closed if the wrapper is closed.
  • reactor (Reactor) -- the reactor that is managing this wrapper, or not specified, it's looked up by way of {Task.current}.
  • io () -- the native object to wrap.
def initialize(io, reactor = nil)
	@io = io
	
	@reactor = reactor
	@monitor = nil
end

def reactor= reactor

Binding to a reactor is purely a performance consideration. Generally, I don't like APIs that exist only due to optimisations. This is borderline, so consider this functionality semi-private.
Bind this wrapper to a different reactor. Assign nil to convert to an unbound wrapper (can be used from any reactor/task but with slightly increased overhead.)
def reactor= reactor
	if @monitor
		@monitor.close 
		@monitor = nil
	end
	
	@reactor = reactor
end

def wait_any(interests = :rw, duration = nil)

Parameters:
  • duration (Float) -- timeout after the given duration if not `nil`.
  • interests (:r | :w | :rw) -- what events to wait for.
def wait_any(interests = :rw, duration = nil)
	# There is value in caching this monitor - if you can reuse it, you will get about 2x the throughput, because you avoid calling Reactor#register and Monitor#close for every call. That being said, by caching it, you also introduce lifetime issues. I'm going to accept this overhead into the wrapper design because it's pretty convenient, but if you want faster IO, take a look at the performance spec which compares this method with a more direct alternative.
	if @reactor
		unless @monitor
			@monitor = @reactor.register(@io, interests)
		else
			@monitor.interests = interests
			@monitor.value = Fiber.current
		end
		
		begin
			wait_for(@reactor, @monitor, duration)
		ensure
			@monitor.interests = nil
		end
	else
		reactor = Task.current.reactor
		monitor = reactor.register(@io, interests)
		
		begin
			wait_for(reactor, monitor, duration)
		ensure
			monitor.close
		end
	end
end

def wait_for(reactor, monitor, duration)

def wait_for(reactor, monitor, duration)
	# If the user requested an explicit timeout for this operation:
	if duration
		reactor.timeout(duration) do
			Task.yield
		end
	else
		Task.yield
	end
	
	return true
end

def wait_readable(duration = nil)

Wait for the io to become readable.
def wait_readable(duration = nil)
	wait_any(:r, duration)
end

def wait_writable(duration = nil)

Wait for the io to become writable.
def wait_writable(duration = nil)
	wait_any(:w, duration)
end