Class: NIO::Selector
- Inherits:
-
Object
- Object
- NIO::Selector
- Defined in:
- lib/nio/selector.rb,
ext/nio4r/selector.c
Overview
Selectors monitor IO objects for events of interest
Instance Method Summary collapse
-
#close ⇒ Object
Close this selector and free its resources.
-
#closed? ⇒ Boolean
Is this selector closed?.
-
#deregister(io) ⇒ Object
Deregister the given IO object from the selector.
- #empty? ⇒ Boolean
-
#initialize ⇒ Object
constructor
Methods.
-
#register(io, interest) ⇒ Object
Register interest in an IO object with the selector for the given types of events.
-
#registered?(io) ⇒ Boolean
Is the given IO object registered with the selector?.
-
#select(timeout = nil) ⇒ Object
Select which monitors are ready.
-
#wakeup ⇒ Object
Wake up a thread that’s in the middle of selecting on this selector, if any such thread exists.
Constructor Details
#initialize ⇒ Object
Methods
7 8 9 10 11 12 13 14 |
# File 'lib/nio/selector.rb', line 7 def initialize @selectables = {} @lock = Mutex.new # Other threads can wake up a selector @wakeup, @waker = IO.pipe @closed = false end |
Instance Method Details
#close ⇒ Object
Close this selector and free its resources
114 115 116 117 118 119 120 121 122 |
# File 'lib/nio/selector.rb', line 114 def close @lock.synchronize do return if @closed @wakeup.close rescue nil @waker.close rescue nil @closed = true end end |
#closed? ⇒ Boolean
Is this selector closed?
125 126 127 |
# File 'lib/nio/selector.rb', line 125 def closed? @closed end |
#deregister(io) ⇒ Object
Deregister the given IO object from the selector
36 37 38 39 40 41 42 |
# File 'lib/nio/selector.rb', line 36 def deregister(io) @lock.synchronize do monitor = @selectables.delete io monitor.close(false) if monitor && !monitor.closed? monitor end end |
#empty? ⇒ Boolean
39 40 41 |
# File 'ext/nio4r/selector.c', line 39 def empty? @selectables.empty? end |
#register(io, interest) ⇒ Object
Register interest in an IO object with the selector for the given types of events. Valid event types for interest are:
-
:r - is the IO readable?
-
:w - is the IO writeable?
-
:rw - is the IO either readable or writeable?
21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/nio/selector.rb', line 21 def register(io, interest) @lock.synchronize do fail IOError, "selector is closed" if closed? monitor = @selectables[io] fail ArgumentError, "already registered as #{monitor.interests.inspect}" if monitor monitor = Monitor.new(io, interest, self) @selectables[monitor.io] = monitor monitor end end |
#registered?(io) ⇒ Boolean
Is the given IO object registered with the selector?
45 46 47 |
# File 'lib/nio/selector.rb', line 45 def registered?(io) @lock.synchronize { @selectables.key? io } end |
#select(timeout = nil) ⇒ Object
Select which monitors are ready
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/nio/selector.rb', line 50 def select(timeout = nil) @lock.synchronize do readers = [@wakeup] writers = [] @selectables.each do |io, monitor| readers << io if monitor.interests == :r || monitor.interests == :rw writers << io if monitor.interests == :w || monitor.interests == :rw monitor.readiness = nil end ready_readers, ready_writers = Kernel.select readers, writers, [], timeout return unless ready_readers # timeout or wakeup selected_monitors = Set.new ready_readers.each do |io| if io == @wakeup # Clear all wakeup signals we've received by reading them # Wakeups should have level triggered behavior @wakeup.read(@wakeup.stat.size) return else monitor = @selectables[io] monitor.readiness = :r selected_monitors << monitor end end ready_writers.each do |io| monitor = @selectables[io] monitor.readiness = case monitor.readiness when :r :rw else :w end selected_monitors << monitor end if block_given? selected_monitors.each do |m| yield m end selected_monitors.size else selected_monitors end end end |
#wakeup ⇒ Object
Wake up a thread that’s in the middle of selecting on this selector, if any such thread exists.
Invoking this method more than once between two successive select calls has the same effect as invoking it just once. In other words, it provides level-triggered behavior.
107 108 109 110 111 |
# File 'lib/nio/selector.rb', line 107 def wakeup # Send the selector a signal in the form of writing data to a pipe @waker.write "\0" nil end |