class Async::IO::Generic

Represents an asynchronous IO within a reactor.

def async

def async
	while true
		result = yield
		
		case result
		when :wait_readable
			wait_readable
		when :wait_writable
			wait_writable
		else
			return result
		end
	end
end

def async

def async
	while true
		begin
			return yield
		rescue ::IO::WaitReadable, ::IO::EAGAINWaitReadable
			wait_readable
		rescue ::IO::WaitWritable, ::IO::EAGAINWaitWritable
			wait_writable
		end
	end
end

def async

def async
	while true
		begin
			return yield
		rescue ::IO::WaitReadable
			wait_readable
		rescue ::IO::WaitWritable
			wait_writable
		end
	end
end

def async_send(*args)

def async_send(*args)
	async do
		@io.__send__(*args, exception: false)
	end
end

def async_send(*args)

def async_send(*args)
	async do
		@io.__send__(*args)
	end
end

def async_send(*args)

def async_send(*args)
	async do
		@io.__send__(*args)
	end
end

def wrap(*args)

Instantiate a wrapped instance of the class, and optionally yield it to a given block, closing it afterwards.
def wrap(*args)
	wrapper = self.new(@wrapped_klass.new(*args))
	
	if block_given?
		begin
			yield wrapper
		ensure
			wrapper.close
		end
	else
		return wrapper
	end
end

def wrap_blocking_method(new_name, method_name, invert: true)

Invokes `$2` on the underlying {io}. If the operation would block, the current task is paused until the operation can succeed, at which point it's resumed and the operation is completed.
@method $1
@!macro [attach] wrap_blocking_method
def wrap_blocking_method(new_name, method_name, invert: true)
	define_method(new_name) do |*args|
		async_send(method_name, *args)
	end
	
	if invert
		# We define the original _nonblock method to call the async variant. We ignore options.
		# define_method(method_name) do |*args, **options|
		# 	self.__send__(new_name, *args)
		# end
		def_delegators :@io, method_name
	end
end

def wraps(klass, *additional_methods)

def wraps(klass, *additional_methods)
	@wrapped_klass = klass
	WRAPPERS[klass] = self
	
	# These are methods implemented by the wrapped class, that we aren't overriding, that may be of interest:
	# fallback_methods = klass.instance_methods(false) - instance_methods
	# puts "Forwarding #{klass} methods #{fallback_methods} to @io"
	
	def_delegators :@io, *additional_methods
end