nio4r 2.4.0 → 2.5.7

Sign up to get free protection for your applications and to get access to all the features.
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