nio4r 0.2.0 → 2.7.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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data/ext/libev/Changes +232 -3
- data/ext/libev/LICENSE +2 -1
- data/ext/libev/README +11 -10
- data/ext/libev/ev.c +2249 -473
- data/ext/libev/ev.h +165 -135
- data/ext/libev/ev_epoll.c +68 -36
- data/ext/libev/ev_iouring.c +694 -0
- data/ext/libev/ev_kqueue.c +44 -18
- data/ext/libev/ev_linuxaio.c +620 -0
- data/ext/libev/ev_poll.c +28 -20
- data/ext/libev/ev_port.c +23 -10
- data/ext/libev/ev_select.c +18 -12
- data/ext/libev/ev_vars.h +65 -19
- data/ext/libev/ev_win32.c +16 -7
- data/ext/libev/ev_wrap.h +236 -160
- data/ext/nio4r/.clang-format +16 -0
- data/ext/nio4r/bytebuffer.c +465 -0
- data/ext/nio4r/extconf.rb +44 -35
- data/ext/nio4r/libev.h +3 -4
- data/ext/nio4r/monitor.c +186 -54
- data/ext/nio4r/nio4r.h +17 -23
- data/ext/nio4r/nio4r_ext.c +11 -3
- data/ext/nio4r/org/nio4r/ByteBuffer.java +295 -0
- data/ext/nio4r/org/nio4r/Monitor.java +176 -0
- data/ext/nio4r/org/nio4r/Nio4r.java +104 -0
- data/ext/nio4r/org/nio4r/Selector.java +297 -0
- data/ext/nio4r/selector.c +350 -182
- data/lib/nio/bytebuffer.rb +235 -0
- data/lib/nio/monitor.rb +100 -8
- data/lib/nio/selector.rb +110 -44
- data/lib/nio/version.rb +8 -1
- data/lib/nio.rb +47 -16
- data/lib/nio4r.rb +7 -0
- data/license.md +80 -0
- data/readme.md +91 -0
- data/releases.md +343 -0
- data.tar.gz.sig +2 -0
- metadata +114 -79
- metadata.gz.sig +0 -0
- data/.gitignore +0 -20
- data/.rspec +0 -4
- data/.travis.yml +0 -7
- data/CHANGES.md +0 -10
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -20
- data/README.md +0 -171
- data/Rakefile +0 -9
- data/examples/echo_server.rb +0 -38
- data/ext/libev/README.embed +0 -3
- data/ext/libev/test_libev_win32.c +0 -123
- data/lib/nio/jruby/monitor.rb +0 -42
- data/lib/nio/jruby/selector.rb +0 -135
- data/nio4r.gemspec +0 -22
- data/spec/nio/monitor_spec.rb +0 -46
- data/spec/nio/selector_spec.rb +0 -269
- data/spec/spec_helper.rb +0 -3
- data/tasks/extension.rake +0 -10
- data/tasks/rspec.rake +0 -7
data/ext/libev/ev_epoll.c
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* libev epoll fd activity backend
|
|
3
3
|
*
|
|
4
|
-
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
|
|
4
|
+
* Copyright (c) 2007,2008,2009,2010,2011,2016,2017,2019 Marc Alexander Lehmann <libev@schmorp.de>
|
|
5
5
|
* All rights reserved.
|
|
6
6
|
*
|
|
7
7
|
* Redistribution and use in source and binary forms, with or without modifica-
|
|
@@ -93,10 +93,10 @@ epoll_modify (EV_P_ int fd, int oev, int nev)
|
|
|
93
93
|
ev.events = (nev & EV_READ ? EPOLLIN : 0)
|
|
94
94
|
| (nev & EV_WRITE ? EPOLLOUT : 0);
|
|
95
95
|
|
|
96
|
-
if (
|
|
96
|
+
if (ecb_expect_true (!epoll_ctl (backend_fd, oev && oldmask != nev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev)))
|
|
97
97
|
return;
|
|
98
98
|
|
|
99
|
-
if (
|
|
99
|
+
if (ecb_expect_true (errno == ENOENT))
|
|
100
100
|
{
|
|
101
101
|
/* if ENOENT then the fd went away, so try to do the right thing */
|
|
102
102
|
if (!nev)
|
|
@@ -105,7 +105,7 @@ epoll_modify (EV_P_ int fd, int oev, int nev)
|
|
|
105
105
|
if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev))
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
108
|
-
else if (
|
|
108
|
+
else if (ecb_expect_true (errno == EEXIST))
|
|
109
109
|
{
|
|
110
110
|
/* EEXIST means we ignored a previous DEL, but the fd is still active */
|
|
111
111
|
/* if the kernel mask is the same as the new mask, we assume it hasn't changed */
|
|
@@ -115,7 +115,7 @@ epoll_modify (EV_P_ int fd, int oev, int nev)
|
|
|
115
115
|
if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev))
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
|
-
else if (
|
|
118
|
+
else if (ecb_expect_true (errno == EPERM))
|
|
119
119
|
{
|
|
120
120
|
/* EPERM means the fd is always ready, but epoll is too snobbish */
|
|
121
121
|
/* to handle it, unlike select or poll. */
|
|
@@ -124,12 +124,14 @@ epoll_modify (EV_P_ int fd, int oev, int nev)
|
|
|
124
124
|
/* add fd to epoll_eperms, if not already inside */
|
|
125
125
|
if (!(oldmask & EV_EMASK_EPERM))
|
|
126
126
|
{
|
|
127
|
-
array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1,
|
|
127
|
+
array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, array_needsize_noinit);
|
|
128
128
|
epoll_eperms [epoll_epermcnt++] = fd;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
|
+
else
|
|
134
|
+
assert (("libev: I/O watcher with invalid fd found in epoll_ctl", errno != EBADF && errno != ELOOP && errno != EINVAL));
|
|
133
135
|
|
|
134
136
|
fd_kill (EV_A_ fd);
|
|
135
137
|
|
|
@@ -144,14 +146,16 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|
|
144
146
|
int i;
|
|
145
147
|
int eventcnt;
|
|
146
148
|
|
|
149
|
+
if (ecb_expect_false (epoll_epermcnt))
|
|
150
|
+
timeout = EV_TS_CONST (0.);
|
|
151
|
+
|
|
147
152
|
/* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */
|
|
148
153
|
/* the default libev max wait time, however. */
|
|
149
154
|
EV_RELEASE_CB;
|
|
150
|
-
eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax,
|
|
151
|
-
epoll_epermcnt ? 0 : ev_timeout_to_ms (timeout));
|
|
155
|
+
eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax, EV_TS_TO_MSEC (timeout));
|
|
152
156
|
EV_ACQUIRE_CB;
|
|
153
157
|
|
|
154
|
-
if (
|
|
158
|
+
if (ecb_expect_false (eventcnt < 0))
|
|
155
159
|
{
|
|
156
160
|
if (errno != EINTR)
|
|
157
161
|
ev_syserr ("(libev) epoll_wait");
|
|
@@ -168,21 +172,34 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|
|
168
172
|
int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)
|
|
169
173
|
| (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0);
|
|
170
174
|
|
|
171
|
-
/*
|
|
172
|
-
|
|
173
|
-
|
|
175
|
+
/*
|
|
176
|
+
* check for spurious notification.
|
|
177
|
+
* this only finds spurious notifications on egen updates
|
|
178
|
+
* other spurious notifications will be found by epoll_ctl, below
|
|
179
|
+
* we assume that fd is always in range, as we never shrink the anfds array
|
|
180
|
+
*/
|
|
181
|
+
if (ecb_expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32)))
|
|
174
182
|
{
|
|
175
183
|
/* recreate kernel state */
|
|
176
|
-
postfork
|
|
184
|
+
postfork |= 2;
|
|
177
185
|
continue;
|
|
178
186
|
}
|
|
179
187
|
|
|
180
|
-
if (
|
|
188
|
+
if (ecb_expect_false (got & ~want))
|
|
181
189
|
{
|
|
182
190
|
anfds [fd].emask = want;
|
|
183
191
|
|
|
184
|
-
/*
|
|
185
|
-
|
|
192
|
+
/*
|
|
193
|
+
* we received an event but are not interested in it, try mod or del
|
|
194
|
+
* this often happens because we optimistically do not unregister fds
|
|
195
|
+
* when we are no longer interested in them, but also when we get spurious
|
|
196
|
+
* notifications for fds from another process. this is partially handled
|
|
197
|
+
* above with the gencounter check (== our fd is not the event fd), and
|
|
198
|
+
* partially here, when epoll_ctl returns an error (== a child has the fd
|
|
199
|
+
* but we closed it).
|
|
200
|
+
* note: for events such as POLLHUP, where we can't know whether it refers
|
|
201
|
+
* to EV_READ or EV_WRITE, we might issue redundant EPOLL_CTL_MOD calls.
|
|
202
|
+
*/
|
|
186
203
|
ev->events = (want & EV_READ ? EPOLLIN : 0)
|
|
187
204
|
| (want & EV_WRITE ? EPOLLOUT : 0);
|
|
188
205
|
|
|
@@ -190,7 +207,7 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|
|
190
207
|
/* which is fortunately easy to do for us. */
|
|
191
208
|
if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev))
|
|
192
209
|
{
|
|
193
|
-
postfork
|
|
210
|
+
postfork |= 2; /* an error occurred, recreate kernel state */
|
|
194
211
|
continue;
|
|
195
212
|
}
|
|
196
213
|
}
|
|
@@ -199,7 +216,7 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|
|
199
216
|
}
|
|
200
217
|
|
|
201
218
|
/* if the receive array was full, increase its size */
|
|
202
|
-
if (
|
|
219
|
+
if (ecb_expect_false (eventcnt == epoll_eventmax))
|
|
203
220
|
{
|
|
204
221
|
ev_free (epoll_events);
|
|
205
222
|
epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1);
|
|
@@ -215,28 +232,43 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|
|
215
232
|
if (anfds [fd].emask & EV_EMASK_EPERM && events)
|
|
216
233
|
fd_event (EV_A_ fd, events);
|
|
217
234
|
else
|
|
218
|
-
|
|
235
|
+
{
|
|
236
|
+
epoll_eperms [i] = epoll_eperms [--epoll_epermcnt];
|
|
237
|
+
anfds [fd].emask = 0;
|
|
238
|
+
}
|
|
219
239
|
}
|
|
220
240
|
}
|
|
221
241
|
|
|
222
|
-
int
|
|
223
|
-
|
|
242
|
+
static int
|
|
243
|
+
epoll_epoll_create (void)
|
|
224
244
|
{
|
|
225
|
-
|
|
226
|
-
backend_fd = epoll_create1 (EPOLL_CLOEXEC);
|
|
245
|
+
int fd;
|
|
227
246
|
|
|
228
|
-
|
|
247
|
+
#if defined EPOLL_CLOEXEC && !defined __ANDROID__
|
|
248
|
+
fd = epoll_create1 (EPOLL_CLOEXEC);
|
|
249
|
+
|
|
250
|
+
if (fd < 0 && (errno == EINVAL || errno == ENOSYS))
|
|
229
251
|
#endif
|
|
230
|
-
|
|
252
|
+
{
|
|
253
|
+
fd = epoll_create (256);
|
|
231
254
|
|
|
232
|
-
|
|
233
|
-
|
|
255
|
+
if (fd >= 0)
|
|
256
|
+
fcntl (fd, F_SETFD, FD_CLOEXEC);
|
|
257
|
+
}
|
|
234
258
|
|
|
235
|
-
|
|
259
|
+
return fd;
|
|
260
|
+
}
|
|
236
261
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
262
|
+
inline_size
|
|
263
|
+
int
|
|
264
|
+
epoll_init (EV_P_ int flags)
|
|
265
|
+
{
|
|
266
|
+
if ((backend_fd = epoll_epoll_create ()) < 0)
|
|
267
|
+
return 0;
|
|
268
|
+
|
|
269
|
+
backend_mintime = EV_TS_CONST (1e-3); /* epoll does sometimes return early, this is just to avoid the worst */
|
|
270
|
+
backend_modify = epoll_modify;
|
|
271
|
+
backend_poll = epoll_poll;
|
|
240
272
|
|
|
241
273
|
epoll_eventmax = 64; /* initial number of events receivable per poll */
|
|
242
274
|
epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
|
|
@@ -244,23 +276,23 @@ epoll_init (EV_P_ int flags)
|
|
|
244
276
|
return EVBACKEND_EPOLL;
|
|
245
277
|
}
|
|
246
278
|
|
|
247
|
-
|
|
279
|
+
inline_size
|
|
280
|
+
void
|
|
248
281
|
epoll_destroy (EV_P)
|
|
249
282
|
{
|
|
250
283
|
ev_free (epoll_events);
|
|
251
284
|
array_free (epoll_eperm, EMPTY);
|
|
252
285
|
}
|
|
253
286
|
|
|
254
|
-
|
|
287
|
+
ecb_cold
|
|
288
|
+
static void
|
|
255
289
|
epoll_fork (EV_P)
|
|
256
290
|
{
|
|
257
291
|
close (backend_fd);
|
|
258
292
|
|
|
259
|
-
while ((backend_fd =
|
|
293
|
+
while ((backend_fd = epoll_epoll_create ()) < 0)
|
|
260
294
|
ev_syserr ("(libev) epoll_create");
|
|
261
295
|
|
|
262
|
-
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
|
|
263
|
-
|
|
264
296
|
fd_rearm_all (EV_A);
|
|
265
297
|
}
|
|
266
298
|
|