nio4r 1.2.1 → 2.5.3

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.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/workflow.yml +43 -0
  3. data/.gitignore +1 -0
  4. data/.rspec +0 -1
  5. data/.rubocop.yml +70 -31
  6. data/CHANGES.md +190 -42
  7. data/Gemfile +8 -4
  8. data/Guardfile +10 -0
  9. data/README.md +102 -147
  10. data/Rakefile +3 -4
  11. data/examples/echo_server.rb +3 -2
  12. data/ext/libev/Changes +44 -13
  13. data/ext/libev/README +2 -1
  14. data/ext/libev/ev.c +314 -225
  15. data/ext/libev/ev.h +90 -88
  16. data/ext/libev/ev_epoll.c +30 -16
  17. data/ext/libev/ev_kqueue.c +19 -9
  18. data/ext/libev/ev_linuxaio.c +642 -0
  19. data/ext/libev/ev_poll.c +19 -11
  20. data/ext/libev/ev_port.c +13 -6
  21. data/ext/libev/ev_select.c +4 -2
  22. data/ext/libev/ev_vars.h +14 -3
  23. data/ext/libev/ev_wrap.h +16 -0
  24. data/ext/nio4r/bytebuffer.c +429 -0
  25. data/ext/nio4r/extconf.rb +17 -30
  26. data/ext/nio4r/monitor.c +113 -49
  27. data/ext/nio4r/nio4r.h +11 -13
  28. data/ext/nio4r/org/nio4r/ByteBuffer.java +293 -0
  29. data/ext/nio4r/org/nio4r/Monitor.java +175 -0
  30. data/ext/nio4r/org/nio4r/Nio4r.java +22 -391
  31. data/ext/nio4r/org/nio4r/Selector.java +299 -0
  32. data/ext/nio4r/selector.c +155 -68
  33. data/lib/nio.rb +4 -4
  34. data/lib/nio/bytebuffer.rb +229 -0
  35. data/lib/nio/monitor.rb +73 -11
  36. data/lib/nio/selector.rb +64 -21
  37. data/lib/nio/version.rb +1 -1
  38. data/nio4r.gemspec +34 -20
  39. data/{tasks → rakelib}/extension.rake +4 -0
  40. data/{tasks → rakelib}/rspec.rake +2 -0
  41. data/{tasks → rakelib}/rubocop.rake +2 -0
  42. data/spec/nio/acceptables_spec.rb +5 -5
  43. data/spec/nio/bytebuffer_spec.rb +354 -0
  44. data/spec/nio/monitor_spec.rb +128 -79
  45. data/spec/nio/selectables/pipe_spec.rb +12 -3
  46. data/spec/nio/selectables/ssl_socket_spec.rb +61 -29
  47. data/spec/nio/selectables/tcp_socket_spec.rb +47 -34
  48. data/spec/nio/selectables/udp_socket_spec.rb +24 -7
  49. data/spec/nio/selector_spec.rb +65 -16
  50. data/spec/spec_helper.rb +12 -3
  51. data/spec/support/selectable_examples.rb +45 -18
  52. metadata +33 -23
  53. data/.rubocop_todo.yml +0 -35
  54. data/.travis.yml +0 -27
  55. data/LICENSE.txt +0 -20
  56. data/ext/libev/README.embed +0 -3
  57. data/ext/libev/test_libev_win32.c +0 -123
@@ -1,45 +1,52 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
5
  RSpec.describe TCPSocket do
4
- port_offset = 0
5
- let(:tcp_port) { 12_345 + (port_offset += 1) }
6
+ let(:addr) { "127.0.0.1" }
6
7
 
7
8
  let :readable_subject do
8
- server = TCPServer.new("localhost", tcp_port)
9
- sock = TCPSocket.open("localhost", tcp_port)
9
+ server = TCPServer.new(addr, 0)
10
+ sock = TCPSocket.new(addr, server.local_address.ip_port)
10
11
  peer = server.accept
11
- peer << "data"
12
+
13
+ peer << "Xdata"
14
+ peer.flush
15
+ sock.read(1)
16
+
12
17
  sock
13
18
  end
14
19
 
15
20
  let :unreadable_subject do
