lib/lightio/library/io.rb in lightio-0.3.1 vs lib/lightio/library/io.rb in lightio-0.3.2
- old
+ new
@@ -116,20 +116,19 @@
return
end
@io_watcher.wait_readable
end
- def io_watcher
- @io_watcher
- end
-
class << self
def open(*args)
io = self.new(*args)
- yield io
- ensure
- io.close if io.respond_to? :close
+ 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?
@@ -146,25 +145,50 @@
def select(read_fds, write_fds=nil, _except_fds=nil, timeout=nil)
timer = timeout && Time.now
read_fds ||= []
write_fds ||= []
loop do
- # clear io watcher status
- read_fds.each {|fd| fd.send(:io_watcher).clear_status}
- write_fds.each {|fd| fd.send(:io_watcher).clear_status}
+ # 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| fd.closed? ? raise(IOError, 'closed stream') : fd.send(:io_watcher).readable?}
- w_fds = write_fds.select {|fd| fd.closed? ? raise(IOError, 'closed stream') : fd.send(:io_watcher).writable?}
+ 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
end
end
end