nio4r 2.4.0 → 2.5.7

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/workflow.yml +47 -0
  3. data/.rubocop.yml +30 -11
  4. data/CHANGES.md +63 -0
  5. data/Gemfile +1 -1
  6. data/README.md +57 -30
  7. data/examples/echo_server.rb +2 -2
  8. data/ext/libev/Changes +90 -2
  9. data/ext/libev/README +2 -1
  10. data/ext/libev/ev.c +708 -247
  11. data/ext/libev/ev.h +33 -29
  12. data/ext/libev/ev_epoll.c +41 -28
  13. data/ext/libev/ev_iouring.c +694 -0
  14. data/ext/libev/ev_kqueue.c +15 -9
  15. data/ext/libev/ev_linuxaio.c +620 -0
  16. data/ext/libev/ev_poll.c +19 -14
  17. data/ext/libev/ev_port.c +8 -5
  18. data/ext/libev/ev_select.c +6 -6
  19. data/ext/libev/ev_vars.h +46 -1
  20. data/ext/libev/ev_win32.c +2 -2
  21. data/ext/libev/ev_wrap.h +72 -0
  22. data/ext/nio4r/.clang-format +16 -0
  23. data/ext/nio4r/bytebuffer.c +27 -28
  24. data/ext/nio4r/extconf.rb +9 -0
  25. data/ext/nio4r/libev.h +1 -3
  26. data/ext/nio4r/monitor.c +34 -31
  27. data/ext/nio4r/nio4r.h +7 -12
  28. data/ext/nio4r/org/nio4r/ByteBuffer.java +2 -0
  29. data/ext/nio4r/org/nio4r/Monitor.java +1 -0
  30. data/ext/nio4r/org/nio4r/Selector.java +13 -11
  31. data/ext/nio4r/selector.c +66 -51
  32. data/lib/nio.rb +20 -1
  33. data/lib/nio/bytebuffer.rb +4 -0
  34. data/lib/nio/monitor.rb +1 -1
  35. data/lib/nio/selector.rb +12 -10
  36. data/lib/nio/version.rb +1 -1
  37. data/nio4r.gemspec +10 -2
  38. data/spec/nio/bytebuffer_spec.rb +0 -1
  39. data/spec/nio/selectables/ssl_socket_spec.rb +3 -1
  40. data/spec/nio/selectables/udp_socket_spec.rb +2 -2
  41. data/spec/nio/selector_spec.rb +27 -5
  42. data/spec/spec_helper.rb +2 -0
  43. metadata +17 -12
  44. data/.travis.yml +0 -29
  45. data/Guardfile +0 -10
  46. data/LICENSE.txt +0 -20
  47. data/appveyor.yml +0 -40
data/lib/nio.rb CHANGED
@@ -12,9 +12,28 @@ module NIO
12
12
  def self.engine
13
13
  ENGINE
14
14
  end
15
+
16
+ def self.pure?(env = ENV)
17
+ # The user has explicitly opted in to non-native implementation:
18
+ if env["NIO4R_PURE"] == "true"
19
+ return true
20
+ end
21
+
22
+ # Native Ruby on Windows is not supported:
23
+ if (Gem.win_platform? && !defined?(JRUBY_VERSION))
24
+ return true
25
+ end
26
+
27
+ # M1 native extension is crashing on M1 (arm64):
28
+ # if RUBY_PLATFORM =~ /darwin/ && RUBY_PLATFORM =~ /arm64/
29
+ # return true
30
+ # end
31
+
32
+ return false
33
+ end
15
34
  end
16
35
 
17
- if ENV["NIO4R_PURE"] == "true" || (Gem.win_platform? && !defined?(JRUBY_VERSION))
36
+ if NIO.pure?
18
37
  require "nio/monitor"
19
38
  require "nio/selector"
20
39
  require "nio/bytebuffer"
@@ -24,6 +24,7 @@ module NIO
24
24
  # @return [NIO::ByteBuffer]
25
25
  def initialize(capacity)
