xref: /dragonfly/contrib/dhcpcd/src/eloop.c (revision 0ffa96a2)
1 /*
2  * eloop - portable event based main loop.
3  * Copyright (c) 2006-2018 Roy Marples <roy@marples.name>
4  * All rights reserved.
5 
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #if (defined(__unix__) || defined(unix)) && !defined(USG)
29 #include <sys/param.h>
30 #endif
31 #include <sys/time.h>
32 
33 #include <assert.h>
34 #include <errno.h>
35 #include <limits.h>
36 #include <signal.h>
37 #include <stdint.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 
42 /* config.h should define HAVE_KQUEUE, HAVE_EPOLL, etc. */
43 #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_H)
44 #include "config.h"
45 #endif
46 
47 /* Attempt to autodetect kqueue or epoll.
48  * Failing that, fall back to pselect. */
49 #if !defined(HAVE_KQUEUE) && !defined(HAVE_EPOLL) && !defined(HAVE_PSELECT) && \
50     !defined(HAVE_POLLTS) && !defined(HAVE_PPOLL)
51 #if defined(BSD)
52 /* Assume BSD has a working sys/queue.h and kqueue(2) interface. */
53 #define HAVE_SYS_QUEUE_H
54 #define HAVE_KQUEUE
55 #define WARN_SELECT
56 #elif defined(__linux__) || defined(__sun)
57 /* Assume Linux and Solaris have a working epoll(3) interface. */
58 #define HAVE_EPOLL
59 #define WARN_SELECT
60 #else
61 /* pselect(2) is a POSIX standard. */
62 #define HAVE_PSELECT
63 #define WARN_SELECT
64 #endif
65 #endif
66 
67 /* pollts and ppoll require poll.
68  * pselect is wrapped in a pollts/ppoll style interface
69  * and as such require poll as well. */
70 #if defined(HAVE_PSELECT) || defined(HAVE_POLLTS) || defined(HAVE_PPOLL)
71 #ifndef HAVE_POLL
72 #define HAVE_POLL
73 #endif
74 #if defined(HAVE_POLLTS)
75 #define POLLTS pollts
76 #elif defined(HAVE_PPOLL)
77 #define POLLTS ppoll
78 #else
79 #define POLLTS eloop_pollts
80 #define ELOOP_NEED_POLLTS
81 #endif
82 #endif
83 
84 #include "eloop.h"
85 
86 #ifndef UNUSED
87 #define UNUSED(a) (void)((a))
88 #endif
89 #ifndef __unused
90 #ifdef __GNUC__
91 #define __unused   __attribute__((__unused__))
92 #else
93 #define __unused
94 #endif
95 #endif
96 
97 #ifndef MSEC_PER_SEC
98 #define MSEC_PER_SEC	1000L
99 #define NSEC_PER_MSEC	1000000L
100 #endif
101 
102 #if defined(HAVE_KQUEUE)
103 #include <sys/event.h>
104 #include <fcntl.h>
105 #ifdef __NetBSD__
106 /* udata is void * except on NetBSD.
107  * lengths are int except on NetBSD. */
108 #define UPTR(x)	((intptr_t)(x))
109 #define LENC(x)	(x)
110 #else
111 #define UPTR(x)	(x)
112 #define LENC(x)	((int)(x))
113 #endif
114 #elif defined(HAVE_EPOLL)
115 #include <sys/epoll.h>
116 #elif defined(HAVE_POLL)
117 #if defined(HAVE_PSELECT)
118 #include <sys/select.h>
119 #endif
120 #include <poll.h>
121 #endif
122 
123 #ifdef WARN_SELECT
124 #if defined(HAVE_KQUEUE)
125 #pragma message("Compiling eloop with kqueue(2) support.")
126 #elif defined(HAVE_EPOLL)
127 #pragma message("Compiling eloop with epoll(7) support.")
128 #elif defined(HAVE_PSELECT)
129 #pragma message("Compiling eloop with pselect(2) support.")
130 #elif defined(HAVE_PPOLL)
131 #pragma message("Compiling eloop with ppoll(2) support.")
132 #elif defined(HAVE_POLLTS)
133 #pragma message("Compiling eloop with pollts(2) support.")
134 #else
135 #error Unknown select mechanism for eloop
136 #endif
137 #endif
138 
139 /* Our structures require TAILQ macros, which really every libc should
140  * ship as they are useful beyond belief.
141  * Sadly some libc's don't have sys/queue.h and some that do don't have
142  * the TAILQ_FOREACH macro. For those that don't, the application using
143  * this implementation will need to ship a working queue.h somewhere.
144  * If we don't have sys/queue.h found in config.h, then
145  * allow QUEUE_H to override loading queue.h in the current directory. */
146 #ifndef TAILQ_FOREACH
147 #ifdef HAVE_SYS_QUEUE_H
148 #include <sys/queue.h>
149 #elif defined(QUEUE_H)
150 #define __QUEUE_HEADER(x) #x
151 #define _QUEUE_HEADER(x) __QUEUE_HEADER(x)
152 #include _QUEUE_HEADER(QUEUE_H)
153 #else
154 #include "queue.h"
155 #endif
156 #endif
157 
158 struct eloop_event {
159 	TAILQ_ENTRY(eloop_event) next;
160 	int fd;
161 	void (*read_cb)(void *);
162 	void *read_cb_arg;
163 	void (*write_cb)(void *);
164 	void *write_cb_arg;
165 };
166 
167 struct eloop_timeout {
168 	TAILQ_ENTRY(eloop_timeout) next;
169 	struct timespec when;
170 	void (*callback)(void *);
171 	void *arg;
172 	int queue;
173 };
174 
175 struct eloop {
176 	size_t events_len;
177 	TAILQ_HEAD (event_head, eloop_event) events;
178 	struct event_head free_events;
179 	int events_maxfd;
180 	struct eloop_event **event_fds;
181 
182 	TAILQ_HEAD (timeout_head, eloop_timeout) timeouts;
183 	struct timeout_head free_timeouts;
184 
185 	void (*timeout0)(void *);
186 	void *timeout0_arg;
187 	const int *signals;
188 	size_t signals_len;
189 	void (*signal_cb)(int, void *);
190 	void *signal_cb_ctx;
191 
192 #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
193 	int poll_fd;
194 #elif defined(HAVE_POLL)
195 	struct pollfd *fds;
196 	size_t fds_len;
197 #endif
198 
199 	int exitnow;
200 	int exitcode;
201 };
202 
203 #ifdef HAVE_REALLOCARRAY
204 #define	eloop_realloca	reallocarray
205 #else
206 /* Handy routing to check for potential overflow.
207  * reallocarray(3) and reallocarr(3) are not portable. */
208 #define SQRT_SIZE_MAX (((size_t)1) << (sizeof(size_t) * CHAR_BIT / 2))
209 static void *
210 eloop_realloca(void *ptr, size_t n, size_t size)
211 {
212 
213 	if ((n | size) >= SQRT_SIZE_MAX && n > SIZE_MAX / size) {
214 		errno = EOVERFLOW;
215 		return NULL;
216 	}
217 	return realloc(ptr, n * size);
218 }
219 #endif
220 
221 #ifdef HAVE_POLL
222 static void
223 eloop_event_setup_fds(struct eloop *eloop)
224 {
225 	struct eloop_event *e;
226 	size_t i;
227 
228 	i = 0;
229 	TAILQ_FOREACH(e, &eloop->events, next) {
230 		eloop->fds[i].fd = e->fd;
231 		eloop->fds[i].events = 0;
232 		if (e->read_cb)
233 			eloop->fds[i].events |= POLLIN;
234 		if (e->write_cb)
235 			eloop->fds[i].events |= POLLOUT;
236 		eloop->fds[i].revents = 0;
237 		i++;
238 	}
239 }
240 
241 #ifdef ELOOP_NEED_POLLTS
242 /* Wrapper around pselect, to imitate the NetBSD pollts call. */
243 static int
244 eloop_pollts(struct pollfd * fds, nfds_t nfds,
245     const struct timespec *ts, const sigset_t *sigmask)
246 {
247 	fd_set read_fds, write_fds;
248 	nfds_t n;
249 	int maxfd, r;
250 
251 	FD_ZERO(&read_fds);
252 	FD_ZERO(&write_fds);
253 	maxfd = 0;
254 	for (n = 0; n < nfds; n++) {
255 		if (fds[n].events & POLLIN) {
256 			FD_SET(fds[n].fd, &read_fds);
257 			if (fds[n].fd > maxfd)
258 				maxfd = fds[n].fd;
259 		}
260 		if (fds[n].events & POLLOUT) {
261 			FD_SET(fds[n].fd, &write_fds);
262 			if (fds[n].fd > maxfd)
263 				maxfd = fds[n].fd;
264 		}
265 	}
266 
267 	r = pselect(maxfd + 1, &read_fds, &write_fds, NULL, ts, sigmask);
268 	if (r > 0) {
269 		for (n = 0; n < nfds; n++) {
270 			fds[n].revents =
271 			    FD_ISSET(fds[n].fd, &read_fds) ? POLLIN : 0;
272 			if (FD_ISSET(fds[n].fd, &write_fds))
273 				fds[n].revents |= POLLOUT;
274 		}
275 	}
276 
277 	return r;
278 }
279 #endif /* pollts */
280 #else /* !HAVE_POLL */
281 #define eloop_event_setup_fds(a) {}
282 #endif /* HAVE_POLL */
283 
284 int
285 eloop_event_add_rw(struct eloop *eloop, int fd,
286     void (*read_cb)(void *), void *read_cb_arg,
287     void (*write_cb)(void *), void *write_cb_arg)
288 {
289 	struct eloop_event *e;
290 #if defined(HAVE_KQUEUE)
291 	struct kevent ke[2];
292 #elif defined(HAVE_EPOLL)
293 	struct epoll_event epe;
294 #elif defined(HAVE_POLL)
295 	struct pollfd *nfds;
296 #endif
297 
298 	assert(eloop != NULL);
299 	assert(read_cb != NULL || write_cb != NULL);
300 	if (fd == -1) {
301 		errno = EINVAL;
302 		return -1;
303 	}
304 
305 #ifdef HAVE_EPOLL
306 	memset(&epe, 0, sizeof(epe));
307 	epe.data.fd = fd;
308 	epe.events = EPOLLIN;
309 	if (write_cb)
310 		epe.events |= EPOLLOUT;
311 #endif
312 
313 	/* We should only have one callback monitoring the fd. */
314 	if (fd <= eloop->events_maxfd) {
315 		if ((e = eloop->event_fds[fd]) != NULL) {
316 			int error;
317 
318 #if defined(HAVE_KQUEUE)
319 			EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ, EV_ADD,
320 			    0, 0, UPTR(e));
321 			if (write_cb)
322 				EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
323 				    EV_ADD, 0, 0, UPTR(e));
324 			else if (e->write_cb)
325 				EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
326 				    EV_DELETE, 0, 0, UPTR(e));
327 			error = kevent(eloop->poll_fd, ke,
328 			    e->write_cb || write_cb ? 2 : 1, NULL, 0, NULL);
329 #elif defined(HAVE_EPOLL)
330 			epe.data.ptr = e;
331 			error = epoll_ctl(eloop->poll_fd, EPOLL_CTL_MOD,
332 			    fd, &epe);
333 #else
334 			error = 0;
335 #endif
336 			if (read_cb) {
337 				e->read_cb = read_cb;
338 				e->read_cb_arg = read_cb_arg;
339 			}
340 			if (write_cb) {
341 				e->write_cb = write_cb;
342 				e->write_cb_arg = write_cb_arg;
343 			}
344 			eloop_event_setup_fds(eloop);
345 			return error;
346 		}
347 	} else {
348 		struct eloop_event **new_fds;
349 		int maxfd, i;
350 
351 		/* Reserve ourself and 4 more. */
352 		maxfd = fd + 4;
353 		new_fds = eloop_realloca(eloop->event_fds,
354 		    ((size_t)maxfd + 1), sizeof(*eloop->event_fds));
355 		if (new_fds == NULL)
356 			return -1;
357 
358 		/* set new entries NULL as the fd's may not be contiguous. */
359 		for (i = maxfd; i > eloop->events_maxfd; i--)
360 			new_fds[i] = NULL;
361 
362 		eloop->event_fds = new_fds;
363 		eloop->events_maxfd = maxfd;
364 	}
365 
366 	/* Allocate a new event if no free ones already allocated. */
367 	if ((e = TAILQ_FIRST(&eloop->free_events))) {
368 		TAILQ_REMOVE(&eloop->free_events, e, next);
369 	} else {
370 		e = malloc(sizeof(*e));
371 		if (e == NULL)
372 			goto err;
373 	}
374 
375 	/* Ensure we can actually listen to it. */
376 	eloop->events_len++;
377 #ifdef HAVE_POLL
378 	if (eloop->events_len > eloop->fds_len) {
379 		nfds = eloop_realloca(eloop->fds,
380 		    (eloop->fds_len + 5), sizeof(*eloop->fds));
381 		if (nfds == NULL)
382 			goto err;
383 		eloop->fds_len += 5;
384 		eloop->fds = nfds;
385 	}
386 #endif
387 
388 	/* Now populate the structure and add it to the list. */
389 	e->fd = fd;
390 	e->read_cb = read_cb;
391 	e->read_cb_arg = read_cb_arg;
392 	e->write_cb = write_cb;
393 	e->write_cb_arg = write_cb_arg;
394 
395 #if defined(HAVE_KQUEUE)
396 	if (read_cb != NULL)
397 		EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ,
398 		    EV_ADD, 0, 0, UPTR(e));
399 	if (write_cb != NULL)
400 		EV_SET(&ke[1], (uintptr_t)fd, EVFILT_WRITE,
401 		    EV_ADD, 0, 0, UPTR(e));
402 	if (kevent(eloop->poll_fd, ke, write_cb ? 2 : 1, NULL, 0, NULL) == -1)
403 		goto err;
404 #elif defined(HAVE_EPOLL)
405 	epe.data.ptr = e;
406 	if (epoll_ctl(eloop->poll_fd, EPOLL_CTL_ADD, fd, &epe) == -1)
407 		goto err;
408 #endif
409 
410 	TAILQ_INSERT_HEAD(&eloop->events, e, next);
411 	eloop->event_fds[e->fd] = e;
412 	eloop_event_setup_fds(eloop);
413 	return 0;
414 
415 err:
416 	if (e) {
417 		eloop->events_len--;
418 		TAILQ_INSERT_TAIL(&eloop->free_events, e, next);
419 	}
420 	return -1;
421 }
422 
423 int
424 eloop_event_add(struct eloop *eloop, int fd,
425     void (*read_cb)(void *), void *read_cb_arg)
426 {
427 
428 	return eloop_event_add_rw(eloop, fd, read_cb, read_cb_arg, NULL, NULL);
429 }
430 
431 int
432 eloop_event_add_w(struct eloop *eloop, int fd,
433     void (*write_cb)(void *), void *write_cb_arg)
434 {
435 
436 	return eloop_event_add_rw(eloop, fd, NULL,NULL, write_cb, write_cb_arg);
437 }
438 
439 int
440 eloop_event_delete_write(struct eloop *eloop, int fd, int write_only)
441 {
442 	struct eloop_event *e;
443 #if defined(HAVE_KQUEUE)
444 	struct kevent ke[2];
445 #elif defined(HAVE_EPOLL)
446 	struct epoll_event epe;
447 #endif
448 
449 	assert(eloop != NULL);
450 
451 	if (fd > eloop->events_maxfd ||
452 	    (e = eloop->event_fds[fd]) == NULL)
453 	{
454 		errno = ENOENT;
455 		return -1;
456 	}
457 
458 	if (write_only) {
459 		if (e->write_cb == NULL)
460 			return 0;
461 		if (e->read_cb == NULL)
462 			goto remove;
463 		e->write_cb = NULL;
464 		e->write_cb_arg = NULL;
465 #if defined(HAVE_KQUEUE)
466 		EV_SET(&ke[0], (uintptr_t)e->fd,
467 		    EVFILT_WRITE, EV_DELETE, 0, 0, UPTR(NULL));
468 		kevent(eloop->poll_fd, ke, 1, NULL, 0, NULL);
469 #elif defined(HAVE_EPOLL)
470 		memset(&epe, 0, sizeof(epe));
471 		epe.data.fd = e->fd;
472 		epe.data.ptr = e;
473 		epe.events = EPOLLIN;
474 		epoll_ctl(eloop->poll_fd, EPOLL_CTL_MOD, fd, &epe);
475 #endif
476 		eloop_event_setup_fds(eloop);
477 		return 1;
478 	}
479 
480 remove:
481 	TAILQ_REMOVE(&eloop->events, e, next);
482 	eloop->event_fds[e->fd] = NULL;
483 	TAILQ_INSERT_TAIL(&eloop->free_events, e, next);
484 	eloop->events_len--;
485 
486 #if defined(HAVE_KQUEUE)
487 	EV_SET(&ke[0], (uintptr_t)fd, EVFILT_READ,
488 	    EV_DELETE, 0, 0, UPTR(NULL));
489 	if (e->write_cb)
490 		EV_SET(&ke[1], (uintptr_t)fd,
491 		    EVFILT_WRITE, EV_DELETE, 0, 0, UPTR(NULL));
492 	kevent(eloop->poll_fd, ke, e->write_cb ? 2 : 1, NULL, 0, NULL);
493 #elif defined(HAVE_EPOLL)
494 	/* NULL event is safe because we
495 	 * rely on epoll_pwait which as added
496 	 * after the delete without event was fixed. */
497 	epoll_ctl(eloop->poll_fd, EPOLL_CTL_DEL, fd, NULL);
498 #endif
499 
500 	eloop_event_setup_fds(eloop);
501 	return 1;
502 }
503 
504 int
505 eloop_q_timeout_add_tv(struct eloop *eloop, int queue,
506     const struct timespec *when, void (*callback)(void *), void *arg)
507 {
508 	struct timespec now, w;
509 	struct eloop_timeout *t, *tt = NULL;
510 
511 	assert(eloop != NULL);
512 	assert(when != NULL);
513 	assert(callback != NULL);
514 
515 	clock_gettime(CLOCK_MONOTONIC, &now);
516 	timespecadd(&now, when, &w);
517 	/* Check for time_t overflow. */
518 	if (timespeccmp(&w, &now, <)) {
519 		errno = ERANGE;
520 		return -1;
521 	}
522 
523 	/* Remove existing timeout if present. */
524 	TAILQ_FOREACH(t, &eloop->timeouts, next) {
525 		if (t->callback == callback && t->arg == arg) {
526 			TAILQ_REMOVE(&eloop->timeouts, t, next);
527 			break;
528 		}
529 	}
530 
531 	if (t == NULL) {
532 		/* No existing, so allocate or grab one from the free pool. */
533 		if ((t = TAILQ_FIRST(&eloop->free_timeouts))) {
534 			TAILQ_REMOVE(&eloop->free_timeouts, t, next);
535 		} else {
536 			if ((t = malloc(sizeof(*t))) == NULL)
537 				return -1;
538 		}
539 	}
540 
541 	t->when = w;
542 	t->callback = callback;
543 	t->arg = arg;
544 	t->queue = queue;
545 
546 	/* The timeout list should be in chronological order,
547 	 * soonest first. */
548 	TAILQ_FOREACH(tt, &eloop->timeouts, next) {
549 		if (timespeccmp(&t->when, &tt->when, <)) {
550 			TAILQ_INSERT_BEFORE(tt, t, next);
551 			return 0;
552 		}
553 	}
554 	TAILQ_INSERT_TAIL(&eloop->timeouts, t, next);
555 	return 0;
556 }
557 
558 int
559 eloop_q_timeout_add_sec(struct eloop *eloop, int queue, time_t when,
560     void (*callback)(void *), void *arg)
561 {
562 	struct timespec tv;
563 
564 	tv.tv_sec = when;
565 	tv.tv_nsec = 0;
566 	return eloop_q_timeout_add_tv(eloop, queue, &tv, callback, arg);
567 }
568 
569 int
570 eloop_q_timeout_add_msec(struct eloop *eloop, int queue, long when,
571     void (*callback)(void *), void *arg)
572 {
573 	struct timespec tv;
574 
575 	tv.tv_sec = when / MSEC_PER_SEC;
576 	tv.tv_nsec = (when % MSEC_PER_SEC) * NSEC_PER_MSEC;
577 	return eloop_q_timeout_add_tv(eloop, queue, &tv, callback, arg);
578 }
579 
580 #if !defined(HAVE_KQUEUE)
581 static int
582 eloop_timeout_add_now(struct eloop *eloop,
583     void (*callback)(void *), void *arg)
584 {
585 
586 	assert(eloop->timeout0 == NULL);
587 	eloop->timeout0 = callback;
588 	eloop->timeout0_arg = arg;
589 	return 0;
590 }
591 #endif
592 
593 int
594 eloop_q_timeout_delete(struct eloop *eloop, int queue,
595     void (*callback)(void *), void *arg)
596 {
597 	struct eloop_timeout *t, *tt;
598 	int n;
599 
600 	assert(eloop != NULL);
601 
602 	n = 0;
603 	TAILQ_FOREACH_SAFE(t, &eloop->timeouts, next, tt) {
604 		if ((queue == 0 || t->queue == queue) &&
605 		    t->arg == arg &&
606 		    (!callback || t->callback == callback))
607 		{
608 			TAILQ_REMOVE(&eloop->timeouts, t, next);
609 			TAILQ_INSERT_TAIL(&eloop->free_timeouts, t, next);
610 			n++;
611 		}
612 	}
613 	return n;
614 }
615 
616 void
617 eloop_exit(struct eloop *eloop, int code)
618 {
619 
620 	assert(eloop != NULL);
621 
622 	eloop->exitcode = code;
623 	eloop->exitnow = 1;
624 }
625 
626 #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
627 static int
628 eloop_open(struct eloop *eloop)
629 {
630 
631 #if defined(HAVE_KQUEUE1)
632 	return (eloop->poll_fd = kqueue1(O_CLOEXEC));
633 #elif defined(HAVE_KQUEUE)
634 	int i;
635 
636 	if ((eloop->poll_fd = kqueue()) == -1)
637 		return -1;
638 	if ((i = fcntl(eloop->poll_fd, F_GETFD, 0)) == -1 ||
639 	    fcntl(eloop->poll_fd, F_SETFD, i | FD_CLOEXEC) == -1)
640 	{
641 		close(eloop->poll_fd);
642 		eloop->poll_fd = -1;
643 	}
644 
645 	return eloop->poll_fd;
646 #elif defined (HAVE_EPOLL)
647 	return (eloop->poll_fd = epoll_create1(EPOLL_CLOEXEC));
648 #else
649 	return (eloop->poll_fd = -1);
650 #endif
651 }
652 #endif
653 
654 int
655 eloop_requeue(struct eloop *eloop)
656 {
657 #if defined(HAVE_POLL)
658 
659 	UNUSED(eloop);
660 	return 0;
661 #else /* !HAVE_POLL */
662 	struct eloop_event *e;
663 	int error;
664 #if defined(HAVE_KQUEUE)
665 	size_t i;
666 	struct kevent *ke;
667 #elif defined(HAVE_EPOLL)
668 	struct epoll_event epe;
669 #endif
670 
671 	assert(eloop != NULL);
672 
673 	if (eloop->poll_fd != -1)
674 		close(eloop->poll_fd);
675 	if (eloop_open(eloop) == -1)
676 		return -1;
677 #if defined (HAVE_KQUEUE)
678 	i = eloop->signals_len;
679 	TAILQ_FOREACH(e, &eloop->events, next) {
680 		i++;
681 		if (e->write_cb)
682 			i++;
683 	}
684 
685 	if ((ke = malloc(sizeof(*ke) * i)) == NULL)
686 		return -1;
687 
688 	for (i = 0; i < eloop->signals_len; i++)
689 		EV_SET(&ke[i], (uintptr_t)eloop->signals[i],
690 		    EVFILT_SIGNAL, EV_ADD, 0, 0, UPTR(NULL));
691 
692 	TAILQ_FOREACH(e, &eloop->events, next) {
693 		EV_SET(&ke[i], (uintptr_t)e->fd, EVFILT_READ,
694 		    EV_ADD, 0, 0, UPTR(e));
695 		i++;
696 		if (e->write_cb) {
697 			EV_SET(&ke[i], (uintptr_t)e->fd, EVFILT_WRITE,
698 			    EV_ADD, 0, 0, UPTR(e));
699 			i++;
700 		}
701 	}
702 
703 	error =  kevent(eloop->poll_fd, ke, LENC(i), NULL, 0, NULL);
704 	free(ke);
705 
706 #elif defined(HAVE_EPOLL)
707 
708 	error = 0;
709 	TAILQ_FOREACH(e, &eloop->events, next) {
710 		memset(&epe, 0, sizeof(epe));
711 		epe.data.fd = e->fd;
712 		epe.events = EPOLLIN;
713 		if (e->write_cb)
714 			epe.events |= EPOLLOUT;
715 		epe.data.ptr = e;
716 		if (epoll_ctl(eloop->poll_fd, EPOLL_CTL_ADD, e->fd, &epe) == -1)
717 			error = -1;
718 	}
719 #endif
720 
721 	return error;
722 #endif /* HAVE_POLL */
723 }
724 
725 int
726 eloop_signal_set_cb(struct eloop *eloop,
727     const int *signals, size_t signals_len,
728     void (*signal_cb)(int, void *), void *signal_cb_ctx)
729 {
730 
731 	assert(eloop != NULL);
732 
733 	eloop->signals = signals;
734 	eloop->signals_len = signals_len;
735 	eloop->signal_cb = signal_cb;
736 	eloop->signal_cb_ctx = signal_cb_ctx;
737 	return eloop_requeue(eloop);
738 }
739 
740 #ifndef HAVE_KQUEUE
741 struct eloop_siginfo {
742 	int sig;
743 	struct eloop *eloop;
744 };
745 static struct eloop_siginfo _eloop_siginfo;
746 static struct eloop *_eloop;
747 
748 static void
749 eloop_signal1(void *arg)
750 {
751 	struct eloop_siginfo *si = arg;
752 
753 	si->eloop->signal_cb(si->sig, si->eloop->signal_cb_ctx);
754 }
755 
756 static void
757 eloop_signal3(int sig, __unused siginfo_t *siginfo, __unused void *arg)
758 {
759 
760 	/* So that we can operate safely under a signal we instruct
761 	 * eloop to pass a copy of the siginfo structure to handle_signal1
762 	 * as the very first thing to do. */
763 	_eloop_siginfo.eloop = _eloop;
764 	_eloop_siginfo.sig = sig;
765 	eloop_timeout_add_now(_eloop_siginfo.eloop,
766 	    eloop_signal1, &_eloop_siginfo);
767 }
768 #endif
769 
770 int
771 eloop_signal_mask(struct eloop *eloop, sigset_t *oldset)
772 {
773 	sigset_t newset;
774 	size_t i;
775 #ifndef HAVE_KQUEUE
776 	struct sigaction sa;
777 #endif
778 
779 	assert(eloop != NULL);
780 
781 	sigemptyset(&newset);
782 	for (i = 0; i < eloop->signals_len; i++)
783 		sigaddset(&newset, eloop->signals[i]);
784 	if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
785 		return -1;
786 
787 #ifndef HAVE_KQUEUE
788 	_eloop = eloop;
789 
790 	memset(&sa, 0, sizeof(sa));
791 	sa.sa_sigaction = eloop_signal3;
792 	sa.sa_flags = SA_SIGINFO;
793 	sigemptyset(&sa.sa_mask);
794 
795 	for (i = 0; i < eloop->signals_len; i++) {
796 		if (sigaction(eloop->signals[i], &sa, NULL) == -1)
797 			return -1;
798 	}
799 #endif
800 	return 0;
801 }
802 
803 struct eloop *
804 eloop_new(void)
805 {
806 	struct eloop *eloop;
807 	struct timespec now;
808 
809 	/* Check we have a working monotonic clock. */
810 	if (clock_gettime(CLOCK_MONOTONIC, &now) == -1)
811 		return NULL;
812 
813 	eloop = calloc(1, sizeof(*eloop));
814 	if (eloop) {
815 		TAILQ_INIT(&eloop->events);
816 		eloop->events_maxfd = -1;
817 		TAILQ_INIT(&eloop->free_events);
818 		TAILQ_INIT(&eloop->timeouts);
819 		TAILQ_INIT(&eloop->free_timeouts);
820 		eloop->exitcode = EXIT_FAILURE;
821 #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
822 		if (eloop_open(eloop) == -1) {
823 			eloop_free(eloop);
824 			return NULL;
825 		}
826 #endif
827 	}
828 
829 	return eloop;
830 }
831 
832 void eloop_free(struct eloop *eloop)
833 {
834 	struct eloop_event *e;
835 	struct eloop_timeout *t;
836 
837 	if (eloop == NULL)
838 		return;
839 
840 	free(eloop->event_fds);
841 	while ((e = TAILQ_FIRST(&eloop->events))) {
842 		TAILQ_REMOVE(&eloop->events, e, next);
843 		free(e);
844 	}
845 	while ((e = TAILQ_FIRST(&eloop->free_events))) {
846 		TAILQ_REMOVE(&eloop->free_events, e, next);
847 		free(e);
848 	}
849 	while ((t = TAILQ_FIRST(&eloop->timeouts))) {
850 		TAILQ_REMOVE(&eloop->timeouts, t, next);
851 		free(t);
852 	}
853 	while ((t = TAILQ_FIRST(&eloop->free_timeouts))) {
854 		TAILQ_REMOVE(&eloop->free_timeouts, t, next);
855 		free(t);
856 	}
857 #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
858 	close(eloop->poll_fd);
859 #elif defined(HAVE_POLL)
860 	free(eloop->fds);
861 #endif
862 	free(eloop);
863 }
864 
865 int
866 eloop_start(struct eloop *eloop, sigset_t *signals)
867 {
868 	int n;
869 	struct eloop_event *e;
870 	struct eloop_timeout *t;
871 	struct timespec now, ts, *tsp;
872 	void (*t0)(void *);
873 #if defined(HAVE_KQUEUE)
874 	struct kevent ke;
875 	UNUSED(signals);
876 #elif defined(HAVE_EPOLL)
877 	struct epoll_event epe;
878 #endif
879 #ifndef HAVE_KQUEUE
880 	int timeout;
881 #endif
882 
883 	assert(eloop != NULL);
884 
885 	eloop->exitnow = 0;
886 	for (;;) {
887 		if (eloop->exitnow)
888 			break;
889 
890 		/* Run all timeouts first. */
891 		if (eloop->timeout0) {
892 			t0 = eloop->timeout0;
893 			eloop->timeout0 = NULL;
894 			t0(eloop->timeout0_arg);
895 			continue;
896 		}
897 		if ((t = TAILQ_FIRST(&eloop->timeouts))) {
898 			clock_gettime(CLOCK_MONOTONIC, &now);
899 			if (timespeccmp(&now, &t->when, >)) {
900 				TAILQ_REMOVE(&eloop->timeouts, t, next);
901 				t->callback(t->arg);
902 				TAILQ_INSERT_TAIL(&eloop->free_timeouts, t, next);
903 				continue;
904 			}
905 			timespecsub(&t->when, &now, &ts);
906 			tsp = &ts;
907 		} else
908 			/* No timeouts, so wait forever. */
909 			tsp = NULL;
910 
911 		if (tsp == NULL && eloop->events_len == 0)
912 			break;
913 
914 #ifndef HAVE_KQUEUE
915 		if (tsp == NULL)
916 			timeout = -1;
917 		else if (tsp->tv_sec > INT_MAX / 1000 ||
918 		    (tsp->tv_sec == INT_MAX / 1000 &&
919 		    (tsp->tv_nsec + 999999) / 1000000 > INT_MAX % 1000000))
920 			timeout = INT_MAX;
921 		else
922 			timeout = (int)(tsp->tv_sec * 1000 +
923 			    (tsp->tv_nsec + 999999) / 1000000);
924 #endif
925 
926 #if defined(HAVE_KQUEUE)
927 		n = kevent(eloop->poll_fd, NULL, 0, &ke, 1, tsp);
928 #elif defined(HAVE_EPOLL)
929 		if (signals)
930 			n = epoll_pwait(eloop->poll_fd, &epe, 1,
931 			    timeout, signals);
932 		else
933 			n = epoll_wait(eloop->poll_fd, &epe, 1, timeout);
934 #elif defined(HAVE_POLL)
935 		if (signals)
936 			n = POLLTS(eloop->fds, (nfds_t)eloop->events_len,
937 			    tsp, signals);
938 		else
939 			n = poll(eloop->fds, (nfds_t)eloop->events_len,
940 			    timeout);
941 #endif
942 		if (n == -1) {
943 			if (errno == EINTR)
944 				continue;
945 			return -errno;
946 		}
947 
948 		/* Process any triggered events.
949 		 * We go back to the start after calling each callback incase
950 		 * the current event or next event is removed. */
951 #if defined(HAVE_KQUEUE)
952 		if (n) {
953 			if (ke.filter == EVFILT_SIGNAL) {
954 				eloop->signal_cb((int)ke.ident,
955 				    eloop->signal_cb_ctx);
956 				continue;
957 			}
958 			e = (struct eloop_event *)ke.udata;
959 			if (ke.filter == EVFILT_WRITE) {
960 				e->write_cb(e->write_cb_arg);
961 				continue;
962 			} else if (ke.filter == EVFILT_READ) {
963 				e->read_cb(e->read_cb_arg);
964 				continue;
965 			}
966 		}
967 #elif defined(HAVE_EPOLL)
968 		if (n) {
969 			e = (struct eloop_event *)epe.data.ptr;
970 			if (epe.events & EPOLLOUT && e->write_cb != NULL) {
971 				e->write_cb(e->write_cb_arg);
972 				continue;
973 			}
974 			if (epe.events &
975 			    (EPOLLIN | EPOLLERR | EPOLLHUP) &&
976 			    e->read_cb != NULL)
977 			{
978 				e->read_cb(e->read_cb_arg);
979 				continue;
980 			}
981 		}
982 #elif defined(HAVE_POLL)
983 		if (n > 0) {
984 			size_t i;
985 
986 			for (i = 0; i < eloop->events_len; i++) {
987 				if (eloop->fds[i].revents & POLLOUT) {
988 					e = eloop->event_fds[eloop->fds[i].fd];
989 					if (e->write_cb != NULL) {
990 						e->write_cb(e->write_cb_arg);
991 						break;
992 					}
993 				}
994 				if (eloop->fds[i].revents) {
995 					e = eloop->event_fds[eloop->fds[i].fd];
996 					if (e->read_cb != NULL) {
997 						e->read_cb(e->read_cb_arg);
998 						break;
999 					}
1000 				}
1001 			}
1002 		}
1003 #endif
1004 	}
1005 
1006 	return eloop->exitcode;
1007 }
1008