Class: LightIO::Watchers::IO

Inherits:
Watcher
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/lightio/watchers/io.rb

Overview

LightIO::Watchers::IO provide a NIO::Monitor wrap to manage ‘raw’ socket / io

@Example:

#- wait_read for server socket
io_watcher = LightIO::Watchers::IO.new(server_socket, :r)
loop do
  io_watcher.wait_read
  client_socket = server_socket.accept
  # do something
end
io_watcher.close

Instance Attribute Summary

Attributes inherited from Watcher

#callback

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io, interests = :rw) ⇒ LightIO::Watchers::IO

Create a io watcher

Parameters:

  • io (Socket)

    An IO-able object

  • interests (Symbol) (defaults to: :rw)

    :r, :w, :rw - Is io readable? writeable? or both



20
21
22
23
24
25
26
27
28
# File 'lib/lightio/watchers/io.rb', line 20

def initialize(io, interests=:rw)
  @io = io
  @ioloop = LightIO::Core::IOloop.current
  @waiting = false
  @error = nil
  # maintain socket status, see https://github.com/socketry/lightio/issues/1
  @readiness = nil
  @monitor = nil
end

Class Method Details

.finalizer(monitor) ⇒ Object



41
42
43
# File 'lib/lightio/watchers/io.rb', line 41

def finalizer(monitor)
  proc {monitor.close if monitor && !monitor.close?}
end

Instance Method Details

#clear_statusObject



71
72
73
# File 'lib/lightio/watchers/io.rb', line 71

def clear_status
  @readiness = nil
end

#closeObject



101
102
103
104
105
106
# File 'lib/lightio/watchers/io.rb', line 101

def close
  set_close_error
  return if closed?
  monitor.close
  callback_on_waiting
end

#closed?Boolean

Returns:

  • (Boolean)


49
50
51
52
53
# File 'lib/lightio/watchers/io.rb', line 49

def closed?
  # check @monitor exists, avoid unnecessary monitor created
  return true unless @monitor
  monitor.closed?
end

#monitor(interests = :rw) ⇒ Object

NIO::Monitor



31
32
33
34
35
36
37
38
# File 'lib/lightio/watchers/io.rb', line 31

def monitor(interests=:rw)
  @monitor ||= begin
    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

#readable?Boolean

this method return previous IO.select status should avoid to directly use

Returns:

  • (Boolean)


57
58
59
60
# File 'lib/lightio/watchers/io.rb', line 57

def readable?
  check_monitor_read
  @readiness == :r || @readiness == :rw
end

#set_callback(&blk) ⇒ Object



114
115
116
# File 'lib/lightio/watchers/io.rb', line 114

def set_callback(&blk)
  @callback = blk
end

#start(ioloop) ⇒ Object

just implement IOloop#wait watcher interface



110
111
112
# File 'lib/lightio/watchers/io.rb', line 110

def start(ioloop)
  # do nothing
end

#wait(timeout = nil, mode = :read) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/lightio/watchers/io.rb', line 89

def wait(timeout=nil, mode=:read)
  LightIO::Timeout.timeout(timeout) do
    check_monitor(mode)
    in_waiting(mode) do
      wait_in_ioloop
    end
    self
  end
rescue Timeout::Error
  nil
end

#wait_readable(timeout = nil) ⇒ LightIO::Watchers::IO?

Blocking until io is readable

Parameters:

  • timeout (Numeric) (defaults to: nil)

    return nil after timeout seconds, otherwise return self

Returns:



78
79
80
# File 'lib/lightio/watchers/io.rb', line 78

def wait_readable(timeout=nil)
  wait timeout, :read
end

#wait_writable(timeout = nil) ⇒ LightIO::Watchers::IO?

Blocking until io is writable

Parameters:

  • timeout (Numeric) (defaults to: nil)

    return nil after timeout seconds, otherwise return self

Returns:



85
86
87
# File 'lib/lightio/watchers/io.rb', line 85

def wait_writable(timeout=nil)
  wait timeout, :write
end

#writable?Boolean Also known as: writeable?

this method return previous IO.select status should avoid to directly use

Returns:

  • (Boolean)


64
65
66
67
# File 'lib/lightio/watchers/io.rb', line 64

def writable?
  check_monitor_write
  @readiness == :w || @readiness == :rw
end