16
- TCPServer.new("localhost", tcp_port)
17
- sock = TCPSocket.new("localhost", tcp_port)
21
+ server = TCPServer.new(addr, 0)
22
+ sock = TCPSocket.new(addr, server.local_address.ip_port)
18
23
 
19
24
  # Sanity check to make sure we actually produced an unreadable socket
20
- if select([sock], [], [], 0)
21
- pending "Failed to produce an unreadable socket"
22
- end
25
+ pending "Failed to produce an unreadable socket" if select([sock], [], [], 0)
23
26
 
24
27
  sock
25
28
  end
26
29
 
27
30
  let :writable_subject do
28
- TCPServer.new("localhost", tcp_port)
29
- TCPSocket.new("localhost", tcp_port)
31
+ server = TCPServer.new(addr, 0)
32
+ TCPSocket.new(addr, server.local_address.ip_port)
30
33
  end
31
34
 
32
35
  let :unwritable_subject do
33
- server = TCPServer.new("localhost", tcp_port)
34
- sock = TCPSocket.open("localhost", tcp_port)
35
- peer = server.accept
36
+ server = TCPServer.new(addr, 0)
37
+ sock = TCPSocket.new(addr, server.local_address.ip_port)
36
38
 
37
- begin
39
+ # TODO: close this socket
40
+ _peer = server.accept
41
+
42
+ loop do
38
43
  sock.write_nonblock "X" * 1024
39
- _, writers = select [], [sock], [], 0
40
- end while writers && writers.include?(sock)
44
+ _, writers = Kernel.select([], [sock], [], 0)
45
+
46
+ break unless writers && writers.include?(sock)
47
+ end
41
48
 
42
- # I think the kernel might manage to drain its buffer a bit even after
49
+ # HAX: I think the kernel might manage to drain its buffer a bit even after
43
50
  # the socket first goes unwritable. Attempt to sleep past this and then
44
51
  # attempt to write again
45
52
  sleep 0.1
@@ -51,16 +58,14 @@ RSpec.describe TCPSocket do
51
58
  end
52
59
 
53
60
  # Sanity check to make sure we actually produced an unwritable socket
54
- if select([], [sock], [], 0)
55
- pending "Failed to produce an unwritable socket"
56
- end
61
+ pending "Failed to produce an unwritable socket" if select([], [sock], [], 0)
57
62
 
58
63
  sock
59
64
  end
60
65
 
61
66
  let :pair do
62
- server = TCPServer.new("localhost", tcp_port)
63
- client = TCPSocket.open("localhost", tcp_port)
67
+ server = TCPServer.new(addr, 0)
68
+ client = TCPSocket.new(addr, server.local_address.ip_port)
64
69
  [client, server.accept]
65
70
  end
66
71
 
@@ -69,20 +74,28 @@ RSpec.describe TCPSocket do
69
74
  it_behaves_like "an NIO bidirectional stream"
70
75
 
71
76
  context :connect do
77
+ include_context NIO::Selector
78
+
72
79
  it "selects writable when connected" do
73
- selector = NIO::Selector.new
74
- server = TCPServer.new("127.0.0.1", tcp_port)
80
+ begin
81
+ server = TCPServer.new(addr, 0)
82
+
83
+ client = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
84
+ monitor = selector.register(client, :w)
75
85
 
76
- client = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
77
- monitor = selector.register(client, :w)
86
+ expect do
87
+ client.connect_nonblock server.local_address
88
+ end.to raise_exception Errno::EINPROGRESS
78
89
 
79
- expect do
80
- client.connect_nonblock Socket.sockaddr_in(tcp_port, "127.0.0.1")
81
- end.to raise_exception Errno::EINPROGRESS
90
+ ready = selector.select(1)
82
91
 
83
- expect(selector.select(0.001)).to include monitor
84
- result = client.getsockopt(::Socket::SOL_SOCKET, ::Socket::SO_ERROR)
85
- expect(result.unpack("i").first).to be_zero
92
+ expect(ready).to include monitor
93
+ result = client.getsockopt(::Socket::SOL_SOCKET, ::Socket::SO_ERROR)
94
+ expect(result.unpack("i").first).to be_zero
95
+ ensure
96
+ server.close rescue nil
97
+ selector.close rescue nil
98
+ end
86
99
  end
