class Coolio::IO
A buffered I/O class witch fits into the Coolio Watcher framework. It provides both an observer which reads data as it's received from the wire and a buffered write watcher which stores data and writes it out each time the socket becomes writable.
This class is primarily meant as a base class for other streams which need non-blocking writing, and is used to implement Coolio's Socket class and its associated subclasses.
Constants
- INPUT_SIZE
Maximum number of bytes to consume at once
Public Class Methods
# File lib/cool.io/io.rb, line 22 def initialize(io) @_io = io @_write_buffer ||= ::IO::Buffer.new @_read_watcher = Watcher.new(io, self, :r) @_write_watcher = Watcher.new(io, self, :w) end
Public Instance Methods
Attach to the event loop
# File lib/cool.io/io.rb, line 34 def attach(loop) @_read_watcher.attach(loop) schedule_write if !@_write_buffer.empty? self end
Is the watcher attached?
# File lib/cool.io/io.rb, line 60 def attached? @_read_watcher.attached? end
Close the IO stream
# File lib/cool.io/io.rb, line 107 def close detach if attached? detach_write_watcher @_io.close unless @_io.closed? on_close nil end
Is the IO object closed?
# File lib/cool.io/io.rb, line 117 def closed? @_io.nil? or @_io.closed? end
Detach from the event loop
# File lib/cool.io/io.rb, line 41 def detach # TODO should these detect write buffers, as well? @_read_watcher.detach self end
Disable the watcher
# File lib/cool.io/io.rb, line 54 def disable @_read_watcher.disable self end
Enable the watcher
# File lib/cool.io/io.rb, line 48 def enable @_read_watcher.enable self end
Is the watcher enabled?
# File lib/cool.io/io.rb, line 65 def enabled? @_read_watcher.enabled? end
Obtain the event loop associated with this object
# File lib/cool.io/io.rb, line 70 def evloop @_read_watcher.evloop end
Called whenever the IO object hits EOF
# File lib/cool.io/io.rb, line 87 def on_close; end
Called whenever the IO object receives data
# File lib/cool.io/io.rb, line 79 def on_read(data); end
Called whenever a write completes and the output buffer is empty
# File lib/cool.io/io.rb, line 83 def on_write_complete; end
Number of bytes are currently in the output buffer
# File lib/cool.io/io.rb, line 102 def output_buffer_size @_write_buffer.size end
Write data in a buffered, non-blocking manner
# File lib/cool.io/io.rb, line 95 def write(data) @_write_buffer << data schedule_write data.size end
Protected Instance Methods
# File lib/cool.io/io.rb, line 178 def detach_write_watcher @_write_watcher.detach if @_write_watcher and @_write_watcher.attached? end
# File lib/cool.io/io.rb, line 174 def disable_write_watcher @_write_watcher.disable if @_write_watcher and @_write_watcher.enabled? end
# File lib/cool.io/io.rb, line 166 def enable_write_watcher if @_write_watcher.attached? @_write_watcher.enable unless @_write_watcher.enabled? else @_write_watcher.attach(evloop) end end
Read from the input buffer and dispatch to #on_read
# File lib/cool.io/io.rb, line 126 def on_readable begin on_read @_io.read_nonblock(INPUT_SIZE) rescue Errno::EAGAIN, Errno::EINTR return # SystemCallError catches Errno::ECONNRESET amongst others. rescue SystemCallError, EOFError, IOError, SocketError close end end
Write the contents of the output buffer
# File lib/cool.io/io.rb, line 139 def on_writable begin @_write_buffer.write_to(@_io) rescue Errno::EINTR return # SystemCallError catches Errno::EPIPE & Errno::ECONNRESET amongst others. rescue SystemCallError, IOError, SocketError return close end if @_write_buffer.empty? disable_write_watcher on_write_complete end end
Schedule a write to be performed when the IO object becomes writable
# File lib/cool.io/io.rb, line 157 def schedule_write return unless @_io # this would mean 'we are still pre DNS here' return unless @_read_watcher.attached? # this would mean 'currently unattached' -- ie still pre DNS, or just plain not attached, which is ok begin enable_write_watcher rescue IOError end end