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