87
100
  end
88
101
  end
@@ -1,26 +1,43 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
 
3
- RSpec.describe UDPSocket do
5
+ RSpec.describe UDPSocket, if: !defined?(JRUBY_VERSION) do
4
6
  let(:udp_port) { 23_456 }
5
7
 
6
8
  let :readable_subject do
7
- sock = UDPSocket.new
8
- sock.bind("localhost", udp_port)
9
+ server = UDPSocket.new
10
+ server.bind("127.0.0.1", 0)
9
11
 
10
12
  peer = UDPSocket.new
11
- peer.send("hi there", 0, "localhost", udp_port)
13
+ peer.send("hi there", 0, "127.0.0.1", server.local_address.ip_port)
12
14
 
13
- sock
15
+ server
14
16
  end
15
17
 
16
18
  let :unreadable_subject do
17
19
  sock = UDPSocket.new
18
- sock.bind("localhost", udp_port + 1)
20
+ sock.bind("127.0.0.1", 0)
19
21
  sock
20
22
  end
21
23
 
22
24
  let :writable_subject do
23
- pending "come up with a writable UDPSocket example"
25
+ server = UDPSocket.new
26
+ server.bind("127.0.0.1", 0)
27
+
28
+ peer = UDPSocket.new
29
+ peer.connect("127.0.0.1", server.local_address.ip_port)
30
+
31
+ cntr = 0
32
+ begin
33
+ peer.send("X" * 1024, 0)
34
+ cntr += 1
35
+ t = select [], [peer], [], 0
36
+ rescue Errno::ECONNREFUSED => e
37
+ skip "Couldn't make writable UDPSocket subject: #{e.class}: #{e}"
38
+ end while t && t[1].include?(peer) && cntr < 5
39
+
40
+ peer
24
41
  end
25
42
 
26
43
  let :unwritable_subject do
@@ -1,16 +1,46 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "spec_helper"
2
4
  require "timeout"
3
5
 
4
- # Timeouts should be at least this precise (in seconds) to pass the tests
5
- # Typical precision should be better than this, but if it's worse it will fail
6
- # the tests
7
- TIMEOUT_PRECISION = 0.1
8
-
9
6
  RSpec.describe NIO::Selector do
10
7
  let(:pair) { IO.pipe }
11
8
  let(:reader) { pair.first }
12
9
  let(:writer) { pair.last }
13
10
 
11
+ context ".backends" do
12
+ it "knows all supported backends" do
13
+ expect(described_class.backends).to be_a Array
14
+ expect(described_class.backends.first).to be_a Symbol
15
+ end
16
+ end
17
+
18
+ context "#initialize" do
19
+ it "allows explicitly specifying a backend" do |example|
20
+ backend = described_class.backends.first
21
+ selector = described_class.new(backend)
22
+ expect(selector.backend).to eq backend
23
+
24
+ example.reporter.message "Supported backends: #{described_class.backends}"
25
+ end
26
+
27
+ it "raises ArgumentError if given an invalid backend" do
28
+ expect { described_class.new(:derp) }.to raise_error ArgumentError
29
+ end
30
+
31
+ it "raises TypeError if given a non-Symbol parameter" do
32
+ expect { described_class.new(42).to raise_error TypeError }
33
+ end
34
+ end
35
+
36
+ context "backend" do
37
+ it "knows its backend" do |example|
38
+ expect(subject.backend).to be_a Symbol
39
+
40
+ example.reporter.message "Current backend: #{subject.backend}"
41
+ end
42
+ end
43
+
14
44
  context "register" do
15
45
  it "registers IO objects" do
16
46
  monitor = subject.register(reader, :r)
@@ -41,11 +71,18 @@ RSpec.describe NIO::Selector do
41
71
  expect(monitor).to be_closed
42
72
  end
43
73
 
44
- it "reports if it is empty" do
45
- expect(subject).to be_empty
74
+ it "allows deregistering closed IO objects" do
75
+ subject.register(reader, :r)
76
+ reader.close
46
77
 
47
- monitor = subject.register(reader, :r)
78
+ expect do
79
+ subject.deregister(reader)
80
+ end.not_to raise_error
81
+ end
48
82
 
