nio4r 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +6 -2
- data/CHANGES.md +10 -0
- data/LICENSE.txt +1 -1
- data/README.md +16 -11
- data/Rakefile +2 -2
- data/examples/echo_server.rb +9 -0
- data/ext/libev/Changes +34 -2
- data/ext/libev/ev.c +694 -131
- data/ext/libev/ev.h +89 -79
- data/ext/libev/ev_epoll.c +23 -10
- data/ext/libev/ev_kqueue.c +4 -4
- data/ext/libev/ev_poll.c +4 -4
- data/ext/libev/ev_port.c +9 -3
- data/ext/libev/ev_select.c +10 -6
- data/ext/libev/ev_vars.h +3 -2
- data/ext/libev/ev_wrap.h +6 -4
- data/ext/nio4r/monitor.c +23 -6
- data/ext/nio4r/org/nio4r/Nio4r.java +409 -0
- data/ext/nio4r/selector.c +36 -8
- data/lib/nio.rb +4 -7
- data/lib/nio/monitor.rb +15 -4
- data/lib/nio/selector.rb +23 -6
- data/lib/nio/version.rb +1 -1
- data/nio4r.gemspec +2 -2
- data/spec/nio/acceptables_spec.rb +30 -0
- data/spec/nio/monitor_spec.rb +37 -22
- data/spec/nio/selectables_spec.rb +178 -0
- data/spec/nio/selector_spec.rb +71 -173
- data/tasks/extension.rake +6 -5
- metadata +17 -14
- data/lib/nio/jruby/monitor.rb +0 -42
- data/lib/nio/jruby/selector.rb +0 -136
data/spec/nio/selector_spec.rb
CHANGED
@@ -6,11 +6,17 @@ require 'spec_helper'
|
|
6
6
|
TIMEOUT_PRECISION = 0.1
|
7
7
|
|
8
8
|
describe NIO::Selector do
|
9
|
-
|
10
|
-
|
9
|
+
context "register" do
|
10
|
+
it "registers IO objects" do
|
11
|
+
pipe, _ = IO.pipe
|
12
|
+
|
13
|
+
monitor = subject.register(pipe, :r)
|
14
|
+
monitor.should_not be_closed
|
15
|
+
end
|
11
16
|
|
12
|
-
|
13
|
-
|
17
|
+
it "raises TypeError if asked to register non-IO objects" do
|
18
|
+
expect { subject.register(42, :r) }.to raise_exception TypeError
|
19
|
+
end
|
14
20
|
end
|
15
21
|
|
16
22
|
it "knows which IO objects are registered" do
|
@@ -30,22 +36,31 @@ describe NIO::Selector do
|
|
30
36
|
monitor.should be_closed
|
31
37
|
end
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
|
39
|
+
context "timeouts" do
|
40
|
+
it "waits for a timeout when selecting" do
|
41
|
+
reader, writer = IO.pipe
|
42
|
+
monitor = subject.register(reader, :r)
|
36
43
|
|
37
|
-
|
38
|
-
|
44
|
+
payload = "hi there"
|
45
|
+
writer << payload
|
39
46
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
47
|
+
timeout = 0.5
|
48
|
+
started_at = Time.now
|
49
|
+
subject.select(timeout).should include monitor
|
50
|
+
(Time.now - started_at).should be_within(TIMEOUT_PRECISION).of(0)
|
51
|
+
reader.read_nonblock(payload.size)
|
45
52
|
|
46
|
-
|
47
|
-
|
48
|
-
|
53
|
+
started_at = Time.now
|
54
|
+
subject.select(timeout).should be_nil
|
55
|
+
(Time.now - started_at).should be_within(TIMEOUT_PRECISION).of(timeout)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "raises ArgumentError if given a negative timeout" do
|
59
|
+
reader, _ = IO.pipe
|
60
|
+
subject.register(reader, :r)
|
61
|
+
|
62
|
+
expect { subject.select(-1) }.to raise_exception(ArgumentError)
|
63
|
+
end
|
49
64
|
end
|
50
65
|
|
51
66
|
context "wakeup" do
|
@@ -74,6 +89,45 @@ describe NIO::Selector do
|
|
74
89
|
end
|
75
90
|
end
|
76
91
|
|
92
|
+
context "select" do
|
93
|
+
it "selects IO objects" do
|
94
|
+
readable, writer = IO.pipe
|
95
|
+
writer << "ohai"
|
96
|
+
|
97
|
+
unreadable, _ = IO.pipe
|
98
|
+
|
99
|
+
readable_monitor = subject.register(readable, :r)
|
100
|
+
unreadable_monitor = subject.register(unreadable, :r)
|
101
|
+
|
102
|
+
selected = subject.select(0)
|
103
|
+
selected.size.should == 1
|
104
|
+
selected.should include(readable_monitor)
|
105
|
+
selected.should_not include(unreadable_monitor)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "iterates across selected objects with a block" do
|
109
|
+
readable1, writer = IO.pipe
|
110
|
+
writer << "ohai"
|
111
|
+
|
112
|
+
readable2, writer = IO.pipe
|
113
|
+
writer << "ohai"
|
114
|
+
|
115
|
+
unreadable, _ = IO.pipe
|
116
|
+
|
117
|
+
monitor1 = subject.register(readable1, :r)
|
118
|
+
monitor2 = subject.register(readable2, :r)
|
119
|
+
monitor3 = subject.register(unreadable, :r)
|
120
|
+
|
121
|
+
readables = []
|
122
|
+
result = subject.select { |monitor| readables << monitor }
|
123
|
+
result.should == 2
|
124
|
+
|
125
|
+
readables.should include(monitor1)
|
126
|
+
readables.should include(monitor2)
|
127
|
+
readables.should_not include(monitor3)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
77
131
|
context "select_each" do
|
78
132
|
it "iterates across ready selectables" do
|
79
133
|
readable1, writer = IO.pipe
|
@@ -117,160 +171,4 @@ describe NIO::Selector do
|
|
117
171
|
subject.close
|
118
172
|
subject.should be_closed
|
119
173
|
end
|
120
|
-
|
121
|
-
context "selectables" do
|
122
|
-
shared_context "an NIO selectable" do
|
123
|
-
it "selects for read readiness" do
|
124
|
-
waiting_monitor = subject.register(unreadable_subject, :r)
|
125
|
-
ready_monitor = subject.register(readable_subject, :r)
|
126
|
-
|
127
|
-
ready_monitors = subject.select
|
128
|
-
ready_monitors.should include ready_monitor
|
129
|
-
ready_monitors.should_not include waiting_monitor
|
130
|
-
end
|
131
|
-
|
132
|
-
it "selects for write readiness" do
|
133
|
-
waiting_monitor = subject.register(unwritable_subject, :w)
|
134
|
-
ready_monitor = subject.register(writable_subject, :w)
|
135
|
-
|
136
|
-
ready_monitors = subject.select(0.1)
|
137
|
-
|
138
|
-
ready_monitors.should include ready_monitor
|
139
|
-
ready_monitors.should_not include waiting_monitor
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
context "IO.pipe" do
|
144
|
-
let :readable_subject do
|
145
|
-
pipe, peer = IO.pipe
|
146
|
-
peer << "data"
|
147
|
-
pipe
|
148
|
-
end
|
149
|
-
|
150
|
-
let :unreadable_subject do
|
151
|
-
pipe, _ = IO.pipe
|
152
|
-
pipe
|
153
|
-
end
|
154
|
-
|
155
|
-
let :writable_subject do
|
156
|
-
_, pipe = IO.pipe
|
157
|
-
pipe
|
158
|
-
end
|
159
|
-
|
160
|
-
let :unwritable_subject do
|
161
|
-
reader, pipe = IO.pipe
|
162
|
-
|
163
|
-
begin
|
164
|
-
pipe.write_nonblock "JUNK IN THE TUBES"
|
165
|
-
_, writers = select [], [pipe], [], 0
|
166
|
-
rescue Errno::EPIPE
|
167
|
-
break
|
168
|
-
end while writers and writers.include? pipe
|
169
|
-
|
170
|
-
pipe
|
171
|
-
end
|
172
|
-
|
173
|
-
it_behaves_like "an NIO selectable"
|
174
|
-
end
|
175
|
-
|
176
|
-
context TCPSocket do
|
177
|
-
let(:tcp_port) { 12345 }
|
178
|
-
|
179
|
-
let :readable_subject do
|
180
|
-
server = TCPServer.new("localhost", tcp_port)
|
181
|
-
sock = TCPSocket.open("localhost", tcp_port)
|
182
|
-
peer = server.accept
|
183
|
-
peer << "data"
|
184
|
-
sock
|
185
|
-
end
|
186
|
-
|
187
|
-
let :unreadable_subject do
|
188
|
-
if defined?(JRUBY_VERSION) and ENV['TRAVIS']
|
189
|
-
pending "This is sporadically showing up readable on JRuby in CI"
|
190
|
-
else
|
191
|
-
TCPServer.new("localhost", tcp_port + 1)
|
192
|
-
TCPSocket.open("localhost", tcp_port + 1)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
let :writable_subject do
|
197
|
-
TCPServer.new("localhost", tcp_port + 2)
|
198
|
-
TCPSocket.open("localhost", tcp_port + 2)
|
199
|
-
end
|
200
|
-
|
201
|
-
let :unwritable_subject do
|
202
|
-
server = TCPServer.new("localhost", tcp_port + 3)
|
203
|
-
sock = TCPSocket.open("localhost", tcp_port + 3)
|
204
|
-
peer = server.accept
|
205
|
-
|
206
|
-
begin
|
207
|
-
sock.write_nonblock "JUNK IN THE TUBES"
|
208
|
-
_, writers = select [], [sock], [], 0
|
209
|
-
end while writers and writers.include? sock
|
210
|
-
|
211
|
-
sock
|
212
|
-
end
|
213
|
-
|
214
|
-
it_behaves_like "an NIO selectable"
|
215
|
-
end
|
216
|
-
|
217
|
-
context UDPSocket do
|
218
|
-
let(:udp_port) { 23456 }
|
219
|
-
|
220
|
-
let :readable_subject do
|
221
|
-
sock = UDPSocket.new
|
222
|
-
sock.bind('localhost', udp_port)
|
223
|
-
|
224
|
-
peer = UDPSocket.new
|
225
|
-
peer.send("hi there", 0, 'localhost', udp_port)
|
226
|
-
|
227
|
-
sock
|
228
|
-
end
|
229
|
-
|
230
|
-
let :unreadable_subject do
|
231
|
-
sock = UDPSocket.new
|
232
|
-
sock.bind('localhost', udp_port + 1)
|
233
|
-
sock
|
234
|
-
end
|
235
|
-
|
236
|
-
let :writable_subject do
|
237
|
-
pending "come up with a writable UDPSocket example"
|
238
|
-
end
|
239
|
-
|
240
|
-
let :unwritable_subject do
|
241
|
-
pending "come up with a UDPSocket that's blocked on writing"
|
242
|
-
end
|
243
|
-
|
244
|
-
it_behaves_like "an NIO selectable"
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
context "acceptables" do
|
249
|
-
shared_context "an NIO acceptable" do
|
250
|
-
it "selects for read readiness" do
|
251
|
-
waiting_monitor = subject.register(unacceptable_subject, :r)
|
252
|
-
ready_monitor = subject.register(acceptable_subject, :r)
|
253
|
-
|
254
|
-
ready_monitors = subject.select
|
255
|
-
ready_monitors.should include ready_monitor
|
256
|
-
ready_monitors.should_not include waiting_monitor
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
context TCPServer do
|
261
|
-
let(:tcp_port) { 23456 }
|
262
|
-
|
263
|
-
let :acceptable_subject do
|
264
|
-
server = TCPServer.new("localhost", tcp_port)
|
265
|
-
TCPSocket.open("localhost", tcp_port)
|
266
|
-
server
|
267
|
-
end
|
268
|
-
|
269
|
-
let :unacceptable_subject do
|
270
|
-
TCPServer.new("localhost", tcp_port + 1)
|
271
|
-
end
|
272
|
-
|
273
|
-
it_behaves_like "an NIO acceptable"
|
274
|
-
end
|
275
|
-
end
|
276
174
|
end
|
data/tasks/extension.rake
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
if defined? JRUBY_VERSION
|
2
|
+
require 'rake/javaextensiontask'
|
3
|
+
Rake::JavaExtensionTask.new('nio4r_ext') do |ext|
|
4
|
+
ext.ext_dir = 'ext/nio4r'
|
5
|
+
end
|
6
6
|
else
|
7
|
+
require 'rake/extensiontask'
|
7
8
|
Rake::ExtensionTask.new('nio4r_ext') do |ext|
|
8
9
|
ext.ext_dir = 'ext/nio4r'
|
9
10
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nio4r
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,22 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-02-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake-compiler
|
16
|
-
requirement: &
|
16
|
+
requirement: &70285234600680 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0
|
21
|
+
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70285234600680
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70285234600040 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,18 +32,18 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70285234600040
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rspec
|
38
|
-
requirement: &
|
38
|
+
requirement: &70285234599480 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
|
-
- -
|
41
|
+
- - ! '>='
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version:
|
43
|
+
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70285234599480
|
47
47
|
description: New IO for Ruby
|
48
48
|
email:
|
49
49
|
- tony.arcieri@gmail.com
|
@@ -81,15 +81,16 @@ files:
|
|
81
81
|
- ext/nio4r/monitor.c
|
82
82
|
- ext/nio4r/nio4r.h
|
83
83
|
- ext/nio4r/nio4r_ext.c
|
84
|
+
- ext/nio4r/org/nio4r/Nio4r.java
|
84
85
|
- ext/nio4r/selector.c
|
85
86
|
- lib/nio.rb
|
86
|
-
- lib/nio/jruby/monitor.rb
|
87
|
-
- lib/nio/jruby/selector.rb
|
88
87
|
- lib/nio/monitor.rb
|
89
88
|
- lib/nio/selector.rb
|
90
89
|
- lib/nio/version.rb
|
91
90
|
- nio4r.gemspec
|
91
|
+
- spec/nio/acceptables_spec.rb
|
92
92
|
- spec/nio/monitor_spec.rb
|
93
|
+
- spec/nio/selectables_spec.rb
|
93
94
|
- spec/nio/selector_spec.rb
|
94
95
|
- spec/spec_helper.rb
|
95
96
|
- tasks/extension.rake
|
@@ -119,7 +120,9 @@ signing_key:
|
|
119
120
|
specification_version: 3
|
120
121
|
summary: NIO provides a high performance selector API for monitoring IO objects
|
121
122
|
test_files:
|
123
|
+
- spec/nio/acceptables_spec.rb
|
122
124
|
- spec/nio/monitor_spec.rb
|
125
|
+
- spec/nio/selectables_spec.rb
|
123
126
|
- spec/nio/selector_spec.rb
|
124
127
|
- spec/spec_helper.rb
|
125
128
|
has_rdoc:
|
data/lib/nio/jruby/monitor.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
module NIO
|
2
|
-
# Monitors watch Channels for specific events
|
3
|
-
class Monitor
|
4
|
-
attr_accessor :value, :io
|
5
|
-
|
6
|
-
# :nodoc
|
7
|
-
def initialize(io, selection_key)
|
8
|
-
@io, @key = io, selection_key
|
9
|
-
selection_key.attach self
|
10
|
-
@closed = false
|
11
|
-
end
|
12
|
-
|
13
|
-
# Obtain the interests for this monitor
|
14
|
-
def interests
|
15
|
-
Selector.iops2sym @key.interestOps
|
16
|
-
end
|
17
|
-
|
18
|
-
# What is the IO object ready for?
|
19
|
-
def readiness
|
20
|
-
Selector.iops2sym @key.readyOps
|
21
|
-
end
|
22
|
-
|
23
|
-
# Is the IO object readable?
|
24
|
-
def readable?
|
25
|
-
readiness == :r || readiness == :rw
|
26
|
-
end
|
27
|
-
|
28
|
-
# Is the IO object writable?
|
29
|
-
def writable?
|
30
|
-
readiness == :w || readiness == :rw
|
31
|
-
end
|
32
|
-
alias_method :writeable?, :writable?
|
33
|
-
|
34
|
-
# Is this monitor closed?
|
35
|
-
def closed?; @closed; end
|
36
|
-
|
37
|
-
# Deactivate this monitor
|
38
|
-
def close
|
39
|
-
@closed = true
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
data/lib/nio/jruby/selector.rb
DELETED
@@ -1,136 +0,0 @@
|
|
1
|
-
module NIO
|
2
|
-
# Selectors monitor IO objects for events of interest
|
3
|
-
class Selector
|
4
|
-
java_import "java.nio.channels.Selector"
|
5
|
-
java_import "java.nio.channels.SelectionKey"
|
6
|
-
|
7
|
-
# Convert nio4r interest symbols to Java NIO interest ops
|
8
|
-
def self.sym2iops(interest, channel)
|
9
|
-
case interest
|
10
|
-
when :r
|
11
|
-
if channel.validOps & SelectionKey::OP_ACCEPT != 0
|
12
|
-
SelectionKey::OP_ACCEPT
|
13
|
-
else
|
14
|
-
SelectionKey::OP_READ
|
15
|
-
end
|
16
|
-
when :w
|
17
|
-
if channel.respond_to? :connected? and not channel.connected?
|
18
|
-
SelectionKey::OP_CONNECT
|
19
|
-
else
|
20
|
-
SelectionKey::OP_WRITE
|
21
|
-
end
|
22
|
-
when :rw
|
23
|
-
super(:r, channel) | super(:w, channel)
|
24
|
-
else raise ArgumentError, "invalid interest type: #{interest}"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
# Convert Java NIO interest ops to the corresponding Ruby symbols
|
29
|
-
def self.iops2sym(interest_ops)
|
30
|
-
case interest_ops
|
31
|
-
when SelectionKey::OP_READ, SelectionKey::OP_ACCEPT
|
32
|
-
:r
|
33
|
-
when SelectionKey::OP_WRITE, SelectionKey::OP_CONNECT
|
34
|
-
:w
|
35
|
-
when SelectionKey::OP_READ | SelectionKey::OP_WRITE
|
36
|
-
:rw
|
37
|
-
when 0 then nil
|
38
|
-
else raise ArgumentError, "unknown interest op combination: 0x#{interest_ops.to_s(16)}"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Create a new NIO::Selector
|
43
|
-
def initialize
|
44
|
-
@java_selector = Selector.open
|
45
|
-
@select_lock = Mutex.new
|
46
|
-
end
|
47
|
-
|
48
|
-
# Register interest in an IO object with the selector for the given types
|
49
|
-
# of events. Valid event types for interest are:
|
50
|
-
# * :r - is the IO readable?
|
51
|
-
# * :w - is the IO writeable?
|
52
|
-
# * :rw - is the IO either readable or writeable?
|
53
|
-
def register(io, interest)
|
54
|
-
java_channel = io.to_channel
|
55
|
-
java_channel.configureBlocking(false)
|
56
|
-
interest_ops = self.class.sym2iops(interest, java_channel)
|
57
|
-
|
58
|
-
begin
|
59
|
-
selector_key = java_channel.register @java_selector, interest_ops
|
60
|
-
rescue NativeException => ex
|
61
|
-
case ex.cause
|
62
|
-
when java.lang.IllegalArgumentException
|
63
|
-
raise ArgumentError, "invalid interest type for #{java_channel}: #{interest}"
|
64
|
-
else raise
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
NIO::Monitor.new(io, selector_key)
|
69
|
-
end
|
70
|
-
|
71
|
-
# Deregister the given IO object from the selector
|
72
|
-
def deregister(io)
|
73
|
-
key = io.to_channel.keyFor(@java_selector)
|
74
|
-
return unless key
|
75
|
-
|
76
|
-
monitor = key.attachment
|
77
|
-
monitor.close
|
78
|
-
monitor
|
79
|
-
end
|
80
|
-
|
81
|
-
# Is the given IO object registered with the selector?
|
82
|
-
def registered?(io)
|
83
|
-
key = io.to_channel.keyFor(@java_selector)
|
84
|
-
return unless key
|
85
|
-
!key.attachment.closed?
|
86
|
-
end
|
87
|
-
|
88
|
-
# Select which monitors are ready
|
89
|
-
def select(timeout = nil)
|
90
|
-
selected = []
|
91
|
-
ready = select_each(timeout) { |monitor| selected << monitor }
|
92
|
-
return unless ready
|
93
|
-
|
94
|
-
selected
|
95
|
-
end
|
96
|
-
|
97
|
-
# Iterate across all selectable monitors
|
98
|
-
def select_each(timeout = nil)
|
99
|
-
@select_lock.synchronize do
|
100
|
-
if timeout == 0
|
101
|
-
# The Java NIO API thinks zero means you want to BLOCK FOREVER o_O
|
102
|
-
# How about we don't block at all instead?
|
103
|
-
ready = @java_selector.selectNow
|
104
|
-
elsif timeout
|
105
|
-
ready = @java_selector.select(timeout * 1000)
|
106
|
-
else
|
107
|
-
ready = @java_selector.select
|
108
|
-
end
|
109
|
-
|
110
|
-
return unless ready > 0 # timeout or wakeup
|
111
|
-
|
112
|
-
@java_selector.selectedKeys.each { |key| yield key.attachment }
|
113
|
-
@java_selector.selectedKeys.clear
|
114
|
-
|
115
|
-
ready
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
# Wake up the other thread that's currently blocking on this selector
|
120
|
-
def wakeup
|
121
|
-
raise IOError, "selector is closed" if closed?
|
122
|
-
@java_selector.wakeup
|
123
|
-
nil
|
124
|
-
end
|
125
|
-
|
126
|
-
# Close this selector
|
127
|
-
def close
|
128
|
-
@java_selector.close
|
129
|
-
end
|
130
|
-
|
131
|
-
# Is this selector closed?
|
132
|
-
def closed?
|
133
|
-
!@java_selector.isOpen
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|