26
26
  raise TypeError, "no implicit conversion of #{capacity.class} to Integer" unless capacity.is_a?(Integer)
27
+
27
28
  @capacity = capacity
28
29
  clear
29
30
  end
@@ -119,9 +120,11 @@ module NIO
119
120
  # @return [self]
120
121
  def put(str)
121
122
  raise TypeError, "expected String, got #{str.class}" unless str.respond_to?(:to_str)
123
+
122
124
  str = str.to_str
123
125
 
124
126
  raise OverflowError, "buffer is full" if str.length > @limit - @position
127
+
125
128
  @buffer[@position...str.length] = str
126
129
  @position += str.length
127
130
  self
@@ -188,6 +191,7 @@ module NIO
188
191
  # @raise [NIO::ByteBuffer::MarkUnsetError] mark has not been set (call `#mark` first)
189
192
  def reset
190
193
  raise MarkUnsetError, "mark has not been set" unless @mark
194
+
191
195
  @position = @mark
192
196
  self
193
197
  end
data/lib/nio/monitor.rb CHANGED
@@ -8,7 +8,7 @@ module NIO
8
8
 
9
9
  # :nodoc:
10
10
  def initialize(io, interests, selector)
11
- unless io.is_a? OpenSSL::SSL::SSLSocket
11
+ unless defined?(::OpenSSL) && io.is_a?(::OpenSSL::SSL::SSLSocket)
12
12
  unless io.is_a?(IO)
13
13
  if IO.respond_to? :try_convert
14
14
  io = IO.try_convert(io)
data/lib/nio/selector.rb CHANGED
@@ -14,7 +14,7 @@ module NIO
14
14
 
15
15
  # Create a new NIO::Selector
16
16
  def initialize(backend = :ruby)
17
- raise ArgumentError, "unsupported backend: #{backend}" unless backend == :ruby
17
+ raise ArgumentError, "unsupported backend: #{backend}" unless [:ruby, nil].include?(backend)
18
18
 
19
19
  @selectables = {}
20
20
  @lock = Mutex.new
@@ -26,14 +26,16 @@ module NIO
26
26
 
27
27
  # Return a symbol representing the backend I/O multiplexing mechanism used.
28
28
  # Supported backends are:
29
- # * :ruby - pure Ruby (i.e IO.select)
30
- # * :java - Java NIO on JRuby
31
- # * :epoll - libev w\ Linux epoll
32
- # * :poll - libev w\ POSIX poll
33
- # * :kqueue - libev w\ BSD kqueue
34
- # * :select - libev w\ SysV select
35
- # * :port - libev w\ I/O completion ports
36
- # * :unknown - libev w\ unknown backend
29
+ # * :ruby - pure Ruby (i.e IO.select)
30
+ # * :java - Java NIO on JRuby
31
+ # * :epoll - libev w\ Linux epoll
32
+ # * :poll - libev w\ POSIX poll
33
+ # * :kqueue - libev w\ BSD kqueue
34
+ # * :select - libev w\ SysV select
35
+ # * :port - libev w\ I/O completion ports
36
+ # * :linuxaio - libev w\ Linux AIO io_submit (experimental)
37
+ # * :io_uring - libev w\ Linux io_uring (experimental)
38
+ # * :unknown - libev w\ unknown backend
37
39
  def backend
38
40
  :ruby
39
41
  end
@@ -44,7 +46,7 @@ module NIO
44
46
  # * :w - is the IO writeable?
45
47
  # * :rw - is the IO either readable or writeable?
46
48
  def register(io, interest)
47
- unless io.is_a? OpenSSL::SSL::SSLSocket
49
+ unless defined?(::OpenSSL) && io.is_a?(::OpenSSL::SSL::SSLSocket)
48
50
  io = IO.try_convert(io)
49
51
  end
50
52
 
data/lib/nio/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NIO
4
- VERSION = "2.4.0"
4
+ VERSION = "2.5.7"
5
5
  end