83
+ it "reports if it is empty" do
84
+ expect(subject).to be_empty
85
+ subject.register(reader, :r)
49
86
  expect(subject).not_to be_empty
50
87
  end
51
88
 
@@ -66,37 +103,49 @@ RSpec.describe NIO::Selector do
66
103
  end
67
104
 
68
105
  context "timeouts" do
69
- it "waits for a timeout when selecting" do
106
+ let(:select_precision) {0.2}
107
+ let(:timeout) {2.0}
108
+ let(:payload) {"hi there"}
109
+
110
+ it "waits for timeout when selecting from empty selector" do
111
+ started_at = Time.now
112
+ expect(subject.select(timeout)).to be_nil
113
+ expect(Time.now - started_at).to be_within(select_precision).of(timeout)
114
+ end
115
+
116
+ it "waits for a timeout when selecting with reader" do
70
117
  monitor = subject.register(reader, :r)
71
118
 
72
- payload = "hi there"
73
119
  writer << payload
74
120
 
75
- timeout = 0.5
76
121
  started_at = Time.now
77
122
  expect(subject.select(timeout)).to include monitor
78
- expect(Time.now - started_at).to be_within(TIMEOUT_PRECISION).of(0)
123
+ expect(Time.now - started_at).to be_within(select_precision).of(0)
79
124
  reader.read_nonblock(payload.size)
80
125
 
81
126
  started_at = Time.now
82
127
  expect(subject.select(timeout)).to be_nil
83
- expect(Time.now - started_at).to be_within(TIMEOUT_PRECISION).of(timeout)
128
+ expect(Time.now - started_at).to be_within(select_precision).of(timeout)
84
129
  end
85
130
 
86
131
  it "raises ArgumentError if given a negative timeout" do
87
132
  subject.register(reader, :r)
88
133
 
89
- expect { subject.select(-1) }.to raise_exception(ArgumentError)
134
+ expect do
135
+ subject.select(-1)
136
+ end.to raise_exception(ArgumentError)
90
137
  end
91
138
  end
92
139
 
93
140
  context "wakeup" do
141
+ let(:select_precision) {0.2}
142
+
94
143
  it "wakes up if signaled to from another thread" do
95
144
  subject.register(reader, :r)
96
145
 
97
146
  thread = Thread.new do
98
147
  started_at = Time.now
99
- expect(subject.select).to be_nil
148
+ expect(subject.select).to eq []
100
149
  Time.now - started_at
101
150
  end
102
151
 
@@ -104,7 +153,7 @@ RSpec.describe NIO::Selector do
104
153
  sleep timeout
105
154
  subject.wakeup
106
155
 
107
- expect(thread.value).to be_within(TIMEOUT_PRECISION).of(timeout)
156
+ expect(thread.value).to be_within(select_precision).of(timeout)
108
157
  end
109
158
 
110
159
  it "raises IOError if asked to wake up a closed selector" do
@@ -1,9 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "coveralls"
2
4
  Coveralls.wear!
3
5
 
4
- require "rubygems"
5
- require "bundler/setup"
6
6
  require "nio"
7
7
  require "support/selectable_examples"
8
8
 
9
- RSpec.configure(&:disable_monkey_patching!)
9
+ RSpec.configure do |config|
10
+ config.disable_monkey_patching!
11
+
12
+ # Enable flags like --only-failures and --next-failure
13
+ config.example_status_persistence_file_path = ".rspec_status"
14
+
15
+ config.expect_with :rspec do |c|
16
+ c.syntax = :expect
17
+ end
18
+ end
@@ -1,42 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_context NIO::Selector do
4
+ let(:selector) {@selector = NIO::Selector.new}
5
+
6
+ after(:each) do
7
+ if defined?(@selector)
8
+ @selector.close
9
+ end
10
+ end
11
+ end
12
+
1
13
  RSpec.shared_context "an NIO selectable" do
2
- let(:selector) { NIO::Selector.new }
14
+ include_context NIO::Selector
3
15
 
4
16
  it "selects readable objects" do
5
17
  monitor = selector.register(readable_subject, :r)
6
- ready = selector.select(0)
18
+ ready = selector.select(1)
7
19
  expect(ready).to be_an Enumerable
8
20
  expect(ready).to include monitor
9
21
  end
10
22
 
