lib/lightio/watchers/io.rb in lightio-0.4.2 vs lib/lightio/watchers/io.rb in lightio-0.4.3

- old
+ new

@@ -19,32 +19,41 @@ # @return [LightIO::Watchers::IO] def initialize(io, interests=:rw) @io = io @ioloop = LightIO::Core::IOloop.current @waiting = false - ObjectSpace.define_finalizer(self, self.class.finalizer(@monitor)) @error = nil # maintain socket status, see https://github.com/socketry/lightio/issues/1 @readiness = nil + @monitor = nil end # NIO::Monitor def monitor(interests=:rw) @monitor ||= begin - @ioloop.add_io_wait(@io, interests) {callback_on_waiting} + raise @error if @error + monitor = @ioloop.add_io_wait(@io, interests) {callback_on_waiting} + ObjectSpace.define_finalizer(self, self.class.finalizer(monitor)) + monitor end end class << self def finalizer(monitor) proc {monitor.close if monitor && !monitor.close?} end end extend Forwardable - def_delegators :monitor, :interests, :interests=, :closed? + def_delegators :monitor, :interests, :interests= + def closed? + # check @monitor exists, avoid unnecessary monitor created + return true unless @monitor + monitor.closed? + end + # this method return previous IO.select status # should avoid to directly use def readable? check_monitor_read @readiness == :r || @readiness == :rw @@ -88,13 +97,13 @@ rescue Timeout::Error nil end def close + set_close_error return if closed? monitor.close - @error = IOError.new('closed stream') callback_on_waiting end # just implement IOloop#wait watcher interface @@ -105,9 +114,13 @@ def set_callback(&blk) @callback = blk end private + def set_close_error + @error ||= IOError.new('closed stream') + end + def check_monitor(mode) case mode when :read check_monitor_read when :write \ No newline at end of file