nio4r 2.5.4 → 2.5.5
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.
- 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: []
|