data/nio4r.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require File.expand_path("../lib/nio/version", __FILE__)
3
+ require File.expand_path("lib/nio/version", __dir__)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.authors = ["Tony Arcieri"]
@@ -20,7 +20,15 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ["lib"]
21
21
  spec.version = NIO::VERSION
22
22
 
23
- spec.required_ruby_version = ">= 2.3"
23
+ spec.metadata = {
24
+ "bug_tracker_uri" => "https://github.com/socketry/nio4r/issues",
25
+ "changelog_uri" => "https://github.com/socketry/nio4r/blob/master/CHANGES.md",
26
+ "documentation_uri" => "https://www.rubydoc.info/gems/nio4r/#{spec.version}",
27
+ "source_code_uri" => "https://github.com/socketry/nio4r/tree/v#{spec.version}",
28
+ "wiki_uri" => "https://github.com/socketry/nio4r/wiki"
29
+ }
30
+
31
+ spec.required_ruby_version = ">= 2.4"
24
32
 
25
33
  if defined? JRUBY_VERSION
26
34
  spec.files << "lib/nio4r_ext.jar"
@@ -352,4 +352,3 @@ RSpec.describe NIO::ByteBuffer do
352
352
  end
353
353
  end
354
354
  end
355
- # rubocop:enable Metrics/BlockLength
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "spec_helper"
4
- require "openssl"
5
4
 
6
5
  RSpec.describe OpenSSL::SSL::SSLSocket do
6
+
7
+ require "openssl"
8
+
7
9
  before(:all) do
8
10
  @tls = []
9
11
  end
@@ -33,8 +33,8 @@ RSpec.describe UDPSocket, if: !defined?(JRUBY_VERSION) do
33
33
  peer.send("X" * 1024, 0)
34
34
  cntr += 1
35
35
  t = select [], [peer], [], 0
36
- rescue Errno::ECONNREFUSED => ex
37
- skip "Couldn't make writable UDPSocket subject: #{ex.class}: #{ex}"
36
+ rescue Errno::ECONNREFUSED => e
37
+ skip "Couldn't make writable UDPSocket subject: #{e.class}: #{e}"
38
38
  end while t && t[1].include?(peer) && cntr < 5
39
39
 
40
40
  peer
@@ -16,10 +16,16 @@ RSpec.describe NIO::Selector do
16
16
  end
17
17
 
18
18
  context "#initialize" do
19
- it "allows explicitly specifying a backend" do
19
+ it "allows explicitly specifying a backend" do |example|
20
20
  backend = described_class.backends.first
21
21
  selector = described_class.new(backend)
22
22
  expect(selector.backend).to eq backend
23
+
24
+ example.reporter.message "Supported backends: #{described_class.backends}"
25
+ end
26
+
27
+ it "automatically selects a backend if none or nil is specified" do
28
+ expect(described_class.new.backend).to eq described_class.new(nil).backend
23
29
  end
24
30
 
25
31
  it "raises ArgumentError if given an invalid backend" do
@@ -32,8 +38,10 @@ RSpec.describe NIO::Selector do
32
38
  end
33
39
 
34
40
  context "backend" do
35
- it "knows its backend" do
41
+ it "knows its backend" do |example|
36
42
  expect(subject.backend).to be_a Symbol
43
+
44
+ example.reporter.message "Current backend: #{subject.backend}"
37
45
  end
38
46
  end
39
47
 
@@ -67,6 +75,15 @@ RSpec.describe NIO::Selector do
67
75
  expect(monitor).to be_closed
68
76
  end
69
77
 
78
+ it "allows deregistering closed IO objects" do
79
+ subject.register(reader, :r)
80
+ reader.close
81
+
82
+ expect do
83
+ subject.deregister(reader)
84
+ end.not_to raise_error
85
+ end
86
+
70
87
  it "reports if it is empty" do
71
88
  expect(subject).to be_empty
72
89
  subject.register(reader, :r)
