class Async::IO::Generic

Represents an asynchronous IO within a reactor.

Constants

WRAPPERS

Attributes

wrapped_klass[R]
timeout[RW]

Public Class Methods

wrap(*args) { |wrapper| ... } click to toggle source

Instantiate a wrapped instance of the class, and optionally yield it to a given block, closing it afterwards.

# File lib/async/io/generic.rb, line 88
def wrap(*args)
        wrapper = self.new(@wrapped_klass.new(*args))
        
        return wrapper unless block_given?
        
        begin
                yield wrapper
        ensure
                wrapper.close
        end
end
wrap_blocking_method(new_name, method_name, invert: true, &block) click to toggle source

@!macro [attach] wrap_blocking_method

@method $1
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.
# File lib/async/io/generic.rb, line 57
def wrap_blocking_method(new_name, method_name, invert: true, &block)
        if block_given?
                define_method(new_name, &block)
        else
                define_method(new_name) do |*args|
                        async_send(method_name, *args)
                end
        end
        
        if invert
                # We wrap the original _nonblock method, ignoring options.
                define_method(method_name) do |*args, exception: false|
                        async_send(method_name, *args)
                end
        end
end
wraps(klass, *additional_methods) click to toggle source
# File lib/async/io/generic.rb, line 76
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

Public Instance Methods

<<(buffer) click to toggle source
# File lib/async/io/generic.rb, line 170
def << buffer
        write(buffer)
        return self
end
connected?() click to toggle source
# File lib/async/io/generic.rb, line 206
def connected?
        !@io.closed?
end
dup() click to toggle source
Calls superclass method
# File lib/async/io/generic.rb, line 175
def dup
        super.tap do |copy|
                copy.timeout = self.timeout
        end
end
nonblock() click to toggle source
# File lib/async/io/generic.rb, line 194
def nonblock
        true
end
nonblock=(value) click to toggle source
# File lib/async/io/generic.rb, line 198
def nonblock= value
        true
end
nonblock?() click to toggle source
# File lib/async/io/generic.rb, line 202
def nonblock?
        true
end
read(length = nil, buffer = nil) click to toggle source

Read `length` bytes of data from the underlying I/O. If length is unspecified, read everything.

# File lib/async/io/generic.rb, line 111
def read(length = nil, buffer = nil)
        if buffer
                buffer.clear
        else
                buffer = String.new
        end
        
        if length
                return String.new(encoding: Encoding::BINARY) if length <= 0
                
                # Fast path:
                if buffer = self.sysread(length, buffer)
                        
                        # Slow path:
                        while buffer.bytesize < length
                                # Slow path:
                                if chunk = self.sysread(length - buffer.bytesize)
                                        buffer << chunk
                                else
                                        break
                                end
                        end
                        
                        return buffer
                else
                        return nil
                end
        else
                buffer = self.sysread(BLOCK_SIZE, buffer)
                
                while chunk = self.sysread(BLOCK_SIZE)
                        buffer << chunk
                end
                
                return buffer
        end
end
wait(timeout = self.timeout, mode = :read) click to toggle source
# File lib/async/io/generic.rb, line 181
def wait(timeout = self.timeout, mode = :read)
        case mode
        when :read
                wait_readable(timeout)
        when :write
                wait_writable(timeout)
        else
                wait_any(:rw, timeout)
        end
rescue TimeoutError
        return nil
end
write(buffer) click to toggle source
# File lib/async/io/generic.rb, line 154
def write(buffer)
        # Fast path:
        written = self.syswrite(buffer)
        remaining = buffer.bytesize - written
        
        while remaining > 0
                # Slow path:
                length = self.syswrite(buffer.byteslice(written, remaining))
                
                remaining -= length
                written += length
        end
        
        return written
end

Protected Instance Methods

async_send(*arguments, timeout: self.timeout) click to toggle source
# File lib/async/io/generic.rb, line 214
def async_send(*arguments, timeout: self.timeout)
        while true
                result = @io.__send__(*arguments, exception: false)
                
                case result
                when :wait_readable
                        wait_readable(timeout)
                when :wait_writable
                        wait_writable(timeout)
                else
                        return result
                end
        end
end