nio4r 0.1.0-java
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/.gitignore +20 -0
- data/.rspec +4 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +20 -0
- data/README.md +123 -0
- data/Rakefile +9 -0
- data/ext/libev/Changes +388 -0
- data/ext/libev/LICENSE +36 -0
- data/ext/libev/README +58 -0
- data/ext/libev/README.embed +3 -0
- data/ext/libev/ev.c +3913 -0
- data/ext/libev/ev.h +829 -0
- data/ext/libev/ev_epoll.c +266 -0
- data/ext/libev/ev_kqueue.c +198 -0
- data/ext/libev/ev_poll.c +148 -0
- data/ext/libev/ev_port.c +179 -0
- data/ext/libev/ev_select.c +310 -0
- data/ext/libev/ev_vars.h +203 -0
- data/ext/libev/ev_win32.c +153 -0
- data/ext/libev/ev_wrap.h +196 -0
- data/ext/libev/test_libev_win32.c +123 -0
- data/ext/nio4r/extconf.rb +44 -0
- data/ext/nio4r/libev.h +8 -0
- data/ext/nio4r/monitor.c +164 -0
- data/ext/nio4r/nio4r.h +53 -0
- data/ext/nio4r/nio4r_ext.c +16 -0
- data/ext/nio4r/selector.c +370 -0
- data/lib/nio/jruby/monitor.rb +26 -0
- data/lib/nio/jruby/selector.rb +110 -0
- data/lib/nio/monitor.rb +21 -0
- data/lib/nio/selector.rb +101 -0
- data/lib/nio/version.rb +3 -0
- data/lib/nio.rb +30 -0
- data/nio4r.gemspec +23 -0
- data/spec/nio/monitor_spec.rb +36 -0
- data/spec/nio/selector_spec.rb +197 -0
- data/spec/spec_helper.rb +3 -0
- data/tasks/extension.rake +10 -0
- data/tasks/rspec.rake +7 -0
- metadata +121 -0
data/lib/nio.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'nio/version'
|
3
|
+
|
4
|
+
# New I/O for Ruby
|
5
|
+
module NIO
|
6
|
+
# NIO implementation, one of the following (as a string):
|
7
|
+
# * select: in pure Ruby using Kernel.select
|
8
|
+
# * libev: as a C extension using libev
|
9
|
+
# * java: using Java NIO
|
10
|
+
def self.engine; ENGINE end
|
11
|
+
end
|
12
|
+
|
13
|
+
if ENV["NIO4R_PURE"]
|
14
|
+
require 'nio/monitor'
|
15
|
+
require 'nio/selector'
|
16
|
+
NIO::ENGINE = 'select'
|
17
|
+
else
|
18
|
+
if defined?(JRUBY_VERSION)
|
19
|
+
require 'java'
|
20
|
+
require 'nio/jruby/monitor'
|
21
|
+
require 'nio/jruby/selector'
|
22
|
+
NIO::ENGINE = 'java'
|
23
|
+
else
|
24
|
+
require 'nio4r_ext'
|
25
|
+
NIO::ENGINE = 'libev'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# TIMTOWTDI!!!
|
30
|
+
Nio = NIO
|
data/nio4r.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/nio/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Tony Arcieri"]
|
6
|
+
gem.email = ["tony.arcieri@gmail.com"]
|
7
|
+
gem.description = "New IO for Ruby"
|
8
|
+
gem.summary = "NIO provides a high performance selector API for monitoring IO objects"
|
9
|
+
gem.homepage = "https://github.com/tarcieri/nio4r"
|
10
|
+
gem.platform = "java"
|
11
|
+
|
12
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
13
|
+
gem.files = `git ls-files`.split("\n")
|
14
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
gem.name = "nio4r"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = NIO::VERSION
|
18
|
+
#gem.extensions = ["ext/nio4r/extconf.rb"]
|
19
|
+
|
20
|
+
gem.add_development_dependency "rake-compiler", "~> 0.7.9"
|
21
|
+
gem.add_development_dependency "rake"
|
22
|
+
gem.add_development_dependency "rspec", ">= 2.7.0"
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NIO::Monitor do
|
4
|
+
let :readable_pipe do
|
5
|
+
pipe, peer = IO.pipe
|
6
|
+
peer << "data"
|
7
|
+
pipe
|
8
|
+
end
|
9
|
+
|
10
|
+
# let :unreadable_pipe do
|
11
|
+
# pipe, _ = IO.pipe
|
12
|
+
# pipe
|
13
|
+
# end
|
14
|
+
|
15
|
+
let :selector do
|
16
|
+
NIO::Selector.new
|
17
|
+
end
|
18
|
+
|
19
|
+
# Monitors are created by registering IO objects or channels with a selector
|
20
|
+
subject { selector.register(readable_pipe, :r) }
|
21
|
+
|
22
|
+
it "knows its interests" do
|
23
|
+
subject.interests.should == :r
|
24
|
+
end
|
25
|
+
|
26
|
+
it "stores arbitrary values" do
|
27
|
+
subject.value = 42
|
28
|
+
subject.value.should == 42
|
29
|
+
end
|
30
|
+
|
31
|
+
it "closes" do
|
32
|
+
subject.should_not be_closed
|
33
|
+
subject.close
|
34
|
+
subject.should be_closed
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Timeouts should be at least this precise (in seconds) to pass the tests
|
4
|
+
# Typical precision should be better than this, but if it's worse it will fail
|
5
|
+
# the tests
|
6
|
+
TIMEOUT_PRECISION = 0.1
|
7
|
+
|
8
|
+
describe NIO::Selector do
|
9
|
+
it "monitors IO objects" do
|
10
|
+
pipe, _ = IO.pipe
|
11
|
+
|
12
|
+
monitor = subject.register(pipe, :r)
|
13
|
+
monitor.should_not be_closed
|
14
|
+
end
|
15
|
+
|
16
|
+
it "knows which IO objects are registered" do
|
17
|
+
reader, writer = IO.pipe
|
18
|
+
subject.register(reader, :r)
|
19
|
+
|
20
|
+
subject.should be_registered(reader)
|
21
|
+
subject.should_not be_registered(writer)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "deregisters IO objects" do
|
25
|
+
pipe, _ = IO.pipe
|
26
|
+
|
27
|
+
subject.register(pipe, :r)
|
28
|
+
monitor = subject.deregister(pipe)
|
29
|
+
subject.should_not be_registered(pipe)
|
30
|
+
monitor.should be_closed
|
31
|
+
end
|
32
|
+
|
33
|
+
context "select" do
|
34
|
+
it "waits for a timeout when selecting" do
|
35
|
+
reader, writer = IO.pipe
|
36
|
+
monitor = subject.register(reader, :r)
|
37
|
+
|
38
|
+
payload = "hi there"
|
39
|
+
writer << payload
|
40
|
+
|
41
|
+
timeout = 0.5
|
42
|
+
started_at = Time.now
|
43
|
+
subject.select(timeout).should include monitor
|
44
|
+
(Time.now - started_at).should be_within(TIMEOUT_PRECISION).of(0)
|
45
|
+
reader.read_nonblock(payload.size)
|
46
|
+
|
47
|
+
started_at = Time.now
|
48
|
+
subject.select(timeout).should be_nil
|
49
|
+
(Time.now - started_at).should be_within(TIMEOUT_PRECISION).of(timeout)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "wakes up if signaled to from another thread" do
|
53
|
+
pipe, _ = IO.pipe
|
54
|
+
subject.register(pipe, :r)
|
55
|
+
|
56
|
+
thread = Thread.new do
|
57
|
+
started_at = Time.now
|
58
|
+
subject.select.should be_nil
|
59
|
+
Time.now - started_at
|
60
|
+
end
|
61
|
+
|
62
|
+
timeout = 0.1
|
63
|
+
sleep timeout
|
64
|
+
subject.wakeup
|
65
|
+
|
66
|
+
thread.value.should be_within(TIMEOUT_PRECISION).of(timeout)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "closes" do
|
71
|
+
subject.close
|
72
|
+
subject.should be_closed
|
73
|
+
end
|
74
|
+
|
75
|
+
context "selectables" do
|
76
|
+
shared_context "an NIO selectable" do
|
77
|
+
it "selects for read readiness" do
|
78
|
+
waiting_monitor = subject.register(unreadable_subject, :r)
|
79
|
+
ready_monitor = subject.register(readable_subject, :r)
|
80
|
+
|
81
|
+
ready_monitors = subject.select
|
82
|
+
ready_monitors.should include ready_monitor
|
83
|
+
ready_monitors.should_not include waiting_monitor
|
84
|
+
end
|
85
|
+
|
86
|
+
it "selects for write readiness" do
|
87
|
+
waiting_monitor = subject.register(unwritable_subject, :w)
|
88
|
+
ready_monitor = subject.register(writable_subject, :w)
|
89
|
+
|
90
|
+
ready_monitors = subject.select(0.1)
|
91
|
+
|
92
|
+
ready_monitors.should include ready_monitor
|
93
|
+
ready_monitors.should_not include waiting_monitor
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "IO.pipe" do
|
98
|
+
let :readable_subject do
|
99
|
+
pipe, peer = IO.pipe
|
100
|
+
peer << "data"
|
101
|
+
pipe
|
102
|
+
end
|
103
|
+
|
104
|
+
let :unreadable_subject do
|
105
|
+
pipe, _ = IO.pipe
|
106
|
+
pipe
|
107
|
+
end
|
108
|
+
|
109
|
+
let :writable_subject do
|
110
|
+
_, pipe = IO.pipe
|
111
|
+
pipe
|
112
|
+
end
|
113
|
+
|
114
|
+
let :unwritable_subject do
|
115
|
+
reader, pipe = IO.pipe
|
116
|
+
|
117
|
+
begin
|
118
|
+
pipe.write_nonblock "JUNK IN THE TUBES"
|
119
|
+
_, writers = select [], [pipe], [], 0
|
120
|
+
rescue Errno::EPIPE
|
121
|
+
break
|
122
|
+
end while writers and writers.include? pipe
|
123
|
+
|
124
|
+
pipe
|
125
|
+
end
|
126
|
+
|
127
|
+
it_behaves_like "an NIO selectable"
|
128
|
+
end
|
129
|
+
|
130
|
+
context TCPSocket do
|
131
|
+
let(:tcp_port) { 12345 }
|
132
|
+
|
133
|
+
let :readable_subject do
|
134
|
+
server = TCPServer.new("localhost", tcp_port)
|
135
|
+
sock = TCPSocket.open("localhost", tcp_port)
|
136
|
+
peer = server.accept
|
137
|
+
peer << "data"
|
138
|
+
sock
|
139
|
+
end
|
140
|
+
|
141
|
+
let :unreadable_subject do
|
142
|
+
TCPServer.new("localhost", tcp_port + 1)
|
143
|
+
TCPSocket.open("localhost", tcp_port + 1)
|
144
|
+
end
|
145
|
+
|
146
|
+
let :writable_subject do
|
147
|
+
TCPServer.new("localhost", tcp_port + 2)
|
148
|
+
TCPSocket.open("localhost", tcp_port + 2)
|
149
|
+
end
|
150
|
+
|
151
|
+
let :unwritable_subject do
|
152
|
+
server = TCPServer.new("localhost", tcp_port + 3)
|
153
|
+
sock = TCPSocket.open("localhost", tcp_port + 3)
|
154
|
+
peer = server.accept
|
155
|
+
|
156
|
+
begin
|
157
|
+
sock.write_nonblock "JUNK IN THE TUBES"
|
158
|
+
_, writers = select [], [sock], [], 0
|
159
|
+
end while writers and writers.include? sock
|
160
|
+
|
161
|
+
sock
|
162
|
+
end
|
163
|
+
|
164
|
+
it_behaves_like "an NIO selectable"
|
165
|
+
end
|
166
|
+
|
167
|
+
context UDPSocket do
|
168
|
+
let(:udp_port) { 23456 }
|
169
|
+
|
170
|
+
let :readable_subject do
|
171
|
+
sock = UDPSocket.new
|
172
|
+
sock.bind('localhost', udp_port)
|
173
|
+
|
174
|
+
peer = UDPSocket.new
|
175
|
+
peer.send("hi there", 0, 'localhost', udp_port)
|
176
|
+
|
177
|
+
sock
|
178
|
+
end
|
179
|
+
|
180
|
+
let :unreadable_subject do
|
181
|
+
sock = UDPSocket.new
|
182
|
+
sock.bind('localhost', udp_port + 1)
|
183
|
+
sock
|
184
|
+
end
|
185
|
+
|
186
|
+
let :writable_subject do
|
187
|
+
pending "come up with a writable UDPSocket example"
|
188
|
+
end
|
189
|
+
|
190
|
+
let :unwritable_subject do
|
191
|
+
pending "come up with a UDPSocket that's blocked on writing"
|
192
|
+
end
|
193
|
+
|
194
|
+
it_behaves_like "an NIO selectable"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/tasks/rspec.rake
ADDED
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nio4r
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: java
|
7
|
+
authors:
|
8
|
+
- Tony Arcieri
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-26 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake-compiler
|
16
|
+
requirement: &70326293926580 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.7.9
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70326293926580
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70326293925820 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70326293925820
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70326293924680 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.7.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70326293924680
|
47
|
+
description: New IO for Ruby
|
48
|
+
email:
|
49
|
+
- tony.arcieri@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- .rspec
|
56
|
+
- .travis.yml
|
57
|
+
- Gemfile
|
58
|
+
- LICENSE.txt
|
59
|
+
- README.md
|
60
|
+
- Rakefile
|
61
|
+
- ext/libev/Changes
|
62
|
+
- ext/libev/LICENSE
|
63
|
+
- ext/libev/README
|
64
|
+
- ext/libev/README.embed
|
65
|
+
- ext/libev/ev.c
|
66
|
+
- ext/libev/ev.h
|
67
|
+
- ext/libev/ev_epoll.c
|
68
|
+
- ext/libev/ev_kqueue.c
|
69
|
+
- ext/libev/ev_poll.c
|
70
|
+
- ext/libev/ev_port.c
|
71
|
+
- ext/libev/ev_select.c
|
72
|
+
- ext/libev/ev_vars.h
|
73
|
+
- ext/libev/ev_win32.c
|
74
|
+
- ext/libev/ev_wrap.h
|
75
|
+
- ext/libev/test_libev_win32.c
|
76
|
+
- ext/nio4r/extconf.rb
|
77
|
+
- ext/nio4r/libev.h
|
78
|
+
- ext/nio4r/monitor.c
|
79
|
+
- ext/nio4r/nio4r.h
|
80
|
+
- ext/nio4r/nio4r_ext.c
|
81
|
+
- ext/nio4r/selector.c
|
82
|
+
- lib/nio.rb
|
83
|
+
- lib/nio/jruby/monitor.rb
|
84
|
+
- lib/nio/jruby/selector.rb
|
85
|
+
- lib/nio/monitor.rb
|
86
|
+
- lib/nio/selector.rb
|
87
|
+
- lib/nio/version.rb
|
88
|
+
- nio4r.gemspec
|
89
|
+
- spec/nio/monitor_spec.rb
|
90
|
+
- spec/nio/selector_spec.rb
|
91
|
+
- spec/spec_helper.rb
|
92
|
+
- tasks/extension.rake
|
93
|
+
- tasks/rspec.rake
|
94
|
+
homepage: https://github.com/tarcieri/nio4r
|
95
|
+
licenses: []
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
require_paths:
|
99
|
+
- lib
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 1.8.10
|
115
|
+
signing_key:
|
116
|
+
specification_version: 3
|
117
|
+
summary: NIO provides a high performance selector API for monitoring IO objects
|
118
|
+
test_files:
|
119
|
+
- spec/nio/monitor_spec.rb
|
120
|
+
- spec/nio/selector_spec.rb
|
121
|
+
- spec/spec_helper.rb
|