@@ -91,14 +108,20 @@ RSpec.describe NIO::Selector do
91
108
 
92
109
  context "timeouts" do
93
110
  let(:select_precision) {0.2}
111
+ let(:timeout) {2.0}
94
112
  let(:payload) {"hi there"}
95
113
 
96
- it "waits for a timeout when selecting" do
114
+ it "waits for timeout when selecting from empty selector" do
115
+ started_at = Time.now
116
+ expect(subject.select(timeout)).to be_nil
117
+ expect(Time.now - started_at).to be_within(select_precision).of(timeout)
118
+ end
119
+
120
+ it "waits for a timeout when selecting with reader" do
97
121
  monitor = subject.register(reader, :r)
98
122
 
99
123
  writer << payload
100
124
 
101
- timeout = 0.5
102
125
  started_at = Time.now
103
126
  expect(subject.select(timeout)).to include monitor
104
127
  expect(Time.now - started_at).to be_within(select_precision).of(0)
@@ -215,4 +238,3 @@ RSpec.describe NIO::Selector do
215
238
  expect(subject).to be_closed
216
239
  end
217
240
  end
218
- # rubocop:enable Metrics/BlockLength
data/spec/spec_helper.rb CHANGED
@@ -12,6 +12,8 @@ RSpec.configure do |config|
12
12
  # Enable flags like --only-failures and --next-failure
13
13
  config.example_status_persistence_file_path = ".rspec_status"
14
14
 
15
+ config.filter_run_when_matching :focus
16
+
15
17
  config.expect_with :rspec do |c|
16
18
  c.syntax = :expect
17
19
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nio4r
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.5.7
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: 2019-07-07 00:00:00.000000000 Z
11
+ date: 2021-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -47,17 +47,14 @@ extensions:
47
47
  - ext/nio4r/extconf.rb
48
48
  extra_rdoc_files: []
49
49
  files:
50
+ - ".github/workflows/workflow.yml"
50
51
  - ".gitignore"
51
52
  - ".rspec"
52
53
  - ".rubocop.yml"
53
- - ".travis.yml"
54
54
  - CHANGES.md
55
55
  - Gemfile
56
- - Guardfile
57
- - LICENSE.txt
58
56
  - README.md
59
57
  - Rakefile
60
- - appveyor.yml
61
58
  - examples/echo_server.rb
62
59
  - ext/libev/Changes
63
60
  - ext/libev/LICENSE
@@ -65,13 +62,16 @@ files:
65
62
  - ext/libev/ev.c
66
63
  - ext/libev/ev.h
67
64
  - ext/libev/ev_epoll.c
65
+ - ext/libev/ev_iouring.c
68
66
  - ext/libev/ev_kqueue.c
67
+ - ext/libev/ev_linuxaio.c
69
68
  - ext/libev/ev_poll.c
70
69
  - ext/libev/ev_port.c
71
70
  - ext/libev/ev_select.c
72
71
  - ext/libev/ev_vars.h
73
72
  - ext/libev/ev_win32.c
74
73
  - ext/libev/ev_wrap.h
74
+ - ext/nio4r/.clang-format
75
75
  - ext/nio4r/bytebuffer.c
76
76
  - ext/nio4r/extconf.rb
77
77
  - ext/nio4r/libev.h
@@ -106,8 +106,13 @@ files:
106
106
  homepage: https://github.com/socketry/nio4r
107
107
  licenses:
108
108
  - MIT
109
- metadata: {}
110
- post_install_message:
109
+ metadata:
110
+ bug_tracker_uri: https://github.com/socketry/nio4r/issues
111
+ changelog_uri: https://github.com/socketry/nio4r/blob/master/CHANGES.md
112
+ documentation_uri: https://www.rubydoc.info/gems/nio4r/2.5.7
113
+ source_code_uri: https://github.com/socketry/nio4r/tree/v2.5.7
114
+ wiki_uri: https://github.com/socketry/nio4r/wiki
115
+ post_install_message:
111
116
  rdoc_options: []