11
23
  it "does not select unreadable objects" do
12
- monitor = selector.register(unreadable_subject, :r)
24
+ selector.register(unreadable_subject, :r)
13
25
  expect(selector.select(0)).to be_nil
14
26
  end
15
27
 
16
28
  it "selects writable objects" do
17
29
  monitor = selector.register(writable_subject, :w)
18
- ready = selector.select(0)
30
+ ready = selector.select(1)
19
31
  expect(ready).to be_an Enumerable
20
32
  expect(ready).to include monitor
21
33
  end
22
34
 
23
35
  it "does not select unwritable objects" do
24
- monitor = selector.register(unwritable_subject, :w)
25
- expect(selector.select(0)).to be_nil
36
+ selector.register(unwritable_subject, :w)
37
+ ready = selector.select(0)
38
+ expect(ready).to be_nil
26
39
  end
27
40
  end
28
41
 
29
- RSpec.shared_context "an NIO selectable stream" do
30
- let(:selector) { NIO::Selector.new }
42
+ RSpec.shared_context "an NIO selectable stream" do |is_tls13|
43
+ include_context NIO::Selector
44
+
31
45
  let(:stream) { pair.first }
32
46
  let(:peer) { pair.last }
33
47
 
34
48
  it "selects readable when the other end closes" do
35
- # hax: this test is broken for OpenSSL sockets
36
- skip "broken for SSL ;_;" if peer.is_a? OpenSSL::SSL::SSLSocket
37
-
38
49
  monitor = selector.register(stream, :r)
39
- expect(selector.select(0)).to be_nil
50
+ unless is_tls13
51
+ expect(selector.select(1)).to be_nil
52
+ end
40
53
 
41
54
  peer.close
42
55
  # Wait and give the TCP session time to close
@@ -45,14 +58,28 @@ RSpec.shared_context "an NIO selectable stream" do
45
58
  end
46
59
 
47
60
  RSpec.shared_context "an NIO bidirectional stream" do
48
- let(:selector) { NIO::Selector.new }
49
- let(:stream) { pair.first }
50
- let(:peer) { pair.last }
61
+ include_context NIO::Selector
62
+
63
+ let(:stream) {pair.first}
64
+ let(:peer) {pair.last}
51
65
 
52
66
  it "selects readable and writable" do
53
- monitor = selector.register(readable_subject, :rw)
54
- selector.select(0) do |m|
55
- expect(m.readiness).to eq(:rw)
67
+ selector.register(readable_subject, :rw)
68
+
69
+ selector.select(1) do |monitor|
70
+ expect(monitor.readiness).to eq(:rw)
71
+ end
72
+
73
+ readable_subject.close
74
+ end
75
+
76
+ it "keeps readiness after the selectable has been closed" do
77
+ selector.register(readable_subject, :rw)
78
+
79
+ selector.select(1) do |monitor|
80
+ expect(monitor.readiness).to eq(:rw)
81
+ readable_subject.close
82
+ expect(monitor.readiness).to eq(:rw)
56
83
  end
57
84
  end
58
85
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nio4r
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 2.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tony Arcieri
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-31 00:00:00.000000000 Z
11
+ date: 2020-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rake
14
+ name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -38,54 +38,62 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- description: New IO for Ruby
41
+ description: Cross-platform asynchronous I/O primitives for scalable network clients
42
+ and servers. Inspired by the Java NIO API, but simplified for ease-of-use.
42
43
  email:
43
- - tony.arcieri@gmail.com
44
+ - bascule@gmail.com
44
45
  executables: []
45
46
  extensions:
46
47
  - ext/nio4r/extconf.rb
47
48
  extra_rdoc_files: []
48
49
  files:
50
+ - ".github/workflows/workflow.yml"
49
51
  - ".gitignore"
50
52
  - ".rspec"
51
53
  - ".rubocop.yml"
52
- - ".rubocop_todo.yml"
53
- - ".travis.yml"
54
54
  - CHANGES.md
55
55
  - Gemfile
56
- - LICENSE.txt
56
+ - Guardfile
57
57
  - README.md
58
58
  - Rakefile
59
59
  - examples/echo_server.rb
60
60
  - ext/libev/Changes
61
61
  - ext/libev/LICENSE
