epoll.c revision 1.1.1.1.4.2 1 /* $NetBSD: epoll.c,v 1.1.1.1.4.2 2014/05/22 15:50:13 yamt Exp $ */
2
3 /*
4 * Copyright 2000-2007 Niels Provos <provos (at) citi.umich.edu>
5 * Copyright 2007-2012 Niels Provos, Nick Mathewson
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 #include "event2/event-config.h"
30 #include "evconfig-private.h"
31
32 #ifdef EVENT__HAVE_EPOLL
33
34 #include <stdint.h>
35 #include <sys/types.h>
36 #include <sys/resource.h>
37 #ifdef EVENT__HAVE_SYS_TIME_H
38 #include <sys/time.h>
39 #endif
40 #include <sys/queue.h>
41 #include <sys/epoll.h>
42 #include <signal.h>
43 #include <limits.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <unistd.h>
48 #include <errno.h>
49 #ifdef EVENT__HAVE_FCNTL_H
50 #include <fcntl.h>
51 #endif
52 #ifdef EVENT__HAVE_SYS_TIMERFD_H
53 #include <sys/timerfd.h>
54 #endif
55
56 #include "event-internal.h"
57 #include "evsignal-internal.h"
58 #include "event2/thread.h"
59 #include "evthread-internal.h"
60 #include "log-internal.h"
61 #include "evmap-internal.h"
62 #include "changelist-internal.h"
63 #include "time-internal.h"
64
65 #if defined(EVENT__HAVE_SYS_TIMERFD_H) && \
66 defined(EVENT__HAVE_TIMERFD_CREATE) && \
67 defined(HAVE_POSIX_MONOTONIC) && defined(TFD_NONBLOCK) && \
68 defined(TFD_CLOEXEC)
69 /* Note that we only use timerfd if TFD_NONBLOCK and TFD_CLOEXEC are available
70 and working. This means that we can't support it on 2.6.25 (where timerfd
71 was introduced) or 2.6.26, since 2.6.27 introduced those flags.
72 */
73 #define USING_TIMERFD
74 #endif
75
76 struct epollop {
77 struct epoll_event *events;
78 int nevents;
79 int epfd;
80 #ifdef USING_TIMERFD
81 int timerfd;
82 #endif
83 };
84
85 static void *epoll_init(struct event_base *);
86 static int epoll_dispatch(struct event_base *, struct timeval *);
87 static void epoll_dealloc(struct event_base *);
88
89 static const struct eventop epollops_changelist = {
90 "epoll (with changelist)",
91 epoll_init,
92 event_changelist_add_,
93 event_changelist_del_,
94 epoll_dispatch,
95 epoll_dealloc,
96 1, /* need reinit */
97 EV_FEATURE_ET|EV_FEATURE_O1,
98 EVENT_CHANGELIST_FDINFO_SIZE
99 };
100
101
102 static int epoll_nochangelist_add(struct event_base *base, evutil_socket_t fd,
103 short old, short events, void *p);
104 static int epoll_nochangelist_del(struct event_base *base, evutil_socket_t fd,
105 short old, short events, void *p);
106
107 const struct eventop epollops = {
108 "epoll",
109 epoll_init,
110 epoll_nochangelist_add,
111 epoll_nochangelist_del,
112 epoll_dispatch,
113 epoll_dealloc,
114 1, /* need reinit */
115 EV_FEATURE_ET|EV_FEATURE_O1,
116 0
117 };
118
119 #define INITIAL_NEVENT 32
120 #define MAX_NEVENT 4096
121
122 /* On Linux kernels at least up to 2.6.24.4, epoll can't handle timeout
123 * values bigger than (LONG_MAX - 999ULL)/HZ. HZ in the wild can be
124 * as big as 1000, and LONG_MAX can be as small as (1<<31)-1, so the
125 * largest number of msec we can support here is 2147482. Let's
126 * round that down by 47 seconds.
127 */
128 #define MAX_EPOLL_TIMEOUT_MSEC (35*60*1000)
129
130 static void *
131 epoll_init(struct event_base *base)
132 {
133 int epfd = -1;
134 struct epollop *epollop;
135
136 #ifdef EVENT__HAVE_EPOLL_CREATE1
137 /* First, try the shiny new epoll_create1 interface, if we have it. */
138 epfd = epoll_create1(EPOLL_CLOEXEC);
139 #endif
140 if (epfd == -1) {
141 /* Initialize the kernel queue using the old interface. (The
142 size field is ignored since 2.6.8.) */
143 if ((epfd = epoll_create(32000)) == -1) {
144 if (errno != ENOSYS)
145 event_warn("epoll_create");
146 return (NULL);
147 }
148 evutil_make_socket_closeonexec(epfd);
149 }
150
151 if (!(epollop = mm_calloc(1, sizeof(struct epollop)))) {
152 close(epfd);
153 return (NULL);
154 }
155
156 epollop->epfd = epfd;
157
158 /* Initialize fields */
159 epollop->events = mm_calloc(INITIAL_NEVENT, sizeof(struct epoll_event));
160 if (epollop->events == NULL) {
161 mm_free(epollop);
162 close(epfd);
163 return (NULL);
164 }
165 epollop->nevents = INITIAL_NEVENT;
166
167 if ((base->flags & EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST) != 0 ||
168 ((base->flags & EVENT_BASE_FLAG_IGNORE_ENV) == 0 &&
169 evutil_getenv_("EVENT_EPOLL_USE_CHANGELIST") != NULL)) {
170
171 base->evsel = &epollops_changelist;
172 }
173
174 #ifdef USING_TIMERFD
175 /*
176 The epoll interface ordinarily gives us one-millisecond precision,
177 so on Linux it makes perfect sense to use the CLOCK_MONOTONIC_COARSE
178 timer. But when the user has set the new PRECISE_TIMER flag for an
179 event_base, we can try to use timerfd to give them finer granularity.
180 */
181 if ((base->flags & EVENT_BASE_FLAG_PRECISE_TIMER) &&
182 base->monotonic_timer.monotonic_clock == CLOCK_MONOTONIC) {
183 int fd;
184 fd = epollop->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC);
185 if (epollop->timerfd >= 0) {
186 struct epoll_event epev;
187 memset(&epev, 0, sizeof(epev));
188 epev.data.fd = epollop->timerfd;
189 epev.events = EPOLLIN;
190 if (epoll_ctl(epollop->epfd, EPOLL_CTL_ADD, fd, &epev) < 0) {
191 event_warn("epoll_ctl(timerfd)");
192 close(fd);
193 epollop->timerfd = -1;
194 }
195 } else {
196 if (errno != EINVAL && errno != ENOSYS) {
197 /* These errors probably mean that we were
198 * compiled with timerfd/TFD_* support, but
199 * we're running on a kernel that lacks those.
200 */
201 event_warn("timerfd_create");
202 }
203 epollop->timerfd = -1;
204 }
205 } else {
206 epollop->timerfd = -1;
207 }
208 #endif
209
210 evsig_init_(base);
211
212 return (epollop);
213 }
214
215 static const char *
216 change_to_string(int change)
217 {
218 change &= (EV_CHANGE_ADD|EV_CHANGE_DEL);
219 if (change == EV_CHANGE_ADD) {
220 return "add";
221 } else if (change == EV_CHANGE_DEL) {
222 return "del";
223 } else if (change == 0) {
224 return "none";
225 } else {
226 return "???";
227 }
228 }
229
230 static const char *
231 epoll_op_to_string(int op)
232 {
233 return op == EPOLL_CTL_ADD?"ADD":
234 op == EPOLL_CTL_DEL?"DEL":
235 op == EPOLL_CTL_MOD?"MOD":
236 "???";
237 }
238
239 /*
240 Here are the values we're masking off to decide what operations to do.
241 Note that since EV_READ|EV_WRITE.
242
243 Note also that this table is a little sparse, since ADD+DEL is
244 nonsensical ("xxx" in the list below.)
245
246 Note also also that we are shifting old_events by only 3 bits, since
247 EV_READ is 2 and EV_WRITE is 4.
248
249 The table was auto-generated with a python script, according to this
250 pseudocode:
251
252 If either the read or the write change is add+del:
253 This is impossible; Set op==-1, events=0.
254 Else, if either the read or the write change is add:
255 Set events to 0.
256 If the read change is add, or
257 (the read change is not del, and ev_read is in old_events):
258 Add EPOLLIN to events.
259 If the write change is add, or
260 (the write change is not del, and ev_write is in old_events):
261 Add EPOLLOUT to events.
262
263 If old_events is set:
264 Set op to EPOLL_CTL_MOD [*1,*2]
265 Else:
266 Set op to EPOLL_CTL_ADD [*3]
267
268 Else, if the read or the write change is del:
269 Set op to EPOLL_CTL_DEL.
270 If the read change is del:
271 If the write change is del:
272 Set events to EPOLLIN|EPOLLOUT
273 Else if ev_write is in old_events:
274 Set events to EPOLLOUT
275 Set op to EPOLL_CTL_MOD
276 Else
277 Set events to EPOLLIN
278 Else:
279 {The write change is del.}
280 If ev_read is in old_events:
281 Set events to EPOLLIN
282 Set op to EPOLL_CTL_MOD
283 Else:
284 Set the events to EPOLLOUT
285
286 Else:
287 There is no read or write change; set op to 0 and events to 0.
288
289 The logic is a little tricky, since we had no events set on the fd before,
290 we need to set op="ADD" and set events=the events we want to add. If we
291 had any events set on the fd before, and we want any events to remain on
292 the fd, we need to say op="MOD" and set events=the events we want to
293 remain. But if we want to delete the last event, we say op="DEL" and
294 set events=(any non-null pointer).
295
296 [*1] This MOD is only a guess. MOD might fail with ENOENT if the file was
297 closed and a new file was opened with the same fd. If so, we'll retry
298 with ADD.
299
300 [*2] We can't replace this with a no-op even if old_events is the same as
301 the new events: if the file was closed and reopened, we need to retry
302 with an ADD. (We do a MOD in this case since "no change" is more
303 common than "close and reopen", so we'll usually wind up doing 1
304 syscalls instead of 2.)
305
306 [*3] This ADD is only a guess. There is a fun Linux kernel issue where if
307 you have two fds for the same file (via dup) and you ADD one to an
308 epfd, then close it, then re-create it with the same fd (via dup2 or an
309 unlucky dup), then try to ADD it again, you'll get an EEXIST, since the
310 struct epitem is not actually removed from the struct eventpoll until
311 the file itself is closed.
312
313 EV_CHANGE_ADD==1
314 EV_CHANGE_DEL==2
315 EV_READ ==2
316 EV_WRITE ==4
317 Bit 0: read change is add
318 Bit 1: read change is del
319 Bit 2: write change is add
320 Bit 3: write change is del
321 Bit 4: old events had EV_READ
322 Bit 5: old events had EV_WRITE
323 */
324
325 #define INDEX(c) \
326 ( (((c)->read_change&(EV_CHANGE_ADD|EV_CHANGE_DEL))) | \
327 (((c)->write_change&(EV_CHANGE_ADD|EV_CHANGE_DEL)) << 2) | \
328 (((c)->old_events&(EV_READ|EV_WRITE)) << 3) )
329
330 #if EV_READ != 2 || EV_WRITE != 4 || EV_CHANGE_ADD != 1 || EV_CHANGE_DEL != 2
331 #error "Libevent's internals changed! Regenerate the op_table in epoll.c"
332 #endif
333
334 static const struct operation {
335 int events;
336 int op;
337 } op_table[] = {
338 { 0, 0 }, /* old= 0, write: 0, read: 0 */
339 { EPOLLIN, EPOLL_CTL_ADD }, /* old= 0, write: 0, read:add */
340 { EPOLLIN, EPOLL_CTL_DEL }, /* old= 0, write: 0, read:del */
341 { 0, -1 }, /* old= 0, write: 0, read:xxx */
342 { EPOLLOUT, EPOLL_CTL_ADD }, /* old= 0, write:add, read: 0 */
343 { EPOLLIN|EPOLLOUT, EPOLL_CTL_ADD },/* old= 0, write:add, read:add */
344 { EPOLLOUT, EPOLL_CTL_ADD }, /* old= 0, write:add, read:del */
345 { 0, -1 }, /* old= 0, write:add, read:xxx */
346 { EPOLLOUT, EPOLL_CTL_DEL }, /* old= 0, write:del, read: 0 */
347 { EPOLLIN, EPOLL_CTL_ADD }, /* old= 0, write:del, read:add */
348 { EPOLLIN|EPOLLOUT, EPOLL_CTL_DEL },/* old= 0, write:del, read:del */
349 { 0, -1 }, /* old= 0, write:del, read:xxx */
350 { 0, -1 }, /* old= 0, write:xxx, read: 0 */
351 { 0, -1 }, /* old= 0, write:xxx, read:add */
352 { 0, -1 }, /* old= 0, write:xxx, read:del */
353 { 0, -1 }, /* old= 0, write:xxx, read:xxx */
354 { 0, 0 }, /* old= r, write: 0, read: 0 */
355 { EPOLLIN, EPOLL_CTL_MOD }, /* old= r, write: 0, read:add */
356 { EPOLLIN, EPOLL_CTL_DEL }, /* old= r, write: 0, read:del */
357 { 0, -1 }, /* old= r, write: 0, read:xxx */
358 { EPOLLIN|EPOLLOUT, EPOLL_CTL_MOD },/* old= r, write:add, read: 0 */
359 { EPOLLIN|EPOLLOUT, EPOLL_CTL_MOD },/* old= r, write:add, read:add */
360 { EPOLLOUT, EPOLL_CTL_MOD }, /* old= r, write:add, read:del */
361 { 0, -1 }, /* old= r, write:add, read:xxx */
362 { EPOLLIN, EPOLL_CTL_MOD }, /* old= r, write:del, read: 0 */
363 { EPOLLIN, EPOLL_CTL_MOD }, /* old= r, write:del, read:add */
364 { EPOLLIN|EPOLLOUT, EPOLL_CTL_DEL },/* old= r, write:del, read:del */
365 { 0, -1 }, /* old= r, write:del, read:xxx */
366 { 0, -1 }, /* old= r, write:xxx, read: 0 */
367 { 0, -1 }, /* old= r, write:xxx, read:add */
368 { 0, -1 }, /* old= r, write:xxx, read:del */
369 { 0, -1 }, /* old= r, write:xxx, read:xxx */
370 { 0, 0 }, /* old= w, write: 0, read: 0 */
371 { EPOLLIN|EPOLLOUT, EPOLL_CTL_MOD },/* old= w, write: 0, read:add */
372 { EPOLLOUT, EPOLL_CTL_MOD }, /* old= w, write: 0, read:del */
373 { 0, -1 }, /* old= w, write: 0, read:xxx */
374 { EPOLLOUT, EPOLL_CTL_MOD }, /* old= w, write:add, read: 0 */
375 { EPOLLIN|EPOLLOUT, EPOLL_CTL_MOD },/* old= w, write:add, read:add */
376 { EPOLLOUT, EPOLL_CTL_MOD }, /* old= w, write:add, read:del */
377 { 0, -1 }, /* old= w, write:add, read:xxx */
378 { EPOLLOUT, EPOLL_CTL_DEL }, /* old= w, write:del, read: 0 */
379 { EPOLLIN, EPOLL_CTL_MOD }, /* old= w, write:del, read:add */
380 { EPOLLIN|EPOLLOUT, EPOLL_CTL_DEL },/* old= w, write:del, read:del */
381 { 0, -1 }, /* old= w, write:del, read:xxx */
382 { 0, -1 }, /* old= w, write:xxx, read: 0 */
383 { 0, -1 }, /* old= w, write:xxx, read:add */
384 { 0, -1 }, /* old= w, write:xxx, read:del */
385 { 0, -1 }, /* old= w, write:xxx, read:xxx */
386 { 0, 0 }, /* old=rw, write: 0, read: 0 */
387 { EPOLLIN|EPOLLOUT, EPOLL_CTL_MOD },/* old=rw, write: 0, read:add */
388 { EPOLLOUT, EPOLL_CTL_MOD }, /* old=rw, write: 0, read:del */
389 { 0, -1 }, /* old=rw, write: 0, read:xxx */
390 { EPOLLIN|EPOLLOUT, EPOLL_CTL_MOD },/* old=rw, write:add, read: 0 */
391 { EPOLLIN|EPOLLOUT, EPOLL_CTL_MOD },/* old=rw, write:add, read:add */
392 { EPOLLOUT, EPOLL_CTL_MOD }, /* old=rw, write:add, read:del */
393 { 0, -1 }, /* old=rw, write:add, read:xxx */
394 { EPOLLIN, EPOLL_CTL_MOD }, /* old=rw, write:del, read: 0 */
395 { EPOLLIN, EPOLL_CTL_MOD }, /* old=rw, write:del, read:add */
396 { EPOLLIN|EPOLLOUT, EPOLL_CTL_DEL },/* old=rw, write:del, read:del */
397 { 0, -1 }, /* old=rw, write:del, read:xxx */
398 { 0, -1 }, /* old=rw, write:xxx, read: 0 */
399 { 0, -1 }, /* old=rw, write:xxx, read:add */
400 { 0, -1 }, /* old=rw, write:xxx, read:del */
401 { 0, -1 }, /* old=rw, write:xxx, read:xxx */
402 };
403
404 static int
405 epoll_apply_one_change(struct event_base *base,
406 struct epollop *epollop,
407 const struct event_change *ch)
408 {
409 struct epoll_event epev;
410 int op, events = 0;
411 int idx;
412
413 idx = INDEX(ch);
414 op = op_table[idx].op;
415 events = op_table[idx].events;
416
417 if (!events) {
418 EVUTIL_ASSERT(op == 0);
419 return 0;
420 }
421
422 if ((ch->read_change|ch->write_change) & EV_CHANGE_ET)
423 events |= EPOLLET;
424
425 memset(&epev, 0, sizeof(epev));
426 epev.data.fd = ch->fd;
427 epev.events = events;
428 if (epoll_ctl(epollop->epfd, op, ch->fd, &epev) == 0) {
429 event_debug(("Epoll %s(%d) on fd %d okay. [old events were %d; read change was %d; write change was %d]",
430 epoll_op_to_string(op),
431 (int)epev.events,
432 (int)ch->fd,
433 ch->old_events,
434 ch->read_change,
435 ch->write_change));
436 return 0;
437 }
438
439 switch (op) {
440 case EPOLL_CTL_MOD:
441 if (errno == ENOENT) {
442 /* If a MOD operation fails with ENOENT, the
443 * fd was probably closed and re-opened. We
444 * should retry the operation as an ADD.
445 */
446 if (epoll_ctl(epollop->epfd, EPOLL_CTL_ADD, ch->fd, &epev) == -1) {
447 event_warn("Epoll MOD(%d) on %d retried as ADD; that failed too",
448 (int)epev.events, ch->fd);
449 return -1;
450 } else {
451 event_debug(("Epoll MOD(%d) on %d retried as ADD; succeeded.",
452 (int)epev.events,
453 ch->fd));
454 return 0;
455 }
456 }
457 break;
458 case EPOLL_CTL_ADD:
459 if (errno == EEXIST) {
460 /* If an ADD operation fails with EEXIST,
461 * either the operation was redundant (as with a
462 * precautionary add), or we ran into a fun
463 * kernel bug where using dup*() to duplicate the
464 * same file into the same fd gives you the same epitem
465 * rather than a fresh one. For the second case,
466 * we must retry with MOD. */
467 if (epoll_ctl(epollop->epfd, EPOLL_CTL_MOD, ch->fd, &epev) == -1) {
468 event_warn("Epoll ADD(%d) on %d retried as MOD; that failed too",
469 (int)epev.events, ch->fd);
470 return -1;
471 } else {
472 event_debug(("Epoll ADD(%d) on %d retried as MOD; succeeded.",
473 (int)epev.events,
474 ch->fd));
475 return 0;
476 }
477 }
478 break;
479 case EPOLL_CTL_DEL:
480 if (errno == ENOENT || errno == EBADF || errno == EPERM) {
481 /* If a delete fails with one of these errors,
482 * that's fine too: we closed the fd before we
483 * got around to calling epoll_dispatch. */
484 event_debug(("Epoll DEL(%d) on fd %d gave %s: DEL was unnecessary.",
485 (int)epev.events,
486 ch->fd,
487 strerror(errno)));
488 return 0;
489 }
490 break;
491 default:
492 break;
493 }
494
495 event_warn("Epoll %s(%d) on fd %d failed. Old events were %d; read change was %d (%s); write change was %d (%s)",
496 epoll_op_to_string(op),
497 (int)epev.events,
498 ch->fd,
499 ch->old_events,
500 ch->read_change,
501 change_to_string(ch->read_change),
502 ch->write_change,
503 change_to_string(ch->write_change));
504
505 return -1;
506 }
507
508 static int
509 epoll_apply_changes(struct event_base *base)
510 {
511 struct event_changelist *changelist = &base->changelist;
512 struct epollop *epollop = base->evbase;
513 struct event_change *ch;
514
515 int r = 0;
516 int i;
517
518 for (i = 0; i < changelist->n_changes; ++i) {
519 ch = &changelist->changes[i];
520 if (epoll_apply_one_change(base, epollop, ch) < 0)
521 r = -1;
522 }
523
524 return (r);
525 }
526
527 static int
528 epoll_nochangelist_add(struct event_base *base, evutil_socket_t fd,
529 short old, short events, void *p)
530 {
531 struct event_change ch;
532 ch.fd = fd;
533 ch.old_events = old;
534 ch.read_change = ch.write_change = 0;
535 if (events & EV_WRITE)
536 ch.write_change = EV_CHANGE_ADD |
537 (events & EV_ET);
538 if (events & EV_READ)
539 ch.read_change = EV_CHANGE_ADD |
540 (events & EV_ET);
541
542 return epoll_apply_one_change(base, base->evbase, &ch);
543 }
544
545 static int
546 epoll_nochangelist_del(struct event_base *base, evutil_socket_t fd,
547 short old, short events, void *p)
548 {
549 struct event_change ch;
550 ch.fd = fd;
551 ch.old_events = old;
552 ch.read_change = ch.write_change = 0;
553 if (events & EV_WRITE)
554 ch.write_change = EV_CHANGE_DEL;
555 if (events & EV_READ)
556 ch.read_change = EV_CHANGE_DEL;
557
558 return epoll_apply_one_change(base, base->evbase, &ch);
559 }
560
561 static int
562 epoll_dispatch(struct event_base *base, struct timeval *tv)
563 {
564 struct epollop *epollop = base->evbase;
565 struct epoll_event *events = epollop->events;
566 int i, res;
567 long timeout = -1;
568
569 #ifdef USING_TIMERFD
570 if (epollop->timerfd >= 0) {
571 struct itimerspec is;
572 is.it_interval.tv_sec = 0;
573 is.it_interval.tv_nsec = 0;
574 if (tv == NULL) {
575 /* No timeout; disarm the timer. */
576 is.it_value.tv_sec = 0;
577 is.it_value.tv_nsec = 0;
578 } else {
579 if (tv->tv_sec == 0 && tv->tv_usec == 0) {
580 /* we need to exit immediately; timerfd can't
581 * do that. */
582 timeout = 0;
583 }
584 is.it_value.tv_sec = tv->tv_sec;
585 is.it_value.tv_nsec = tv->tv_usec * 1000;
586 }
587 /* TODO: we could avoid unnecessary syscalls here by only
588 calling timerfd_settime when the top timeout changes, or
589 when we're called with a different timeval.
590 */
591 if (timerfd_settime(epollop->timerfd, 0, &is, NULL) < 0) {
592 event_warn("timerfd_settime");
593 }
594 } else
595 #endif
596 if (tv != NULL) {
597 timeout = evutil_tv_to_msec_(tv);
598 if (timeout < 0 || timeout > MAX_EPOLL_TIMEOUT_MSEC) {
599 /* Linux kernels can wait forever if the timeout is
600 * too big; see comment on MAX_EPOLL_TIMEOUT_MSEC. */
601 timeout = MAX_EPOLL_TIMEOUT_MSEC;
602 }
603 }
604
605 epoll_apply_changes(base);
606 event_changelist_remove_all_(&base->changelist, base);
607
608 EVBASE_RELEASE_LOCK(base, th_base_lock);
609
610 res = epoll_wait(epollop->epfd, events, epollop->nevents, timeout);
611
612 EVBASE_ACQUIRE_LOCK(base, th_base_lock);
613
614 if (res == -1) {
615 if (errno != EINTR) {
616 event_warn("epoll_wait");
617 return (-1);
618 }
619
620 return (0);
621 }
622
623 event_debug(("%s: epoll_wait reports %d", __func__, res));
624 EVUTIL_ASSERT(res <= epollop->nevents);
625
626 for (i = 0; i < res; i++) {
627 int what = events[i].events;
628 short ev = 0;
629 #ifdef USING_TIMERFD
630 if (events[i].data.fd == epollop->timerfd)
631 continue;
632 #endif
633
634 if (what & (EPOLLHUP|EPOLLERR)) {
635 ev = EV_READ | EV_WRITE;
636 } else {
637 if (what & EPOLLIN)
638 ev |= EV_READ;
639 if (what & EPOLLOUT)
640 ev |= EV_WRITE;
641 }
642
643 if (!ev)
644 continue;
645
646 evmap_io_active_(base, events[i].data.fd, ev | EV_ET);
647 }
648
649 if (res == epollop->nevents && epollop->nevents < MAX_NEVENT) {
650 /* We used all of the event space this time. We should
651 be ready for more events next time. */
652 int new_nevents = epollop->nevents * 2;
653 struct epoll_event *new_events;
654
655 new_events = mm_realloc(epollop->events,
656 new_nevents * sizeof(struct epoll_event));
657 if (new_events) {
658 epollop->events = new_events;
659 epollop->nevents = new_nevents;
660 }
661 }
662
663 return (0);
664 }
665
666
667 static void
668 epoll_dealloc(struct event_base *base)
669 {
670 struct epollop *epollop = base->evbase;
671
672 evsig_dealloc_(base);
673 if (epollop->events)
674 mm_free(epollop->events);
675 if (epollop->epfd >= 0)
676 close(epollop->epfd);
677 #ifdef USING_TIMERFD
678 if (epollop->timerfd >= 0)
679 close(epollop->timerfd);
680 #endif
681
682 memset(epollop, 0, sizeof(struct epollop));
683 mm_free(epollop);
684 }
685
686 #endif /* EVENT__HAVE_EPOLL */
687