112
117
  require_paths:
113
118
  - lib
@@ -115,15 +120,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
120
  requirements:
116
121
  - - ">="
117
122
  - !ruby/object:Gem::Version
118
- version: '2.3'
123
+ version: '2.4'
119
124
  required_rubygems_version: !ruby/object:Gem::Requirement
120
125
  requirements:
121
126
  - - ">="
122
127
  - !ruby/object:Gem::Version
123
128
  version: '0'
124
129
  requirements: []
125
- rubygems_version: 3.0.3
126
- signing_key:
130
+ rubygems_version: 3.2.3
131
+ signing_key:
127
132
  specification_version: 4
128
133
  summary: New IO for Ruby
129
134
  test_files:
data/.travis.yml DELETED
@@ -1,29 +0,0 @@
1
- language: ruby
2
- cache: bundler
3
- dist: xenial
4
- bundler_args: --without development
5
-
6
- matrix:
7
- fast_finish: true
8
- include:
9
- - rvm: 2.3
10
- - rvm: 2.4
11
- - rvm: 2.5
12
- - rvm: 2.6
13
- env: NIO4R_PURE=true
14
- - rvm: 2.6
15
- - rvm: 2.6
16
- os: osx
17
- - rvm: truffleruby
18
- - rvm: truffleruby
19
- env: NIO4R_PURE=true
20
- - rvm: jruby
21
- env: JRUBY_OPTS="--debug -X+O --dev -J-Djruby.launch.inproc=true -J-Xmx1024M"
22
- - rvm: jruby-head
23
- env: JRUBY_OPTS="--debug -X+O --dev -J-Djruby.launch.inproc=true -J-Xmx1024M"
24
- - rvm: ruby-head
25
- allow_failures:
26
- - rvm: ruby-head
27
- - rvm: truffleruby
28
- - rvm: jruby-head
29
- - rvm: jruby
data/Guardfile DELETED
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- directories %w[lib spec]
4
- clearing :on
5
-
6
- guard :rspec, cmd: "bundle exec rspec" do
7
- watch(%r{^spec/.+_spec\.rb$})
8
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
9
- watch("spec/spec_helper.rb") { "spec" }
10
- end
data/LICENSE.txt DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2011-2018 Tony Arcieri
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/appveyor.yml DELETED
@@ -1,40 +0,0 @@
1
- build: off
2
- deploy: off
3
-
4
- environment:
5
- PATH: C:\Ruby%RUBY_VERSION%\bin;%PATH%
6
- APPVEYOR_SAVE_CACHE_ON_ERROR: True
7
- matrix:
8
- - RUBY_VERSION: _trunk
9
- - RUBY_VERSION: 26-x64
10
- - RUBY_VERSION: 25-x64
11
- - RUBY_VERSION: 24-x64
12
- - RUBY_VERSION: 23-x64
13
- - RUBY_VERSION: 23
14
-
15
- init:
16
- - ps: |
17
- if ($env:RUBY_VERSION -eq '_trunk') {
18
- $trunk_uri = 'https://ci.appveyor.com/api/projects/MSP-Greg/ruby-loco/artifacts/ruby_trunk.7z'
19
- (New-Object Net.WebClient).DownloadFile($trunk_uri, 'C:\ruby_trunk.7z')
20
- 7z.exe x C:\ruby_trunk.7z -oC:\Ruby_trunk
21
- }
22
-
23
- install:
24
- - SET RAKEOPT=-rdevkit
25
- - gem update --system --conservative --no-document
26
- - ruby -v
27
- - gem -v
28
- - bundle -v
29
- - bundle install --path vendor\bundle --without development
30
-
31
- test_script:
32
- - bundle exec rake spec
33
-
34
- matrix:
35
- allow_failures:
36
- - RUBY_VERSION: _trunk
37
-
38
- cache:
39
- # If one of the files after the right arrow changes, cache will be invalidated
40
- - vendor\bundle -> appveyor.yml, Gemfile, nio4r.gemspec