lib/lightio/library/io.rb in lightio-0.3.2 vs lib/lightio/library/io.rb in lightio-0.4.0.pre

- old
+ new

@@ -1,11 +1,13 @@ -require 'forwardable' module LightIO::Library class IO + include Base include LightIO::Wrap::IOWrapper - wrap ::IO + mock ::IO + extend LightIO::Module::IO::ClassMethods + wrap_blocking_methods :read, :write alias_method :<<, :write def read(length=nil, outbuf=nil) @@ -17,11 +19,11 @@ outbuf << data if length == outbuf.size return outbuf end else - return length.nil? ? '' : nil + return length.nil? ? outbuf : nil end end end def readpartial(maxlen, outbuf=nil) @@ -38,11 +40,11 @@ read(1) end def getc wait_readable - @io.getc + @obj.getc end def readline(*args) line = gets(*args) raise EOFError, 'end of file reached' if line.nil? @@ -69,11 +71,11 @@ b end def eof wait_readable - @io.eof? + @obj.eof end alias eof? eof def gets(*args) @@ -93,102 +95,29 @@ break if c == sep end $_ = s end - def close(*args) - # close watcher before io closed - @io_watcher.close - @io.close(*args) - end - def to_io self end + def close(*args) + # close watcher before io closed + io_watcher.close + @obj.close + end + private def wait_readable # if IO is already readable, continue wait_readable may block it forever # so use getbyte detect this situation # Maybe move getc and gets to thread pool is a good idea b = getbyte if b ungetbyte(b) return end - @io_watcher.wait_readable - end - - class << self - def open(*args) - io = self.new(*args) - return io unless block_given? - begin - yield io - ensure - io.close if io.respond_to? :close - end - end - - def pipe(*args) - r, w = raw_class.pipe - if block_given? - begin - return yield r, w - ensure - w.close - r.close - end - end - [IO._wrap(r), IO._wrap(w)] - end - - def select(read_fds, write_fds=nil, _except_fds=nil, timeout=nil) - timer = timeout && Time.now - read_fds ||= [] - write_fds ||= [] - loop do - # make sure io registered, then clear io watcher status - read_fds.each {|fd| get_io_watcher(fd).tap {|io| io.readable?; io.clear_status}} - write_fds.each {|fd| get_io_watcher(fd).tap {|io| io.writable?; io.clear_status}} - # run ioloop once - LightIO.sleep 0 - r_fds = read_fds.select {|fd| - io = convert_to_io(fd) - io.closed? ? raise(IOError, 'closed stream') : get_io_watcher(io).readable? - } - w_fds = write_fds.select {|fd| - io = convert_to_io(fd) - io.closed? ? raise(IOError, 'closed stream') : get_io_watcher(io).writable? - } - e_fds = [] - if r_fds.empty? && w_fds.empty? - if timeout && Time.now - timer > timeout - return nil - end - else - return [r_fds, w_fds, e_fds] - end - end - end - - private - def convert_to_io(io) - unless io.respond_to?(:to_io) - raise TypeError, "no implicit conversion of #{io.class} into IO" - end - to_io = io.to_io - unless to_io.is_a?(IO) - raise TypeError, "can't convert #{io.class} to IO (#{io.class}#to_io gives #{to_io.class})" - end - to_io - end - - def get_io_watcher(io) - unless io.is_a?(IO) - io = convert_to_io(io) - end - io.instance_variable_get(:@io_watcher) - end + io_watcher.wait_readable end end end