cool.io 1.0.0 → 1.9.0
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
- data/.github/workflows/test.yaml +54 -0
- data/.gitignore +30 -0
- data/.rspec +3 -0
- data/{CHANGES → CHANGES.md} +175 -79
- data/{README.markdown → README.md} +43 -49
- data/Rakefile +44 -69
- data/appveyor.yml +18 -0
- data/cool.io.gemspec +18 -131
- data/examples/callbacked_echo_server.rb +24 -0
- data/ext/cool.io/buffer.c +781 -0
- data/ext/cool.io/cool.io.h +13 -0
- data/ext/cool.io/cool.io_ext.c +1 -0
- data/ext/cool.io/ev_wrap.h +4 -2
- data/ext/cool.io/extconf.rb +27 -16
- data/ext/cool.io/iowatcher.c +17 -8
- data/ext/cool.io/loop.c +36 -84
- data/ext/cool.io/stat_watcher.c +103 -25
- data/ext/cool.io/timer_watcher.c +3 -3
- data/ext/cool.io/utils.c +5 -0
- data/ext/cool.io/watcher.h +1 -1
- data/ext/libev/Changes +152 -3
- data/ext/libev/LICENSE +2 -1
- data/ext/libev/README +8 -8
- data/ext/libev/ev.c +1719 -348
- data/ext/libev/ev.h +146 -118
- data/ext/libev/ev_epoll.c +71 -20
- data/ext/libev/ev_kqueue.c +36 -16
- data/ext/libev/ev_poll.c +14 -11
- data/ext/libev/ev_port.c +43 -18
- data/ext/libev/ev_select.c +82 -25
- data/ext/libev/ev_vars.h +28 -21
- data/ext/libev/ev_win32.c +19 -10
- data/ext/libev/ev_wrap.h +166 -152
- data/ext/libev/test_libev_win32.c +1 -1
- data/gems.rb +9 -0
- data/lib/cool.io/async_watcher.rb +1 -1
- data/lib/cool.io/custom_require.rb +9 -0
- data/lib/cool.io/dns_resolver.rb +30 -22
- data/lib/cool.io/dsl.rb +32 -28
- data/lib/cool.io/io.rb +55 -35
- data/lib/cool.io/iowatcher.rb +1 -1
- data/lib/cool.io/listener.rb +35 -17
- data/lib/cool.io/loop.rb +17 -25
- data/lib/cool.io/meta.rb +6 -5
- data/lib/cool.io/server.rb +5 -4
- data/lib/cool.io/socket.rb +41 -30
- data/lib/cool.io/timer_watcher.rb +1 -1
- data/lib/cool.io/version.rb +7 -0
- data/lib/cool.io.rb +11 -10
- data/lib/coolio.rb +1 -1
- data/libev_ruby_gil.diff +175 -0
- data/libev_win_select.diff +130 -0
- data/spec/async_watcher_spec.rb +5 -5
- data/spec/dns_spec.rb +27 -8
- data/spec/iobuffer_spec.rb +147 -0
- data/spec/spec_helper.rb +15 -1
- data/spec/stat_watcher_spec.rb +81 -0
- data/spec/tcp_server_spec.rb +225 -0
- data/spec/tcp_socket_spec.rb +185 -0
- data/spec/timer_watcher_spec.rb +23 -19
- data/spec/udp_socket_spec.rb +58 -0
- data/spec/unix_listener_spec.rb +8 -8
- data/spec/unix_server_spec.rb +10 -8
- metadata +109 -112
- data/VERSION +0 -1
- data/examples/httpclient.rb +0 -38
- data/ext/http11_client/.gitignore +0 -5
- data/ext/http11_client/LICENSE +0 -31
- data/ext/http11_client/ext_help.h +0 -14
- data/ext/http11_client/extconf.rb +0 -6
- data/ext/http11_client/http11_client.c +0 -300
- data/ext/http11_client/http11_parser.c +0 -403
- data/ext/http11_client/http11_parser.h +0 -48
- data/ext/http11_client/http11_parser.rl +0 -173
- data/lib/cool.io/eventmachine.rb +0 -234
- data/lib/cool.io/http_client.rb +0 -419
- data/lib/rev.rb +0 -4
- data/spec/possible_tests/schedules_other_threads.rb +0 -48
- data/spec/possible_tests/test_on_resolve_failed.rb +0 -9
- data/spec/possible_tests/test_resolves.rb +0 -27
- data/spec/possible_tests/test_write_during_resolve.rb +0 -27
- data/spec/possible_tests/works_straight.rb +0 -71
data/ext/libev/ev_epoll.c
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* libev epoll fd activity backend
|
|
3
3
|
*
|
|
4
|
-
* Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
|
|
4
|
+
* Copyright (c) 2007,2008,2009,2010,2011 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-
|
|
8
8
|
* tion, are permitted provided that the following conditions are met:
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
10
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
11
11
|
* this list of conditions and the following disclaimer.
|
|
12
|
-
*
|
|
12
|
+
*
|
|
13
13
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
14
14
|
* notice, this list of conditions and the following disclaimer in the
|
|
15
15
|
* documentation and/or other materials provided with the distribution.
|
|
16
|
-
*
|
|
16
|
+
*
|
|
17
17
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
18
18
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
|
19
19
|
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
@@ -53,7 +53,8 @@
|
|
|
53
53
|
* (such as files). while not critical, no other advanced interface
|
|
54
54
|
* seems to share this (rather non-unixy) limitation.
|
|
55
55
|
* e) epoll claims to be embeddable, but in practise you never get
|
|
56
|
-
* a ready event for the epoll fd.
|
|
56
|
+
* a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32).
|
|
57
|
+
* f) epoll_ctl returning EPERM means the fd is always ready.
|
|
57
58
|
*
|
|
58
59
|
* lots of "weird code" and complication handling in this file is due
|
|
59
60
|
* to these design problems with epoll, as we try very hard to avoid
|
|
@@ -64,6 +65,8 @@
|
|
|
64
65
|
|
|
65
66
|
#include <sys/epoll.h>
|
|
66
67
|
|
|
68
|
+
#define EV_EMASK_EPERM 0x80
|
|
69
|
+
|
|
67
70
|
static void
|
|
68
71
|
epoll_modify (EV_P_ int fd, int oev, int nev)
|
|
69
72
|
{
|
|
@@ -112,6 +115,21 @@ epoll_modify (EV_P_ int fd, int oev, int nev)
|
|
|
112
115
|
if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev))
|
|
113
116
|
return;
|
|
114
117
|
}
|
|
118
|
+
else if (expect_true (errno == EPERM))
|
|
119
|
+
{
|
|
120
|
+
/* EPERM means the fd is always ready, but epoll is too snobbish */
|
|
121
|
+
/* to handle it, unlike select or poll. */
|
|
122
|
+
anfds [fd].emask = EV_EMASK_EPERM;
|
|
123
|
+
|
|
124
|
+
/* add fd to epoll_eperms, if not already inside */
|
|
125
|
+
if (!(oldmask & EV_EMASK_EPERM))
|
|
126
|
+
{
|
|
127
|
+
array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, EMPTY2);
|
|
128
|
+
epoll_eperms [epoll_epermcnt++] = fd;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
115
133
|
|
|
116
134
|
fd_kill (EV_A_ fd);
|
|
117
135
|
|
|
@@ -125,11 +143,14 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|
|
125
143
|
{
|
|
126
144
|
int i;
|
|
127
145
|
int eventcnt;
|
|
128
|
-
|
|
146
|
+
|
|
147
|
+
if (expect_false (epoll_epermcnt))
|
|
148
|
+
timeout = 0.;
|
|
149
|
+
|
|
129
150
|
/* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */
|
|
130
151
|
/* the default libev max wait time, however. */
|
|
131
152
|
EV_RELEASE_CB;
|
|
132
|
-
eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax,
|
|
153
|
+
eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax, timeout * 1e3);
|
|
133
154
|
EV_ACQUIRE_CB;
|
|
134
155
|
|
|
135
156
|
if (expect_false (eventcnt < 0))
|
|
@@ -149,12 +170,16 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|
|
149
170
|
int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)
|
|
150
171
|
| (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0);
|
|
151
172
|
|
|
152
|
-
/*
|
|
153
|
-
|
|
173
|
+
/*
|
|
174
|
+
* check for spurious notification.
|
|
175
|
+
* this only finds spurious notifications on egen updates
|
|
176
|
+
* other spurious notifications will be found by epoll_ctl, below
|
|
177
|
+
* we assume that fd is always in range, as we never shrink the anfds array
|
|
178
|
+
*/
|
|
154
179
|
if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32)))
|
|
155
180
|
{
|
|
156
181
|
/* recreate kernel state */
|
|
157
|
-
postfork
|
|
182
|
+
postfork |= 2;
|
|
158
183
|
continue;
|
|
159
184
|
}
|
|
160
185
|
|
|
@@ -162,8 +187,15 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|
|
162
187
|
{
|
|
163
188
|
anfds [fd].emask = want;
|
|
164
189
|
|
|
165
|
-
/*
|
|
166
|
-
|
|
190
|
+
/*
|
|
191
|
+
* we received an event but are not interested in it, try mod or del
|
|
192
|
+
* this often happens because we optimistically do not unregister fds
|
|
193
|
+
* when we are no longer interested in them, but also when we get spurious
|
|
194
|
+
* notifications for fds from another process. this is partially handled
|
|
195
|
+
* above with the gencounter check (== our fd is not the event fd), and
|
|
196
|
+
* partially here, when epoll_ctl returns an error (== a child has the fd
|
|
197
|
+
* but we closed it).
|
|
198
|
+
*/
|
|
167
199
|
ev->events = (want & EV_READ ? EPOLLIN : 0)
|
|
168
200
|
| (want & EV_WRITE ? EPOLLOUT : 0);
|
|
169
201
|
|
|
@@ -171,7 +203,7 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|
|
171
203
|
/* which is fortunately easy to do for us. */
|
|
172
204
|
if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev))
|
|
173
205
|
{
|
|
174
|
-
postfork
|
|
206
|
+
postfork |= 2; /* an error occurred, recreate kernel state */
|
|
175
207
|
continue;
|
|
176
208
|
}
|
|
177
209
|
}
|
|
@@ -186,15 +218,31 @@ epoll_poll (EV_P_ ev_tstamp timeout)
|
|
|
186
218
|
epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1);
|
|
187
219
|
epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
|
|
188
220
|
}
|
|
221
|
+
|
|
222
|
+
/* now synthesize events for all fds where epoll fails, while select works... */
|
|
223
|
+
for (i = epoll_epermcnt; i--; )
|
|
224
|
+
{
|
|
225
|
+
int fd = epoll_eperms [i];
|
|
226
|
+
unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE);
|
|
227
|
+
|
|
228
|
+
if (anfds [fd].emask & EV_EMASK_EPERM && events)
|
|
229
|
+
fd_event (EV_A_ fd, events);
|
|
230
|
+
else
|
|
231
|
+
{
|
|
232
|
+
epoll_eperms [i] = epoll_eperms [--epoll_epermcnt];
|
|
233
|
+
anfds [fd].emask = 0;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
189
236
|
}
|
|
190
237
|
|
|
191
|
-
|
|
238
|
+
inline_size
|
|
239
|
+
int
|
|
192
240
|
epoll_init (EV_P_ int flags)
|
|
193
241
|
{
|
|
194
242
|
#ifdef EPOLL_CLOEXEC
|
|
195
243
|
backend_fd = epoll_create1 (EPOLL_CLOEXEC);
|
|
196
244
|
|
|
197
|
-
if (backend_fd
|
|
245
|
+
if (backend_fd < 0 && (errno == EINVAL || errno == ENOSYS))
|
|
198
246
|
#endif
|
|
199
247
|
backend_fd = epoll_create (256);
|
|
200
248
|
|
|
@@ -203,9 +251,9 @@ epoll_init (EV_P_ int flags)
|
|
|
203
251
|
|
|
204
252
|
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
|
|
205
253
|
|
|
206
|
-
|
|
207
|
-
backend_modify
|
|
208
|
-
backend_poll
|
|
254
|
+
backend_mintime = 1e-3; /* epoll does sometimes return early, this is just to avoid the worst */
|
|
255
|
+
backend_modify = epoll_modify;
|
|
256
|
+
backend_poll = epoll_poll;
|
|
209
257
|
|
|
210
258
|
epoll_eventmax = 64; /* initial number of events receivable per poll */
|
|
211
259
|
epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
|
|
@@ -213,13 +261,16 @@ epoll_init (EV_P_ int flags)
|
|
|
213
261
|
return EVBACKEND_EPOLL;
|
|
214
262
|
}
|
|
215
263
|
|
|
216
|
-
|
|
264
|
+
inline_size
|
|
265
|
+
void
|
|
217
266
|
epoll_destroy (EV_P)
|
|
218
267
|
{
|
|
219
268
|
ev_free (epoll_events);
|
|
269
|
+
array_free (epoll_eperm, EMPTY);
|
|
220
270
|
}
|
|
221
271
|
|
|
222
|
-
|
|
272
|
+
inline_size
|
|
273
|
+
void
|
|
223
274
|
epoll_fork (EV_P)
|
|
224
275
|
{
|
|
225
276
|
close (backend_fd);
|
data/ext/libev/ev_kqueue.c
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* libev kqueue backend
|
|
3
3
|
*
|
|
4
|
-
* Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
|
|
4
|
+
* Copyright (c) 2007,2008,2009,2010,2011,2012,2013 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-
|
|
8
8
|
* tion, are permitted provided that the following conditions are met:
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
10
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
11
11
|
* this list of conditions and the following disclaimer.
|
|
12
|
-
*
|
|
12
|
+
*
|
|
13
13
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
14
14
|
* notice, this list of conditions and the following disclaimer in the
|
|
15
15
|
* documentation and/or other materials provided with the distribution.
|
|
16
|
-
*
|
|
16
|
+
*
|
|
17
17
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
18
18
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
|
19
19
|
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
#include <string.h>
|
|
44
44
|
#include <errno.h>
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
inline_speed
|
|
47
|
+
void
|
|
47
48
|
kqueue_change (EV_P_ int fd, int filter, int flags, int fflags)
|
|
48
49
|
{
|
|
49
50
|
++kqueue_changecnt;
|
|
@@ -103,12 +104,12 @@ kqueue_poll (EV_P_ ev_tstamp timeout)
|
|
|
103
104
|
kqueue_changecnt = 0;
|
|
104
105
|
|
|
105
106
|
if (expect_false (res < 0))
|
|
106
|
-
{
|
|
107
|
+
{
|
|
107
108
|
if (errno != EINTR)
|
|
108
109
|
ev_syserr ("(libev) kevent");
|
|
109
110
|
|
|
110
111
|
return;
|
|
111
|
-
}
|
|
112
|
+
}
|
|
112
113
|
|
|
113
114
|
for (i = 0; i < res; ++i)
|
|
114
115
|
{
|
|
@@ -152,18 +153,20 @@ kqueue_poll (EV_P_ ev_tstamp timeout)
|
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
|
|
155
|
-
|
|
156
|
+
inline_size
|
|
157
|
+
int
|
|
156
158
|
kqueue_init (EV_P_ int flags)
|
|
157
159
|
{
|
|
158
|
-
/*
|
|
160
|
+
/* initialize the kernel queue */
|
|
161
|
+
kqueue_fd_pid = getpid ();
|
|
159
162
|
if ((backend_fd = kqueue ()) < 0)
|
|
160
163
|
return 0;
|
|
161
164
|
|
|
162
165
|
fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
|
|
163
166
|
|
|
164
|
-
|
|
165
|
-
backend_modify
|
|
166
|
-
backend_poll
|
|
167
|
+
backend_mintime = 1e-9; /* apparently, they did the right thing in freebsd */
|
|
168
|
+
backend_modify = kqueue_modify;
|
|
169
|
+
backend_poll = kqueue_poll;
|
|
167
170
|
|
|
168
171
|
kqueue_eventmax = 64; /* initial number of events receivable per poll */
|
|
169
172
|
kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
|
|
@@ -175,18 +178,32 @@ kqueue_init (EV_P_ int flags)
|
|
|
175
178
|
return EVBACKEND_KQUEUE;
|
|
176
179
|
}
|
|
177
180
|
|
|
178
|
-
|
|
181
|
+
inline_size
|
|
182
|
+
void
|
|
179
183
|
kqueue_destroy (EV_P)
|
|
180
184
|
{
|
|
181
185
|
ev_free (kqueue_events);
|
|
182
186
|
ev_free (kqueue_changes);
|
|
183
187
|
}
|
|
184
188
|
|
|
185
|
-
|
|
189
|
+
inline_size
|
|
190
|
+
void
|
|
186
191
|
kqueue_fork (EV_P)
|
|
187
192
|
{
|
|
188
|
-
|
|
189
|
-
|
|
193
|
+
/* some BSD kernels don't just destroy the kqueue itself,
|
|
194
|
+
* but also close the fd, which isn't documented, and
|
|
195
|
+
* impossible to support properly.
|
|
196
|
+
* we remember the pid of the kqueue call and only close
|
|
197
|
+
* the fd if the pid is still the same.
|
|
198
|
+
* this leaks fds on sane kernels, but BSD interfaces are
|
|
199
|
+
* notoriously buggy and rarely get fixed.
|
|
200
|
+
*/
|
|
201
|
+
pid_t newpid = getpid ();
|
|
202
|
+
|
|
203
|
+
if (newpid == kqueue_fd_pid)
|
|
204
|
+
close (backend_fd);
|
|
205
|
+
|
|
206
|
+
kqueue_fd_pid = newpid;
|
|
190
207
|
while ((backend_fd = kqueue ()) < 0)
|
|
191
208
|
ev_syserr ("(libev) kqueue");
|
|
192
209
|
|
|
@@ -196,3 +213,6 @@ kqueue_fork (EV_P)
|
|
|
196
213
|
fd_rearm_all (EV_A);
|
|
197
214
|
}
|
|
198
215
|
|
|
216
|
+
/* sys/event.h defines EV_ERROR */
|
|
217
|
+
#undef EV_ERROR
|
|
218
|
+
|
data/ext/libev/ev_poll.c
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* libev poll fd activity backend
|
|
3
3
|
*
|
|
4
|
-
* Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
|
|
4
|
+
* Copyright (c) 2007,2008,2009,2010,2011 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-
|
|
8
8
|
* tion, are permitted provided that the following conditions are met:
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
10
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
11
11
|
* this list of conditions and the following disclaimer.
|
|
12
|
-
*
|
|
12
|
+
*
|
|
13
13
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
14
14
|
* notice, this list of conditions and the following disclaimer in the
|
|
15
15
|
* documentation and/or other materials provided with the distribution.
|
|
16
|
-
*
|
|
16
|
+
*
|
|
17
17
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
18
18
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
|
19
19
|
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
|
|
40
40
|
#include <poll.h>
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
inline_size
|
|
43
|
+
void
|
|
43
44
|
pollidx_init (int *base, int count)
|
|
44
45
|
{
|
|
45
46
|
/* consider using memset (.., -1, ...), which is practically guaranteed
|
|
@@ -92,7 +93,7 @@ poll_poll (EV_P_ ev_tstamp timeout)
|
|
|
92
93
|
int res;
|
|
93
94
|
|
|
94
95
|
EV_RELEASE_CB;
|
|
95
|
-
res = poll (polls, pollcnt,
|
|
96
|
+
res = poll (polls, pollcnt, timeout * 1e3);
|
|
96
97
|
EV_ACQUIRE_CB;
|
|
97
98
|
|
|
98
99
|
if (expect_false (res < 0))
|
|
@@ -126,12 +127,13 @@ poll_poll (EV_P_ ev_tstamp timeout)
|
|
|
126
127
|
}
|
|
127
128
|
}
|
|
128
129
|
|
|
129
|
-
|
|
130
|
+
inline_size
|
|
131
|
+
int
|
|
130
132
|
poll_init (EV_P_ int flags)
|
|
131
133
|
{
|
|
132
|
-
|
|
133
|
-
backend_modify
|
|
134
|
-
backend_poll
|
|
134
|
+
backend_mintime = 1e-3;
|
|
135
|
+
backend_modify = poll_modify;
|
|
136
|
+
backend_poll = poll_poll;
|
|
135
137
|
|
|
136
138
|
pollidxs = 0; pollidxmax = 0;
|
|
137
139
|
polls = 0; pollmax = 0; pollcnt = 0;
|
|
@@ -139,7 +141,8 @@ poll_init (EV_P_ int flags)
|
|
|
139
141
|
return EVBACKEND_POLL;
|
|
140
142
|
}
|
|
141
143
|
|
|
142
|
-
|
|
144
|
+
inline_size
|
|
145
|
+
void
|
|
143
146
|
poll_destroy (EV_P)
|
|
144
147
|
{
|
|
145
148
|
ev_free (pollidxs);
|
data/ext/libev/ev_port.c
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* libev solaris event port backend
|
|
3
3
|
*
|
|
4
|
-
* Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
|
|
4
|
+
* Copyright (c) 2007,2008,2009,2010,2011 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-
|
|
8
8
|
* tion, are permitted provided that the following conditions are met:
|
|
9
|
-
*
|
|
9
|
+
*
|
|
10
10
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
11
11
|
* this list of conditions and the following disclaimer.
|
|
12
|
-
*
|
|
12
|
+
*
|
|
13
13
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
14
14
|
* notice, this list of conditions and the following disclaimer in the
|
|
15
15
|
* documentation and/or other materials provided with the distribution.
|
|
16
|
-
*
|
|
16
|
+
*
|
|
17
17
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
18
18
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
|
19
19
|
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
@@ -37,6 +37,17 @@
|
|
|
37
37
|
* either the BSD or the GPL.
|
|
38
38
|
*/
|
|
39
39
|
|
|
40
|
+
/* useful reading:
|
|
41
|
+
*
|
|
42
|
+
* http://bugs.opensolaris.org/view_bug.do?bug_id=6268715 (random results)
|
|
43
|
+
* http://bugs.opensolaris.org/view_bug.do?bug_id=6455223 (just totally broken)
|
|
44
|
+
* http://bugs.opensolaris.org/view_bug.do?bug_id=6873782 (manpage ETIME)
|
|
45
|
+
* http://bugs.opensolaris.org/view_bug.do?bug_id=6874410 (implementation ETIME)
|
|
46
|
+
* http://www.mail-archive.com/networking-discuss@opensolaris.org/msg11898.html ETIME vs. nget
|
|
47
|
+
* http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/event_port.c (libc)
|
|
48
|
+
* http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/portfs/port.c#1325 (kernel)
|
|
49
|
+
*/
|
|
50
|
+
|
|
40
51
|
#include <sys/types.h>
|
|
41
52
|
#include <sys/time.h>
|
|
42
53
|
#include <poll.h>
|
|
@@ -44,7 +55,8 @@
|
|
|
44
55
|
#include <string.h>
|
|
45
56
|
#include <errno.h>
|
|
46
57
|
|
|
47
|
-
|
|
58
|
+
inline_speed
|
|
59
|
+
void
|
|
48
60
|
port_associate_and_check (EV_P_ int fd, int ev)
|
|
49
61
|
{
|
|
50
62
|
if (0 >
|
|
@@ -85,18 +97,20 @@ port_poll (EV_P_ ev_tstamp timeout)
|
|
|
85
97
|
struct timespec ts;
|
|
86
98
|
uint_t nget = 1;
|
|
87
99
|
|
|
100
|
+
/* we initialise this to something we will skip in the loop, as */
|
|
101
|
+
/* port_getn can return with nget unchanged, but no indication */
|
|
102
|
+
/* whether it was the original value or has been updated :/ */
|
|
103
|
+
port_events [0].portev_source = 0;
|
|
104
|
+
|
|
88
105
|
EV_RELEASE_CB;
|
|
89
106
|
EV_TS_SET (ts, timeout);
|
|
90
107
|
res = port_getn (backend_fd, port_events, port_eventmax, &nget, &ts);
|
|
91
108
|
EV_ACQUIRE_CB;
|
|
92
109
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
110
|
+
/* port_getn may or may not set nget on error */
|
|
111
|
+
/* so we rely on port_events [0].portev_source not being updated */
|
|
112
|
+
if (res == -1 && errno != ETIME && errno != EINTR)
|
|
113
|
+
ev_syserr ("(libev) port_getn (see http://bugs.opensolaris.org/view_bug.do?bug_id=6268715, try LIBEV_FLAGS=3 env variable)");
|
|
100
114
|
|
|
101
115
|
for (i = 0; i < nget; ++i)
|
|
102
116
|
{
|
|
@@ -123,18 +137,27 @@ port_poll (EV_P_ ev_tstamp timeout)
|
|
|
123
137
|
}
|
|
124
138
|
}
|
|
125
139
|
|
|
126
|
-
|
|
140
|
+
inline_size
|
|
141
|
+
int
|
|
127
142
|
port_init (EV_P_ int flags)
|
|
128
143
|
{
|
|
129
144
|
/* Initialize the kernel queue */
|
|
130
145
|
if ((backend_fd = port_create ()) < 0)
|
|
131
146
|
return 0;
|
|
132
147
|
|
|
148
|
+
assert (("libev: PORT_SOURCE_FD must not be zero", PORT_SOURCE_FD));
|
|
149
|
+
|
|
133
150
|
fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
|
|
134
151
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
152
|
+
/* if my reading of the opensolaris kernel sources are correct, then
|
|
153
|
+
* opensolaris does something very stupid: it checks if the time has already
|
|
154
|
+
* elapsed and doesn't round up if that is the case,m otherwise it DOES round
|
|
155
|
+
* up. Since we can't know what the case is, we need to guess by using a
|
|
156
|
+
* "large enough" timeout. Normally, 1e-9 would be correct.
|
|
157
|
+
*/
|
|
158
|
+
backend_mintime = 1e-3; /* needed to compensate for port_getn returning early */
|
|
159
|
+
backend_modify = port_modify;
|
|
160
|
+
backend_poll = port_poll;
|
|
138
161
|
|
|
139
162
|
port_eventmax = 64; /* initial number of events receivable per poll */
|
|
140
163
|
port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
|
|
@@ -142,13 +165,15 @@ port_init (EV_P_ int flags)
|
|
|
142
165
|
return EVBACKEND_PORT;
|
|
143
166
|
}
|
|
144
167
|
|
|
145
|
-
|
|
168
|
+
inline_size
|
|
169
|
+
void
|
|
146
170
|
port_destroy (EV_P)
|
|
147
171
|
{
|
|
148
172
|
ev_free (port_events);
|
|
149
173
|
}
|
|
150
174
|
|
|
151
|
-
|
|
175
|
+
inline_size
|
|
176
|
+
void
|
|
152
177
|
port_fork (EV_P)
|
|
153
178
|
{
|
|
154
179
|
close (backend_fd);
|