62
62
  - ext/libev/README
63
- - ext/libev/README.embed
64
63
  - ext/libev/ev.c
65
64
  - ext/libev/ev.h
66
65
  - ext/libev/ev_epoll.c
67
66
  - ext/libev/ev_kqueue.c
67
+ - ext/libev/ev_linuxaio.c
68
68
  - ext/libev/ev_poll.c
69
69
  - ext/libev/ev_port.c
70
70
  - ext/libev/ev_select.c
71
71
  - ext/libev/ev_vars.h
72
72
  - ext/libev/ev_win32.c
73
73
  - ext/libev/ev_wrap.h
74
- - ext/libev/test_libev_win32.c
74
+ - ext/nio4r/bytebuffer.c
75
75
  - ext/nio4r/extconf.rb
76
76
  - ext/nio4r/libev.h
77
77
  - ext/nio4r/monitor.c
78
78
  - ext/nio4r/nio4r.h
79
79
  - ext/nio4r/nio4r_ext.c
80
+ - ext/nio4r/org/nio4r/ByteBuffer.java
81
+ - ext/nio4r/org/nio4r/Monitor.java
80
82
  - ext/nio4r/org/nio4r/Nio4r.java
83
+ - ext/nio4r/org/nio4r/Selector.java
81
84
  - ext/nio4r/selector.c
82
85
  - lib/nio.rb
86
+ - lib/nio/bytebuffer.rb
83
87
  - lib/nio/monitor.rb
84
88
  - lib/nio/selector.rb
85
89
  - lib/nio/version.rb
86
90
  - logo.png
87
91
  - nio4r.gemspec
92
+ - rakelib/extension.rake
93
+ - rakelib/rspec.rake
94
+ - rakelib/rubocop.rake
88
95
  - spec/nio/acceptables_spec.rb
96
+ - spec/nio/bytebuffer_spec.rb
89
97
  - spec/nio/monitor_spec.rb
90
98
  - spec/nio/selectables/pipe_spec.rb
91
99
  - spec/nio/selectables/ssl_socket_spec.rb
@@ -94,14 +102,16 @@ files:
94
102
  - spec/nio/selector_spec.rb
95
103
  - spec/spec_helper.rb
96
104
  - spec/support/selectable_examples.rb
97
- - tasks/extension.rake
98
- - tasks/rspec.rake
99
- - tasks/rubocop.rake
100
- homepage: https://github.com/celluloid/nio4r
105
+ homepage: https://github.com/socketry/nio4r
101
106
  licenses:
102
107
  - MIT
103
- metadata: {}
104
- post_install_message:
108
+ metadata:
109
+ bug_tracker_uri: https://github.com/socketry/nio4r/issues
110
+ changelog_uri: https://github.com/socketry/nio4r/blob/master/CHANGES.md
111
+ documentation_uri: https://www.rubydoc.info/gems/nio4r/2.5.3
112
+ source_code_uri: https://github.com/socketry/nio4r/tree/v2.5.3
113
+ wiki_uri: https://github.com/socketry/nio4r/wiki
114
+ post_install_message:
105
115
  rdoc_options: []
106
116
  require_paths:
107
117
  - lib
@@ -109,20 +119,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
109
119
  requirements:
110
120
  - - ">="
111
121
  - !ruby/object:Gem::Version
112
- version: '0'
122
+ version: '2.4'
113
123
  required_rubygems_version: !ruby/object:Gem::Requirement
114
124
  requirements:
115
125
  - - ">="
116
126
  - !ruby/object:Gem::Version
117
127
  version: '0'
118
128
  requirements: []
119
- rubyforge_project:
120
- rubygems_version: 2.5.1
121
- signing_key:
129
+ rubygems_version: 3.1.2
130
+ signing_key:
122
131
  specification_version: 4
123
- summary: NIO provides a high performance selector API for monitoring IO objects
132
+ summary: New IO for Ruby
124
133
  test_files:
125
134
  - spec/nio/acceptables_spec.rb
135
+ - spec/nio/bytebuffer_spec.rb
126
136
  - spec/nio/monitor_spec.rb
127
137
  - spec/nio/selectables/pipe_spec.rb
128
138
  - spec/nio/selectables/ssl_socket_spec.rb