nio4r 2.5.4 → 2.5.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/workflow.yml +10 -4
- data/README.md +1 -0
- data/ext/libev/Changes +71 -2
- data/ext/libev/ev.c +625 -198
- data/ext/libev/ev.h +25 -22
- data/ext/libev/ev_epoll.c +16 -14
- data/ext/libev/ev_iouring.c +694 -0
- data/ext/libev/ev_kqueue.c +4 -4
- data/ext/libev/ev_linuxaio.c +78 -100
- data/ext/libev/ev_poll.c +6 -6
- data/ext/libev/ev_port.c +3 -3
- data/ext/libev/ev_select.c +6 -6
- data/ext/libev/ev_vars.h +34 -0
- data/ext/libev/ev_win32.c +2 -2
- data/ext/libev/ev_wrap.h +56 -0
- data/ext/nio4r/extconf.rb +1 -0
- data/ext/nio4r/org/nio4r/ByteBuffer.java +2 -0
- data/ext/nio4r/org/nio4r/Monitor.java +1 -0
- data/ext/nio4r/org/nio4r/Selector.java +8 -10
- data/ext/nio4r/selector.c +16 -0
- data/lib/nio.rb +20 -1
- data/lib/nio/selector.rb +11 -9
- data/lib/nio/version.rb +1 -1
- data/spec/nio/selector_spec.rb +4 -0
- data/spec/spec_helper.rb +2 -0
- metadata +5 -4
data/ext/libev/ev_vars.h
CHANGED
@@ -118,6 +118,35 @@ VARx(int, linuxaio_submitmax)
|
|
118
118
|
VARx(ev_io, linuxaio_epoll_w)
|
119
119
|
#endif
|
120
120
|
|
121
|
+
#if EV_USE_IOURING || EV_GENWRAP
|
122
|
+
VARx(int, iouring_fd)
|
123
|
+
VARx(unsigned, iouring_to_submit);
|
124
|
+
VARx(int, iouring_entries)
|
125
|
+
VARx(int, iouring_max_entries)
|
126
|
+
VARx(void *, iouring_sq_ring)
|
127
|
+
VARx(void *, iouring_cq_ring)
|
128
|
+
VARx(void *, iouring_sqes)
|
129
|
+
VARx(uint32_t, iouring_sq_ring_size)
|
130
|
+
VARx(uint32_t, iouring_cq_ring_size)
|
131
|
+
VARx(uint32_t, iouring_sqes_size)
|
132
|
+
VARx(uint32_t, iouring_sq_head)
|
133
|
+
VARx(uint32_t, iouring_sq_tail)
|
134
|
+
VARx(uint32_t, iouring_sq_ring_mask)
|
135
|
+
VARx(uint32_t, iouring_sq_ring_entries)
|
136
|
+
VARx(uint32_t, iouring_sq_flags)
|
137
|
+
VARx(uint32_t, iouring_sq_dropped)
|
138
|
+
VARx(uint32_t, iouring_sq_array)
|
139
|
+
VARx(uint32_t, iouring_cq_head)
|
140
|
+
VARx(uint32_t, iouring_cq_tail)
|
141
|
+
VARx(uint32_t, iouring_cq_ring_mask)
|
142
|
+
VARx(uint32_t, iouring_cq_ring_entries)
|
143
|
+
VARx(uint32_t, iouring_cq_overflow)
|
144
|
+
VARx(uint32_t, iouring_cq_cqes)
|
145
|
+
VARx(ev_tstamp, iouring_tfd_to)
|
146
|
+
VARx(int, iouring_tfd)
|
147
|
+
VARx(ev_io, iouring_tfd_w)
|
148
|
+
#endif
|
149
|
+
|
121
150
|
#if EV_USE_KQUEUE || EV_GENWRAP
|
122
151
|
VARx(pid_t, kqueue_fd_pid)
|
123
152
|
VARx(struct kevent *, kqueue_changes)
|
@@ -198,6 +227,11 @@ VARx(ev_io, sigfd_w)
|
|
198
227
|
VARx(sigset_t, sigfd_set)
|
199
228
|
#endif
|
200
229
|
|
230
|
+
#if EV_USE_TIMERFD || EV_GENWRAP
|
231
|
+
VARx(int, timerfd) /* timerfd for time jump detection */
|
232
|
+
VARx(ev_io, timerfd_w)
|
233
|
+
#endif
|
234
|
+
|
201
235
|
VARx(unsigned int, origflags) /* original loop flags */
|
202
236
|
|
203
237
|
#if EV_FEATURE_API || EV_GENWRAP
|
data/ext/libev/ev_win32.c
CHANGED
@@ -154,8 +154,8 @@ ev_time (void)
|
|
154
154
|
ui.u.LowPart = ft.dwLowDateTime;
|
155
155
|
ui.u.HighPart = ft.dwHighDateTime;
|
156
156
|
|
157
|
-
/* msvc cannot convert ulonglong to double... yes, it is that sucky */
|
158
|
-
return (LONGLONG)(ui.QuadPart - 116444736000000000) * 1e-
|
157
|
+
/* also, msvc cannot convert ulonglong to double... yes, it is that sucky */
|
158
|
+
return EV_TS_FROM_USEC (((LONGLONG)(ui.QuadPart - 116444736000000000) * 1e-1));
|
159
159
|
}
|
160
160
|
|
161
161
|
#endif
|
data/ext/libev/ev_wrap.h
CHANGED
@@ -44,6 +44,32 @@
|
|
44
44
|
#define invoke_cb ((loop)->invoke_cb)
|
45
45
|
#define io_blocktime ((loop)->io_blocktime)
|
46
46
|
#define iocp ((loop)->iocp)
|
47
|
+
#define iouring_cq_cqes ((loop)->iouring_cq_cqes)
|
48
|
+
#define iouring_cq_head ((loop)->iouring_cq_head)
|
49
|
+
#define iouring_cq_overflow ((loop)->iouring_cq_overflow)
|
50
|
+
#define iouring_cq_ring ((loop)->iouring_cq_ring)
|
51
|
+
#define iouring_cq_ring_entries ((loop)->iouring_cq_ring_entries)
|
52
|
+
#define iouring_cq_ring_mask ((loop)->iouring_cq_ring_mask)
|
53
|
+
#define iouring_cq_ring_size ((loop)->iouring_cq_ring_size)
|
54
|
+
#define iouring_cq_tail ((loop)->iouring_cq_tail)
|
55
|
+
#define iouring_entries ((loop)->iouring_entries)
|
56
|
+
#define iouring_fd ((loop)->iouring_fd)
|
57
|
+
#define iouring_max_entries ((loop)->iouring_max_entries)
|
58
|
+
#define iouring_sq_array ((loop)->iouring_sq_array)
|
59
|
+
#define iouring_sq_dropped ((loop)->iouring_sq_dropped)
|
60
|
+
#define iouring_sq_flags ((loop)->iouring_sq_flags)
|
61
|
+
#define iouring_sq_head ((loop)->iouring_sq_head)
|
62
|
+
#define iouring_sq_ring ((loop)->iouring_sq_ring)
|
63
|
+
#define iouring_sq_ring_entries ((loop)->iouring_sq_ring_entries)
|
64
|
+
#define iouring_sq_ring_mask ((loop)->iouring_sq_ring_mask)
|
65
|
+
#define iouring_sq_ring_size ((loop)->iouring_sq_ring_size)
|
66
|
+
#define iouring_sq_tail ((loop)->iouring_sq_tail)
|
67
|
+
#define iouring_sqes ((loop)->iouring_sqes)
|
68
|
+
#define iouring_sqes_size ((loop)->iouring_sqes_size)
|
69
|
+
#define iouring_tfd ((loop)->iouring_tfd)
|
70
|
+
#define iouring_tfd_to ((loop)->iouring_tfd_to)
|
71
|
+
#define iouring_tfd_w ((loop)->iouring_tfd_w)
|
72
|
+
#define iouring_to_submit ((loop)->iouring_to_submit)
|
47
73
|
#define kqueue_changecnt ((loop)->kqueue_changecnt)
|
48
74
|
#define kqueue_changemax ((loop)->kqueue_changemax)
|
49
75
|
#define kqueue_changes ((loop)->kqueue_changes)
|
@@ -97,6 +123,8 @@
|
|
97
123
|
#define sigfd_w ((loop)->sigfd_w)
|
98
124
|
#define timeout_blocktime ((loop)->timeout_blocktime)
|
99
125
|
#define timercnt ((loop)->timercnt)
|
126
|
+
#define timerfd ((loop)->timerfd)
|
127
|
+
#define timerfd_w ((loop)->timerfd_w)
|
100
128
|
#define timermax ((loop)->timermax)
|
101
129
|
#define timers ((loop)->timers)
|
102
130
|
#define userdata ((loop)->userdata)
|
@@ -151,6 +179,32 @@
|
|
151
179
|
#undef invoke_cb
|
152
180
|
#undef io_blocktime
|
153
181
|
#undef iocp
|
182
|
+
#undef iouring_cq_cqes
|
183
|
+
#undef iouring_cq_head
|
184
|
+
#undef iouring_cq_overflow
|
185
|
+
#undef iouring_cq_ring
|
186
|
+
#undef iouring_cq_ring_entries
|
187
|
+
#undef iouring_cq_ring_mask
|
188
|
+
#undef iouring_cq_ring_size
|
189
|
+
#undef iouring_cq_tail
|
190
|
+
#undef iouring_entries
|
191
|
+
#undef iouring_fd
|
192
|
+
#undef iouring_max_entries
|
193
|
+
#undef iouring_sq_array
|
194
|
+
#undef iouring_sq_dropped
|
195
|
+
#undef iouring_sq_flags
|
196
|
+
#undef iouring_sq_head
|
197
|
+
#undef iouring_sq_ring
|
198
|
+
#undef iouring_sq_ring_entries
|
199
|
+
#undef iouring_sq_ring_mask
|
200
|
+
#undef iouring_sq_ring_size
|
201
|
+
#undef iouring_sq_tail
|
202
|
+
#undef iouring_sqes
|
203
|
+
#undef iouring_sqes_size
|
204
|
+
#undef iouring_tfd
|
205
|
+
#undef iouring_tfd_to
|
206
|
+
#undef iouring_tfd_w
|
207
|
+
#undef iouring_to_submit
|
154
208
|
#undef kqueue_changecnt
|
155
209
|
#undef kqueue_changemax
|
156
210
|
#undef kqueue_changes
|
@@ -204,6 +258,8 @@
|
|
204
258
|
#undef sigfd_w
|
205
259
|
#undef timeout_blocktime
|
206
260
|
#undef timercnt
|
261
|
+
#undef timerfd
|
262
|
+
#undef timerfd_w
|
207
263
|
#undef timermax
|
208
264
|
#undef timers
|
209
265
|
#undef userdata
|
data/ext/nio4r/extconf.rb
CHANGED
@@ -15,6 +15,7 @@ require "mkmf"
|
|
15
15
|
have_header("unistd.h")
|
16
16
|
|
17
17
|
$defs << "-DEV_USE_LINUXAIO" if have_header("linux/aio_abi.h")
|
18
|
+
$defs << "-DEV_USE_IOURING" if have_header("linux/io_uring.h")
|
18
19
|
$defs << "-DEV_USE_SELECT" if have_header("sys/select.h")
|
19
20
|
$defs << "-DEV_USE_POLL" if have_type("port_event_t", "poll.h")
|
20
21
|
$defs << "-DEV_USE_EPOLL" if have_header("sys/epoll.h")
|
@@ -1,6 +1,7 @@
|
|
1
1
|
package org.nio4r;
|
2
2
|
|
3
3
|
import java.io.IOException;
|
4
|
+
import java.io.Serializable;
|
4
5
|
import java.nio.channels.Channel;
|
5
6
|
import java.nio.channels.SelectableChannel;
|
6
7
|
import java.nio.channels.ReadableByteChannel;
|
@@ -25,6 +26,7 @@ import org.jruby.runtime.Block;
|
|
25
26
|
created by Upekshej
|
26
27
|
*/
|
27
28
|
public class ByteBuffer extends RubyObject {
|
29
|
+
private static final long serialVersionUID = -6903439483039149324L;
|
28
30
|
private java.nio.ByteBuffer byteBuffer;
|
29
31
|
|
30
32
|
public static RaiseException newOverflowError(ThreadContext context, String message) {
|
@@ -13,6 +13,7 @@ import org.jruby.runtime.ThreadContext;
|
|
13
13
|
import org.jruby.runtime.builtin.IRubyObject;
|
14
14
|
|
15
15
|
public class Monitor extends RubyObject {
|
16
|
+
private static final long serialVersionUID = -3733782997115074794L;
|
16
17
|
private SelectionKey key;
|
17
18
|
private RubyIO io;
|
18
19
|
private IRubyObject interests, selector, value, closed;
|
@@ -7,7 +7,6 @@ import java.io.IOException;
|
|
7
7
|
import java.nio.channels.Channel;
|
8
8
|
import java.nio.channels.SelectableChannel;
|
9
9
|
import java.nio.channels.SelectionKey;
|
10
|
-
import java.nio.channels.CancelledKeyException;
|
11
10
|
|
12
11
|
import org.jruby.Ruby;
|
13
12
|
import org.jruby.RubyArray;
|
@@ -21,9 +20,8 @@ import org.jruby.runtime.ThreadContext;
|
|
21
20
|
import org.jruby.runtime.builtin.IRubyObject;
|
22
21
|
import org.jruby.util.io.OpenFile;
|
23
22
|
|
24
|
-
import org.nio4r.Monitor;
|
25
|
-
|
26
23
|
public class Selector extends RubyObject {
|
24
|
+
private static final long serialVersionUID = -14562818539414873L;
|
27
25
|
private java.nio.channels.Selector selector;
|
28
26
|
private HashMap<SelectableChannel,SelectionKey> cancelledKeys;
|
29
27
|
private volatile boolean wakeupFired;
|
@@ -45,7 +43,7 @@ public class Selector extends RubyObject {
|
|
45
43
|
|
46
44
|
@JRubyMethod
|
47
45
|
public IRubyObject initialize(ThreadContext context, IRubyObject backend) {
|
48
|
-
if(backend != context.runtime.newSymbol("java")) {
|
46
|
+
if(backend != context.runtime.newSymbol("java") && !backend.isNil()) {
|
49
47
|
throw context.runtime.newArgumentError(":java is the only supported backend");
|
50
48
|
}
|
51
49
|
|
@@ -203,15 +201,15 @@ public class Selector extends RubyObject {
|
|
203
201
|
return context.nil;
|
204
202
|
}
|
205
203
|
|
206
|
-
RubyArray array = null;
|
204
|
+
RubyArray<?> array = null;
|
207
205
|
|
208
206
|
if(!block.isGiven()) {
|
209
207
|
array = runtime.newArray(this.selector.selectedKeys().size());
|
210
208
|
}
|
211
209
|
|
212
|
-
Iterator selectedKeys = this.selector.selectedKeys().iterator();
|
210
|
+
Iterator<SelectionKey> selectedKeys = this.selector.selectedKeys().iterator();
|
213
211
|
while(selectedKeys.hasNext()) {
|
214
|
-
SelectionKey key =
|
212
|
+
SelectionKey key = selectedKeys.next();
|
215
213
|
processKey(key);
|
216
214
|
|
217
215
|
selectedKeys.remove();
|
@@ -263,10 +261,10 @@ public class Selector extends RubyObject {
|
|
263
261
|
|
264
262
|
/* Flush our internal buffer of cancelled keys */
|
265
263
|
private void cancelKeys() {
|
266
|
-
Iterator cancelledKeys = this.cancelledKeys.entrySet().iterator();
|
264
|
+
Iterator<Map.Entry<SelectableChannel, SelectionKey>> cancelledKeys = this.cancelledKeys.entrySet().iterator();
|
267
265
|
while(cancelledKeys.hasNext()) {
|
268
|
-
Map.Entry entry =
|
269
|
-
SelectionKey key =
|
266
|
+
Map.Entry<SelectableChannel, SelectionKey> entry = cancelledKeys.next();
|
267
|
+
SelectionKey key = entry.getValue();
|
270
268
|
key.cancel();
|
271
269
|
cancelledKeys.remove();
|
272
270
|
}
|
data/ext/nio4r/selector.c
CHANGED
@@ -183,6 +183,14 @@ static VALUE NIO_Selector_supported_backends(VALUE klass)
|
|
183
183
|
rb_ary_push(result, ID2SYM(rb_intern("port")));
|
184
184
|
}
|
185
185
|
|
186
|
+
if (backends & EVBACKEND_LINUXAIO) {
|
187
|
+
rb_ary_push(result, ID2SYM(rb_intern("linuxaio")));
|
188
|
+
}
|
189
|
+
|
190
|
+
if (backends & EVBACKEND_IOURING) {
|
191
|
+
rb_ary_push(result, ID2SYM(rb_intern("io_uring")));
|
192
|
+
}
|
193
|
+
|
186
194
|
return result;
|
187
195
|
}
|
188
196
|
|
@@ -218,6 +226,10 @@ static VALUE NIO_Selector_initialize(int argc, VALUE *argv, VALUE self)
|
|
218
226
|
flags = EVBACKEND_SELECT;
|
219
227
|
} else if (backend_id == rb_intern("port")) {
|
220
228
|
flags = EVBACKEND_PORT;
|
229
|
+
} else if (backend_id == rb_intern("linuxaio")) {
|
230
|
+
flags = EVBACKEND_LINUXAIO;
|
231
|
+
} else if (backend_id == rb_intern("io_uring")) {
|
232
|
+
flags = EVBACKEND_IOURING;
|
221
233
|
} else {
|
222
234
|
rb_raise(rb_eArgError, "unsupported backend: %s", RSTRING_PTR(rb_funcall(backend, rb_intern("inspect"), 0)));
|
223
235
|
}
|
@@ -263,6 +275,10 @@ static VALUE NIO_Selector_backend(VALUE self)
|
|
263
275
|
return ID2SYM(rb_intern("select"));
|
264
276
|
case EVBACKEND_PORT:
|
265
277
|
return ID2SYM(rb_intern("port"));
|
278
|
+
case EVBACKEND_LINUXAIO:
|
279
|
+
return ID2SYM(rb_intern("linuxaio"));
|
280
|
+
case EVBACKEND_IOURING:
|
281
|
+
return ID2SYM(rb_intern("io_uring"));
|
266
282
|
}
|
267
283
|
|
268
284
|
return ID2SYM(rb_intern("unknown"));
|
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
|
36
|
+
if NIO.pure?
|
18
37
|
require "nio/monitor"
|
19
38
|
require "nio/selector"
|
20
39
|
require "nio/bytebuffer"
|
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
|
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
|
30
|
-
# * :java
|
31
|
-
# * :epoll
|
32
|
-
# * :poll
|
33
|
-
# * :kqueue
|
34
|
-
# * :select
|
35
|
-
# * :port
|
36
|
-
# * :
|
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
|
data/lib/nio/version.rb
CHANGED
data/spec/nio/selector_spec.rb
CHANGED
@@ -24,6 +24,10 @@ RSpec.describe NIO::Selector do
|
|
24
24
|
example.reporter.message "Supported backends: #{described_class.backends}"
|
25
25
|
end
|
26
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
|
29
|
+
end
|
30
|
+
|
27
31
|
it "raises ArgumentError if given an invalid backend" do
|
28
32
|
expect { described_class.new(:derp) }.to raise_error ArgumentError
|
29
33
|
end
|
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.5.
|
4
|
+
version: 2.5.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Arcieri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- ext/libev/ev.c
|
63
63
|
- ext/libev/ev.h
|
64
64
|
- ext/libev/ev_epoll.c
|
65
|
+
- ext/libev/ev_iouring.c
|
65
66
|
- ext/libev/ev_kqueue.c
|
66
67
|
- ext/libev/ev_linuxaio.c
|
67
68
|
- ext/libev/ev_poll.c
|
@@ -108,8 +109,8 @@ licenses:
|
|
108
109
|
metadata:
|
109
110
|
bug_tracker_uri: https://github.com/socketry/nio4r/issues
|
110
111
|
changelog_uri: https://github.com/socketry/nio4r/blob/master/CHANGES.md
|
111
|
-
documentation_uri: https://www.rubydoc.info/gems/nio4r/2.5.
|
112
|
-
source_code_uri: https://github.com/socketry/nio4r/tree/v2.5.
|
112
|
+
documentation_uri: https://www.rubydoc.info/gems/nio4r/2.5.5
|
113
|
+
source_code_uri: https://github.com/socketry/nio4r/tree/v2.5.5
|
113
114
|
wiki_uri: https://github.com/socketry/nio4r/wiki
|
114
115
|
post_install_message:
|
115
116
|
rdoc_options: []
|