nio4r 1.1.0-java → 1.1.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +58 -0
- data/.rubocop_todo.yml +35 -0
- data/.travis.yml +8 -1
- data/CHANGES.md +7 -0
- data/Gemfile +2 -2
- data/Rakefile +1 -1
- data/examples/echo_server.rb +6 -7
- data/ext/libev/Changes +6 -1
- data/ext/libev/ev.c +179 -114
- data/ext/libev/ev.h +14 -7
- data/ext/nio4r/extconf.rb +23 -34
- data/ext/nio4r/selector.c +6 -0
- data/lib/nio.rb +15 -13
- data/lib/nio/monitor.rb +8 -4
- data/lib/nio/selector.rb +11 -11
- data/lib/nio/version.rb +1 -1
- data/nio4r.gemspec +4 -3
- data/spec/nio/acceptables_spec.rb +3 -3
- data/spec/nio/monitor_spec.rb +4 -3
- data/spec/nio/selectables/pipe_spec.rb +5 -5
- data/spec/nio/selectables/ssl_socket_spec.rb +12 -12
- data/spec/nio/selectables/tcp_socket_spec.rb +7 -7
- data/spec/nio/selectables/udp_socket_spec.rb +6 -6
- data/spec/nio/selector_spec.rb +4 -4
- data/spec/spec_helper.rb +7 -5
- data/spec/support/selectable_examples.rb +5 -5
- data/tasks/extension.rake +7 -7
- data/tasks/rspec.rake +2 -2
- data/tasks/rubocop.rake +3 -0
- metadata +23 -6
data/ext/libev/ev.h
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* libev native API header
|
3
3
|
*
|
4
|
-
* Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de>
|
4
|
+
* Copyright (c) 2007,2008,2009,2010,2011,2012,2015 Marc Alexander Lehmann <libev@schmorp.de>
|
5
5
|
* All rights reserved.
|
6
6
|
*
|
7
7
|
* Redistribution and use in source and binary forms, with or without modifica-
|
@@ -42,12 +42,16 @@
|
|
42
42
|
|
43
43
|
#ifdef __cplusplus
|
44
44
|
# define EV_CPP(x) x
|
45
|
+
# if __cplusplus >= 201103L
|
46
|
+
# define EV_THROW noexcept
|
47
|
+
# else
|
48
|
+
# define EV_THROW throw ()
|
49
|
+
# endif
|
45
50
|
#else
|
46
51
|
# define EV_CPP(x)
|
52
|
+
# define EV_THROW
|
47
53
|
#endif
|
48
54
|
|
49
|
-
#define EV_THROW EV_CPP(throw())
|
50
|
-
|
51
55
|
EV_CPP(extern "C" {)
|
52
56
|
|
53
57
|
/*****************************************************************************/
|
@@ -148,6 +152,8 @@ EV_CPP(extern "C" {)
|
|
148
152
|
|
149
153
|
typedef double ev_tstamp;
|
150
154
|
|
155
|
+
#include <string.h> /* for memmove */
|
156
|
+
|
151
157
|
#ifndef EV_ATOMIC_T
|
152
158
|
# include <signal.h>
|
153
159
|
# define EV_ATOMIC_T sig_atomic_t volatile
|
@@ -205,7 +211,7 @@ struct ev_loop;
|
|
205
211
|
/*****************************************************************************/
|
206
212
|
|
207
213
|
#define EV_VERSION_MAJOR 4
|
208
|
-
#define EV_VERSION_MINOR
|
214
|
+
#define EV_VERSION_MINOR 20
|
209
215
|
|
210
216
|
/* eventmask, revents, events... */
|
211
217
|
enum {
|
@@ -660,7 +666,7 @@ EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_THROW;
|
|
660
666
|
EV_API_DECL void *ev_userdata (EV_P) EV_THROW;
|
661
667
|
typedef void (*ev_loop_callback)(EV_P);
|
662
668
|
EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW;
|
663
|
-
/* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out*/
|
669
|
+
/* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out */
|
664
670
|
EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW;
|
665
671
|
|
666
672
|
EV_API_DECL unsigned int ev_pending_count (EV_P) EV_THROW; /* number of pending events, if any */
|
@@ -715,7 +721,8 @@ EV_API_DECL void ev_resume (EV_P) EV_THROW;
|
|
715
721
|
#define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
|
716
722
|
#define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
|
717
723
|
|
718
|
-
#define
|
724
|
+
#define ev_cb_(ev) (ev)->cb /* rw */
|
725
|
+
#define ev_cb(ev) (memmove (&ev_cb_ (ev), &((ev_watcher *)(ev))->cb, sizeof (ev_cb_ (ev))), (ev)->cb)
|
719
726
|
|
720
727
|
#if EV_MINPRI == EV_MAXPRI
|
721
728
|
# define ev_priority(ev) ((ev), EV_MINPRI)
|
@@ -728,7 +735,7 @@ EV_API_DECL void ev_resume (EV_P) EV_THROW;
|
|
728
735
|
#define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at)
|
729
736
|
|
730
737
|
#ifndef ev_set_cb
|
731
|
-
# define ev_set_cb(ev,cb_)
|
738
|
+
# define ev_set_cb(ev,cb_) (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev))))
|
732
739
|
#endif
|
733
740
|
|
734
741
|
/* stopping (enabling, adding) a watcher does nothing if it is already running */
|
data/ext/nio4r/extconf.rb
CHANGED
@@ -1,52 +1,41 @@
|
|
1
|
-
require
|
1
|
+
require "mkmf"
|
2
2
|
|
3
|
-
|
4
|
-
$defs << '-DHAVE_RB_THREAD_BLOCKING_REGION'
|
5
|
-
end
|
3
|
+
have_header("unistd.h")
|
6
4
|
|
7
|
-
if have_func(
|
8
|
-
$defs <<
|
5
|
+
if have_func("rb_thread_blocking_region")
|
6
|
+
$defs << "-DHAVE_RB_THREAD_BLOCKING_REGION"
|
9
7
|
end
|
10
8
|
|
11
|
-
if
|
12
|
-
$defs <<
|
9
|
+
if have_func("rb_thread_call_without_gvl")
|
10
|
+
$defs << "-DHAVE_RB_THEREAD_CALL_WITHOUT_GVL"
|
13
11
|
end
|
14
12
|
|
15
|
-
if have_header(
|
16
|
-
$defs << '-DEV_USE_POLL'
|
17
|
-
end
|
13
|
+
$defs << "-DEV_USE_SELECT" if have_header("sys/select.h")
|
18
14
|
|
19
|
-
if have_header(
|
20
|
-
$defs << '-DEV_USE_EPOLL'
|
21
|
-
end
|
15
|
+
$defs << "-DEV_USE_POLL" if have_header("poll.h")
|
22
16
|
|
23
|
-
|
24
|
-
$defs << '-DEV_USE_KQUEUE'
|
25
|
-
end
|
17
|
+
$defs << "-DEV_USE_EPOLL" if have_header("sys/epoll.h")
|
26
18
|
|
27
|
-
if have_header(
|
28
|
-
$defs <<
|
19
|
+
if have_header("sys/event.h") && have_header("sys/queue.h")
|
20
|
+
$defs << "-DEV_USE_KQUEUE"
|
29
21
|
end
|
30
22
|
|
31
|
-
if have_header(
|
32
|
-
$defs << '-DHAVE_SYS_RESOURCE_H'
|
33
|
-
end
|
23
|
+
$defs << "-DEV_USE_PORT" if have_header("port.h")
|
34
24
|
|
35
|
-
|
36
|
-
|
37
|
-
|
25
|
+
$defs << "-DHAVE_SYS_RESOURCE_H" if have_header("sys/resource.h")
|
26
|
+
|
27
|
+
$defs << "-DHAVE_RUBYSIG_H" if RUBY_VERSION.to_f < 1.9
|
38
28
|
|
39
|
-
dir_config
|
40
|
-
create_makefile
|
29
|
+
dir_config "nio4r_ext"
|
30
|
+
create_makefile "nio4r_ext"
|
41
31
|
|
42
|
-
# win32 needs to link in "just the right order" for some reason or
|
43
|
-
#
|
32
|
+
# win32 needs to link in "just the right order" for some reason or
|
33
|
+
# ioctlsocket will be mapped to an [inverted] ruby specific version.
|
44
34
|
if RUBY_PLATFORM =~ /mingw|win32/
|
45
|
-
makefile_contents = File.read
|
35
|
+
makefile_contents = File.read "Makefile"
|
46
36
|
|
47
|
-
|
48
|
-
makefile_contents.gsub! 'DLDFLAGS = ', 'DLDFLAGS = -export-all '
|
37
|
+
makefile_contents.gsub! "DLDFLAGS = ", "DLDFLAGS = -export-all "
|
49
38
|
|
50
|
-
makefile_contents.gsub!
|
51
|
-
File.open(
|
39
|
+
makefile_contents.gsub! "LIBS = $(LIBRUBYARG_SHARED)", "LIBS = -lws2_32 $(LIBRUBYARG_SHARED)"
|
40
|
+
File.open("Makefile", "w") { |f| f.write makefile_contents }
|
52
41
|
end
|
data/ext/nio4r/selector.c
CHANGED
data/lib/nio.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "thread"
|
2
|
+
require "socket"
|
3
|
+
require "nio/version"
|
4
4
|
|
5
5
|
# New I/O for Ruby
|
6
6
|
module NIO
|
@@ -8,22 +8,24 @@ module NIO
|
|
8
8
|
# * select: in pure Ruby using Kernel.select
|
9
9
|
# * libev: as a C extension using libev
|
10
10
|
# * java: using Java NIO
|
11
|
-
def self.engine
|
11
|
+
def self.engine
|
12
|
+
ENGINE
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
|
-
if ENV["NIO4R_PURE"] || (Gem.win_platform? && !defined?(JRUBY_VERSION))
|
15
|
-
require
|
16
|
-
require
|
17
|
-
NIO::ENGINE =
|
16
|
+
if ENV["NIO4R_PURE"] == "true" || (Gem.win_platform? && !defined?(JRUBY_VERSION))
|
17
|
+
require "nio/monitor"
|
18
|
+
require "nio/selector"
|
19
|
+
NIO::ENGINE = "ruby"
|
18
20
|
else
|
19
|
-
require
|
21
|
+
require "nio4r_ext"
|
20
22
|
|
21
23
|
if defined?(JRUBY_VERSION)
|
22
|
-
require
|
23
|
-
require
|
24
|
+
require "java"
|
25
|
+
require "jruby"
|
24
26
|
org.nio4r.Nio4r.new.load(JRuby.runtime, false)
|
25
|
-
NIO::ENGINE =
|
27
|
+
NIO::ENGINE = "java"
|
26
28
|
else
|
27
|
-
NIO::ENGINE =
|
29
|
+
NIO::ENGINE = "libev"
|
28
30
|
end
|
29
31
|
end
|
data/lib/nio/monitor.rb
CHANGED
@@ -13,11 +13,13 @@ module NIO
|
|
13
13
|
io = io.to_io
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
fail TypeError, "can't convert #{io.class} into IO" unless io.is_a? IO
|
17
17
|
end
|
18
18
|
|
19
|
-
@io
|
20
|
-
@
|
19
|
+
@io = io
|
20
|
+
@interests = interests
|
21
|
+
@selector = selector
|
22
|
+
@closed = false
|
21
23
|
end
|
22
24
|
|
23
25
|
# Is the IO object readable?
|
@@ -32,7 +34,9 @@ module NIO
|
|
32
34
|
alias_method :writeable?, :writable?
|
33
35
|
|
34
36
|
# Is this monitor closed?
|
35
|
-
def closed
|
37
|
+
def closed?
|
38
|
+
@closed
|
39
|
+
end
|
36
40
|
|
37
41
|
# Deactivate this monitor
|
38
42
|
def close(deregister = true)
|
data/lib/nio/selector.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "set"
|
2
2
|
|
3
3
|
module NIO
|
4
4
|
# Selectors monitor IO objects for events of interest
|
@@ -20,13 +20,10 @@ module NIO
|
|
20
20
|
# * :rw - is the IO either readable or writeable?
|
21
21
|
def register(io, interest)
|
22
22
|
@lock.synchronize do
|
23
|
-
if closed?
|
24
|
-
raise IOError, "selector is closed"
|
25
|
-
end
|
23
|
+
fail IOError, "selector is closed" if closed?
|
26
24
|
|
27
|
-
|
28
|
-
|
29
|
-
end
|
25
|
+
monitor = @selectables[io]
|
26
|
+
fail ArgumentError, "already registered as #{monitor.interests.inspect}" if monitor
|
30
27
|
|
31
28
|
monitor = Monitor.new(io, interest, self)
|
32
29
|
@selectables[monitor.io] = monitor
|
@@ -39,20 +36,21 @@ module NIO
|
|
39
36
|
def deregister(io)
|
40
37
|
@lock.synchronize do
|
41
38
|
monitor = @selectables.delete io
|
42
|
-
monitor.close(false) if monitor
|
39
|
+
monitor.close(false) if monitor && !monitor.closed?
|
43
40
|
monitor
|
44
41
|
end
|
45
42
|
end
|
46
43
|
|
47
44
|
# Is the given IO object registered with the selector?
|
48
45
|
def registered?(io)
|
49
|
-
@lock.synchronize { @selectables.
|
46
|
+
@lock.synchronize { @selectables.key? io }
|
50
47
|
end
|
51
48
|
|
52
49
|
# Select which monitors are ready
|
53
50
|
def select(timeout = nil)
|
54
51
|
@lock.synchronize do
|
55
|
-
readers
|
52
|
+
readers = [@wakeup]
|
53
|
+
writers = []
|
56
54
|
|
57
55
|
@selectables.each do |io, monitor|
|
58
56
|
readers << io if monitor.interests == :r || monitor.interests == :rw
|
@@ -124,7 +122,9 @@ module NIO
|
|
124
122
|
end
|
125
123
|
|
126
124
|
# Is this selector closed?
|
127
|
-
def closed
|
125
|
+
def closed?
|
126
|
+
@closed
|
127
|
+
end
|
128
128
|
|
129
129
|
def empty?
|
130
130
|
@selectables.empty?
|
data/lib/nio/version.rb
CHANGED
data/nio4r.gemspec
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path(
|
2
|
+
require File.expand_path("../lib/nio/version", __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
5
|
gem.authors = ["Tony Arcieri"]
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |gem|
|
|
9
9
|
gem.homepage = "https://github.com/celluloid/nio4r"
|
10
10
|
gem.license = "MIT"
|
11
11
|
|
12
|
-
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
13
13
|
gem.files = `git ls-files`.split("\n")
|
14
14
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
15
|
gem.name = "nio4r"
|
@@ -25,5 +25,6 @@ Gem::Specification.new do |gem|
|
|
25
25
|
|
26
26
|
gem.add_development_dependency "rake-compiler"
|
27
27
|
gem.add_development_dependency "rake"
|
28
|
-
gem.add_development_dependency "rspec", "~> 3.0
|
28
|
+
gem.add_development_dependency "rspec", "~> 3.0"
|
29
|
+
gem.add_development_dependency "rubocop"
|
29
30
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
describe "NIO acceptables" do
|
3
|
+
RSpec.describe "NIO acceptables" do
|
4
4
|
shared_context "an NIO acceptable" do
|
5
5
|
let(:selector) { NIO::Selector.new }
|
6
6
|
|
@@ -15,7 +15,7 @@ describe "NIO acceptables" do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
describe TCPServer do
|
18
|
-
let(:tcp_port) {
|
18
|
+
let(:tcp_port) { 23_456 }
|
19
19
|
|
20
20
|
let :acceptable_subject do
|
21
21
|
server = TCPServer.new("localhost", tcp_port)
|
data/spec/nio/monitor_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
describe NIO::Monitor do
|
3
|
+
RSpec.describe NIO::Monitor do
|
4
4
|
let(:pipes) { IO.pipe }
|
5
5
|
let(:reader) { pipes.first }
|
6
6
|
let(:writer) { pipes.last }
|
@@ -30,7 +30,8 @@ describe NIO::Monitor do
|
|
30
30
|
|
31
31
|
it "knows what operations IO objects are ready for" do
|
32
32
|
# For whatever odd reason this breaks unless we eagerly evaluate subject
|
33
|
-
reader_monitor
|
33
|
+
reader_monitor = subject
|
34
|
+
writer_monitor = peer
|
34
35
|
|
35
36
|
selected = selector.select(0)
|
36
37
|
expect(selected).not_to include(reader_monitor)
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
|
-
describe "IO.pipe" do
|
3
|
+
RSpec.describe "IO.pipe" do
|
4
4
|
let(:pair) { IO.pipe }
|
5
5
|
|
6
6
|
let :unreadable_subject do
|
@@ -18,17 +18,17 @@ describe "IO.pipe" do
|
|
18
18
|
let :unwritable_subject do
|
19
19
|
reader, pipe = IO.pipe
|
20
20
|
|
21
|
-
#HACK: On OS X 10.8, this str must be larger than PIPE_BUF. Otherwise,
|
21
|
+
# HACK: On OS X 10.8, this str must be larger than PIPE_BUF. Otherwise,
|
22
22
|
# the write is atomic and select() will return writable but write()
|
23
23
|
# will throw EAGAIN if there is too little space to write the string
|
24
24
|
# TODO: Use FFI to lookup the platform-specific size of PIPE_BUF
|
25
|
-
str = "JUNK IN THE TUBES" *
|
25
|
+
str = "JUNK IN THE TUBES" * 10_000
|
26
26
|
begin
|
27
27
|
pipe.write_nonblock str
|
28
28
|
_, writers = select [], [pipe], [], 0
|
29
29
|
rescue Errno::EPIPE
|
30
30
|
break
|
31
|
-
end while writers
|
31
|
+
end while writers && writers.include?(pipe)
|
32
32
|
|
33
33
|
pipe
|
34
34
|
end
|
@@ -1,20 +1,20 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "spec_helper"
|
2
|
+
require "openssl"
|
3
3
|
|
4
|
-
describe OpenSSL::SSL::SSLSocket, :
|
5
|
-
let(:tcp_port) {
|
4
|
+
RSpec.describe OpenSSL::SSL::SSLSocket, if: RUBY_VERSION >= "1.9.0" do
|
5
|
+
let(:tcp_port) { 34_567 }
|
6
6
|
|
7
7
|
let(:ssl_key) { OpenSSL::PKey::RSA.new(1024) }
|
8
8
|
|
9
9
|
let(:ssl_cert) do
|
10
|
-
name = OpenSSL::X509::Name.new([%w
|
10
|
+
name = OpenSSL::X509::Name.new([%w(CN localhost)])
|
11
11
|
OpenSSL::X509::Certificate.new.tap do |cert|
|
12
12
|
cert.version = 2
|
13
13
|
cert.serial = 1
|
14
14
|
cert.issuer = name
|
15
15
|
cert.subject = name
|
16
16
|
cert.not_before = Time.now
|
17
|
-
cert.not_after = Time.now + (365 * 24 *60 *60)
|
17
|
+
cert.not_after = Time.now + (365 * 24 * 60 * 60)
|
18
18
|
cert.public_key = ssl_key.public_key
|
19
19
|
|
20
20
|
cert.sign(ssl_key, OpenSSL::Digest::SHA1.new)
|
@@ -114,8 +114,8 @@ describe OpenSSL::SSL::SSLSocket, :if => RUBY_VERSION >= "1.9.0" do
|
|
114
114
|
expect(count).not_to eq(0)
|
115
115
|
rescue IO::WaitReadable, IO::WaitWritable
|
116
116
|
pending "SSL will report writable but not accept writes"
|
117
|
-
raise if
|
118
|
-
end while writers
|
117
|
+
raise if writers.include? ssl_client
|
118
|
+
end while writers && writers.include?(ssl_client)
|
119
119
|
|
120
120
|
# I think the kernel might manage to drain its buffer a bit even after
|
121
121
|
# the socket first goes unwritable. Attempt to sleep past this and then
|
@@ -124,15 +124,15 @@ describe OpenSSL::SSL::SSLSocket, :if => RUBY_VERSION >= "1.9.0" do
|
|
124
124
|
|
125
125
|
# Once more for good measure!
|
126
126
|
begin
|
127
|
-
# ssl_client.write_nonblock "X" * 1024
|
127
|
+
# ssl_client.write_nonblock "X" * 1024
|
128
128
|
loop { ssl_client.write_nonblock "X" * 1024 }
|
129
129
|
rescue OpenSSL::SSL::SSLError
|
130
130
|
end
|
131
131
|
|
132
132
|
# Sanity check to make sure we actually produced an unwritable socket
|
133
|
-
# if select([], [ssl_client], [], 0)
|
134
|
-
# pending "Failed to produce an unwritable socket"
|
135
|
-
# end
|
133
|
+
# if select([], [ssl_client], [], 0)
|
134
|
+
# pending "Failed to produce an unwritable socket"
|
135
|
+
# end
|
136
136
|
|
137
137
|
ssl_client
|
138
138
|
end
|