xref: /freebsd/contrib/pf/libevent/poll.c (revision 67ecd4f3)
167ecd4f3SMax Laier /*	$OpenBSD: poll.c,v 1.2 2002/06/25 15:50:15 mickey Exp $	*/
267ecd4f3SMax Laier 
367ecd4f3SMax Laier /*
467ecd4f3SMax Laier  * Copyright 2000-2003 Niels Provos <provos@citi.umich.edu>
567ecd4f3SMax Laier  * All rights reserved.
667ecd4f3SMax Laier  *
767ecd4f3SMax Laier  * Redistribution and use in source and binary forms, with or without
867ecd4f3SMax Laier  * modification, are permitted provided that the following conditions
967ecd4f3SMax Laier  * are met:
1067ecd4f3SMax Laier  * 1. Redistributions of source code must retain the above copyright
1167ecd4f3SMax Laier  *    notice, this list of conditions and the following disclaimer.
1267ecd4f3SMax Laier  * 2. Redistributions in binary form must reproduce the above copyright
1367ecd4f3SMax Laier  *    notice, this list of conditions and the following disclaimer in the
1467ecd4f3SMax Laier  *    documentation and/or other materials provided with the distribution.
1567ecd4f3SMax Laier  * 3. The name of the author may not be used to endorse or promote products
1667ecd4f3SMax Laier  *    derived from this software without specific prior written permission.
1767ecd4f3SMax Laier  *
1867ecd4f3SMax Laier  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1967ecd4f3SMax Laier  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2067ecd4f3SMax Laier  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2167ecd4f3SMax Laier  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2267ecd4f3SMax Laier  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2367ecd4f3SMax Laier  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2467ecd4f3SMax Laier  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2567ecd4f3SMax Laier  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2667ecd4f3SMax Laier  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2767ecd4f3SMax Laier  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2867ecd4f3SMax Laier  */
2967ecd4f3SMax Laier #ifdef HAVE_CONFIG_H
3067ecd4f3SMax Laier #include "config.h"
3167ecd4f3SMax Laier #endif
3267ecd4f3SMax Laier 
3367ecd4f3SMax Laier #include <sys/types.h>
3467ecd4f3SMax Laier #ifdef HAVE_SYS_TIME_H
3567ecd4f3SMax Laier #include <sys/time.h>
3667ecd4f3SMax Laier #else
3767ecd4f3SMax Laier #include <sys/_time.h>
3867ecd4f3SMax Laier #endif
3967ecd4f3SMax Laier #include <sys/queue.h>
4067ecd4f3SMax Laier #include <sys/tree.h>
4167ecd4f3SMax Laier #include <poll.h>
4267ecd4f3SMax Laier #include <signal.h>
4367ecd4f3SMax Laier #include <stdio.h>
4467ecd4f3SMax Laier #include <stdlib.h>
4567ecd4f3SMax Laier #include <string.h>
4667ecd4f3SMax Laier #include <unistd.h>
4767ecd4f3SMax Laier #include <errno.h>
4867ecd4f3SMax Laier #ifdef CHECK_INVARIANTS
4967ecd4f3SMax Laier #include <assert.h>
5067ecd4f3SMax Laier #endif
5167ecd4f3SMax Laier 
5267ecd4f3SMax Laier #include "event.h"
5367ecd4f3SMax Laier #include "event-internal.h"
5467ecd4f3SMax Laier #include "evsignal.h"
5567ecd4f3SMax Laier #include "log.h"
5667ecd4f3SMax Laier 
5767ecd4f3SMax Laier extern volatile sig_atomic_t evsignal_caught;
5867ecd4f3SMax Laier 
5967ecd4f3SMax Laier struct pollop {
6067ecd4f3SMax Laier 	int event_count;		/* Highest number alloc */
6167ecd4f3SMax Laier 	int nfds;                       /* Size of event_* */
6267ecd4f3SMax Laier 	int fd_count;                   /* Size of idxplus1_by_fd */
6367ecd4f3SMax Laier 	struct pollfd *event_set;
6467ecd4f3SMax Laier 	struct event **event_r_back;
6567ecd4f3SMax Laier 	struct event **event_w_back;
6667ecd4f3SMax Laier 	int *idxplus1_by_fd; /* Index into event_set by fd; we add 1 so
6767ecd4f3SMax Laier 			      * that 0 (which is easy to memset) can mean
6867ecd4f3SMax Laier 			      * "no entry." */
6967ecd4f3SMax Laier };
7067ecd4f3SMax Laier 
7167ecd4f3SMax Laier void *poll_init	(void);
7267ecd4f3SMax Laier int poll_add		(void *, struct event *);
7367ecd4f3SMax Laier int poll_del		(void *, struct event *);
7467ecd4f3SMax Laier int poll_recalc		(struct event_base *, void *, int);
7567ecd4f3SMax Laier int poll_dispatch	(struct event_base *, void *, struct timeval *);
7667ecd4f3SMax Laier void poll_dealloc	(void *);
7767ecd4f3SMax Laier 
7867ecd4f3SMax Laier const struct eventop pollops = {
7967ecd4f3SMax Laier 	"poll",
8067ecd4f3SMax Laier 	poll_init,
8167ecd4f3SMax Laier 	poll_add,
8267ecd4f3SMax Laier 	poll_del,
8367ecd4f3SMax Laier 	poll_recalc,
8467ecd4f3SMax Laier 	poll_dispatch,
8567ecd4f3SMax Laier 	poll_dealloc
8667ecd4f3SMax Laier };
8767ecd4f3SMax Laier 
8867ecd4f3SMax Laier void *
poll_init(void)8967ecd4f3SMax Laier poll_init(void)
9067ecd4f3SMax Laier {
9167ecd4f3SMax Laier 	struct pollop *pollop;
9267ecd4f3SMax Laier 
9367ecd4f3SMax Laier 	/* Disable poll when this environment variable is set */
9467ecd4f3SMax Laier 	if (getenv("EVENT_NOPOLL"))
9567ecd4f3SMax Laier 		return (NULL);
9667ecd4f3SMax Laier 
9767ecd4f3SMax Laier 	if (!(pollop = calloc(1, sizeof(struct pollop))))
9867ecd4f3SMax Laier 		return (NULL);
9967ecd4f3SMax Laier 
10067ecd4f3SMax Laier 	evsignal_init();
10167ecd4f3SMax Laier 
10267ecd4f3SMax Laier 	return (pollop);
10367ecd4f3SMax Laier }
10467ecd4f3SMax Laier 
10567ecd4f3SMax Laier /*
10667ecd4f3SMax Laier  * Called with the highest fd that we know about.  If it is 0, completely
10767ecd4f3SMax Laier  * recalculate everything.
10867ecd4f3SMax Laier  */
10967ecd4f3SMax Laier 
11067ecd4f3SMax Laier int
poll_recalc(struct event_base * base,void * arg,int max)11167ecd4f3SMax Laier poll_recalc(struct event_base *base, void *arg, int max)
11267ecd4f3SMax Laier {
11367ecd4f3SMax Laier 	return (0);
11467ecd4f3SMax Laier }
11567ecd4f3SMax Laier 
11667ecd4f3SMax Laier #ifdef CHECK_INVARIANTS
11767ecd4f3SMax Laier static void
poll_check_ok(struct pollop * pop)11867ecd4f3SMax Laier poll_check_ok(struct pollop *pop)
11967ecd4f3SMax Laier {
12067ecd4f3SMax Laier 	int i, idx;
12167ecd4f3SMax Laier 	struct event *ev;
12267ecd4f3SMax Laier 
12367ecd4f3SMax Laier 	for (i = 0; i < pop->fd_count; ++i) {
12467ecd4f3SMax Laier 		idx = pop->idxplus1_by_fd[i]-1;
12567ecd4f3SMax Laier 		if (idx < 0)
12667ecd4f3SMax Laier 			continue;
12767ecd4f3SMax Laier 		assert(pop->event_set[idx].fd == i);
12867ecd4f3SMax Laier 		if (pop->event_set[idx].events & POLLIN) {
12967ecd4f3SMax Laier 			ev = pop->event_r_back[idx];
13067ecd4f3SMax Laier 			assert(ev);
13167ecd4f3SMax Laier 			assert(ev->ev_events & EV_READ);
13267ecd4f3SMax Laier 			assert(ev->ev_fd == i);
13367ecd4f3SMax Laier 		}
13467ecd4f3SMax Laier 		if (pop->event_set[idx].events & POLLOUT) {
13567ecd4f3SMax Laier 			ev = pop->event_w_back[idx];
13667ecd4f3SMax Laier 			assert(ev);
13767ecd4f3SMax Laier 			assert(ev->ev_events & EV_WRITE);
13867ecd4f3SMax Laier 			assert(ev->ev_fd == i);
13967ecd4f3SMax Laier 		}
14067ecd4f3SMax Laier 	}
14167ecd4f3SMax Laier 	for (i = 0; i < pop->nfds; ++i) {
14267ecd4f3SMax Laier 		struct pollfd *pfd = &pop->event_set[i];
14367ecd4f3SMax Laier 		assert(pop->idxplus1_by_fd[pfd->fd] == i+1);
14467ecd4f3SMax Laier 	}
14567ecd4f3SMax Laier }
14667ecd4f3SMax Laier #else
14767ecd4f3SMax Laier #define poll_check_ok(pop)
14867ecd4f3SMax Laier #endif
14967ecd4f3SMax Laier 
15067ecd4f3SMax Laier int
poll_dispatch(struct event_base * base,void * arg,struct timeval * tv)15167ecd4f3SMax Laier poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
15267ecd4f3SMax Laier {
15367ecd4f3SMax Laier 	int res, i, sec, nfds;
15467ecd4f3SMax Laier 	struct pollop *pop = arg;
15567ecd4f3SMax Laier 
15667ecd4f3SMax Laier 	poll_check_ok(pop);
15767ecd4f3SMax Laier 	sec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
15867ecd4f3SMax Laier 	nfds = pop->nfds;
15967ecd4f3SMax Laier 	res = poll(pop->event_set, nfds, sec);
16067ecd4f3SMax Laier 
16167ecd4f3SMax Laier 	if (res == -1) {
16267ecd4f3SMax Laier 		if (errno != EINTR) {
16367ecd4f3SMax Laier                         event_warn("poll");
16467ecd4f3SMax Laier 			return (-1);
16567ecd4f3SMax Laier 		}
16667ecd4f3SMax Laier 
16767ecd4f3SMax Laier 		evsignal_process();
16867ecd4f3SMax Laier 		return (0);
16967ecd4f3SMax Laier 	} else if (evsignal_caught)
17067ecd4f3SMax Laier 		evsignal_process();
17167ecd4f3SMax Laier 
17267ecd4f3SMax Laier 	event_debug(("%s: poll reports %d", __func__, res));
17367ecd4f3SMax Laier 
17467ecd4f3SMax Laier 	if (res == 0)
17567ecd4f3SMax Laier 		return (0);
17667ecd4f3SMax Laier 
17767ecd4f3SMax Laier 	for (i = 0; i < nfds; i++) {
17867ecd4f3SMax Laier 		int what = pop->event_set[i].revents;
17967ecd4f3SMax Laier 		struct event *r_ev = NULL, *w_ev = NULL;
18067ecd4f3SMax Laier 		if (!what)
18167ecd4f3SMax Laier 			continue;
18267ecd4f3SMax Laier 
18367ecd4f3SMax Laier 		res = 0;
18467ecd4f3SMax Laier 
18567ecd4f3SMax Laier 		/* If the file gets closed notify */
18667ecd4f3SMax Laier 		if (what & (POLLHUP|POLLERR))
18767ecd4f3SMax Laier 			what |= POLLIN|POLLOUT;
18867ecd4f3SMax Laier 		if (what & POLLIN) {
18967ecd4f3SMax Laier 			res |= EV_READ;
19067ecd4f3SMax Laier 			r_ev = pop->event_r_back[i];
19167ecd4f3SMax Laier 		}
19267ecd4f3SMax Laier 		if (what & POLLOUT) {
19367ecd4f3SMax Laier 			res |= EV_WRITE;
19467ecd4f3SMax Laier 			w_ev = pop->event_w_back[i];
19567ecd4f3SMax Laier 		}
19667ecd4f3SMax Laier 		if (res == 0)
19767ecd4f3SMax Laier 			continue;
19867ecd4f3SMax Laier 
19967ecd4f3SMax Laier 		if (r_ev && (res & r_ev->ev_events)) {
20067ecd4f3SMax Laier 			if (!(r_ev->ev_events & EV_PERSIST))
20167ecd4f3SMax Laier 				event_del(r_ev);
20267ecd4f3SMax Laier 			event_active(r_ev, res & r_ev->ev_events, 1);
20367ecd4f3SMax Laier 		}
20467ecd4f3SMax Laier 		if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) {
20567ecd4f3SMax Laier 			if (!(w_ev->ev_events & EV_PERSIST))
20667ecd4f3SMax Laier 				event_del(w_ev);
20767ecd4f3SMax Laier 			event_active(w_ev, res & w_ev->ev_events, 1);
20867ecd4f3SMax Laier 		}
20967ecd4f3SMax Laier 	}
21067ecd4f3SMax Laier 
21167ecd4f3SMax Laier 	return (0);
21267ecd4f3SMax Laier }
21367ecd4f3SMax Laier 
21467ecd4f3SMax Laier int
poll_add(void * arg,struct event * ev)21567ecd4f3SMax Laier poll_add(void *arg, struct event *ev)
21667ecd4f3SMax Laier {
21767ecd4f3SMax Laier 	struct pollop *pop = arg;
21867ecd4f3SMax Laier 	struct pollfd *pfd = NULL;
21967ecd4f3SMax Laier 	int i;
22067ecd4f3SMax Laier 
22167ecd4f3SMax Laier 	if (ev->ev_events & EV_SIGNAL)
22267ecd4f3SMax Laier 		return (evsignal_add(ev));
22367ecd4f3SMax Laier 	if (!(ev->ev_events & (EV_READ|EV_WRITE)))
22467ecd4f3SMax Laier 		return (0);
22567ecd4f3SMax Laier 
22667ecd4f3SMax Laier 	poll_check_ok(pop);
22767ecd4f3SMax Laier 	if (pop->nfds + 1 >= pop->event_count) {
22867ecd4f3SMax Laier 		struct pollfd *tmp_event_set;
22967ecd4f3SMax Laier 		struct event **tmp_event_r_back;
23067ecd4f3SMax Laier 		struct event **tmp_event_w_back;
23167ecd4f3SMax Laier 		int tmp_event_count;
23267ecd4f3SMax Laier 
23367ecd4f3SMax Laier 		if (pop->event_count < 32)
23467ecd4f3SMax Laier 			tmp_event_count = 32;
23567ecd4f3SMax Laier 		else
23667ecd4f3SMax Laier 			tmp_event_count = pop->event_count * 2;
23767ecd4f3SMax Laier 
23867ecd4f3SMax Laier 		/* We need more file descriptors */
23967ecd4f3SMax Laier 		tmp_event_set = realloc(pop->event_set,
24067ecd4f3SMax Laier 				 tmp_event_count * sizeof(struct pollfd));
24167ecd4f3SMax Laier 		if (tmp_event_set == NULL) {
24267ecd4f3SMax Laier 			event_warn("realloc");
24367ecd4f3SMax Laier 			return (-1);
24467ecd4f3SMax Laier 		}
24567ecd4f3SMax Laier 		pop->event_set = tmp_event_set;
24667ecd4f3SMax Laier 
24767ecd4f3SMax Laier 		tmp_event_r_back = realloc(pop->event_r_back,
24867ecd4f3SMax Laier 			    tmp_event_count * sizeof(struct event *));
24967ecd4f3SMax Laier 		if (tmp_event_r_back == NULL) {
25067ecd4f3SMax Laier 			/* event_set overallocated; that's okay. */
25167ecd4f3SMax Laier 			event_warn("realloc");
25267ecd4f3SMax Laier 			return (-1);
25367ecd4f3SMax Laier 		}
25467ecd4f3SMax Laier 		pop->event_r_back = tmp_event_r_back;
25567ecd4f3SMax Laier 
25667ecd4f3SMax Laier 		tmp_event_w_back = realloc(pop->event_w_back,
25767ecd4f3SMax Laier 			    tmp_event_count * sizeof(struct event *));
25867ecd4f3SMax Laier 		if (tmp_event_w_back == NULL) {
25967ecd4f3SMax Laier 			/* event_set and event_r_back overallocated; that's
26067ecd4f3SMax Laier 			 * okay. */
26167ecd4f3SMax Laier 			event_warn("realloc");
26267ecd4f3SMax Laier 			return (-1);
26367ecd4f3SMax Laier 		}
26467ecd4f3SMax Laier 		pop->event_w_back = tmp_event_w_back;
26567ecd4f3SMax Laier 
26667ecd4f3SMax Laier 		pop->event_count = tmp_event_count;
26767ecd4f3SMax Laier 	}
26867ecd4f3SMax Laier 	if (ev->ev_fd >= pop->fd_count) {
26967ecd4f3SMax Laier 		int *tmp_idxplus1_by_fd;
27067ecd4f3SMax Laier 		int new_count;
27167ecd4f3SMax Laier 		if (pop->fd_count < 32)
27267ecd4f3SMax Laier 			new_count = 32;
27367ecd4f3SMax Laier 		else
27467ecd4f3SMax Laier 			new_count = pop->fd_count * 2;
27567ecd4f3SMax Laier 		while (new_count <= ev->ev_fd)
27667ecd4f3SMax Laier 			new_count *= 2;
27767ecd4f3SMax Laier 		tmp_idxplus1_by_fd =
27867ecd4f3SMax Laier 			realloc(pop->idxplus1_by_fd, new_count * sizeof(int));
27967ecd4f3SMax Laier 		if (tmp_idxplus1_by_fd == NULL) {
28067ecd4f3SMax Laier 			event_warn("realloc");
28167ecd4f3SMax Laier 			return (-1);
28267ecd4f3SMax Laier 		}
28367ecd4f3SMax Laier 		pop->idxplus1_by_fd = tmp_idxplus1_by_fd;
28467ecd4f3SMax Laier 		memset(pop->idxplus1_by_fd + pop->fd_count,
28567ecd4f3SMax Laier 		       0, sizeof(int)*(new_count - pop->fd_count));
28667ecd4f3SMax Laier 		pop->fd_count = new_count;
28767ecd4f3SMax Laier 	}
28867ecd4f3SMax Laier 
28967ecd4f3SMax Laier 	i = pop->idxplus1_by_fd[ev->ev_fd] - 1;
29067ecd4f3SMax Laier 	if (i >= 0) {
29167ecd4f3SMax Laier 		pfd = &pop->event_set[i];
29267ecd4f3SMax Laier 	} else {
29367ecd4f3SMax Laier 		i = pop->nfds++;
29467ecd4f3SMax Laier 		pfd = &pop->event_set[i];
29567ecd4f3SMax Laier 		pfd->events = 0;
29667ecd4f3SMax Laier 		pfd->fd = ev->ev_fd;
29767ecd4f3SMax Laier 		pop->event_w_back[i] = pop->event_r_back[i] = NULL;
29867ecd4f3SMax Laier 		pop->idxplus1_by_fd[ev->ev_fd] = i + 1;
29967ecd4f3SMax Laier 	}
30067ecd4f3SMax Laier 
30167ecd4f3SMax Laier 	pfd->revents = 0;
30267ecd4f3SMax Laier 	if (ev->ev_events & EV_WRITE) {
30367ecd4f3SMax Laier 		pfd->events |= POLLOUT;
30467ecd4f3SMax Laier 		pop->event_w_back[i] = ev;
30567ecd4f3SMax Laier 	}
30667ecd4f3SMax Laier 	if (ev->ev_events & EV_READ) {
30767ecd4f3SMax Laier 		pfd->events |= POLLIN;
30867ecd4f3SMax Laier 		pop->event_r_back[i] = ev;
30967ecd4f3SMax Laier 	}
31067ecd4f3SMax Laier 	poll_check_ok(pop);
31167ecd4f3SMax Laier 
31267ecd4f3SMax Laier 	return (0);
31367ecd4f3SMax Laier }
31467ecd4f3SMax Laier 
31567ecd4f3SMax Laier /*
31667ecd4f3SMax Laier  * Nothing to be done here.
31767ecd4f3SMax Laier  */
31867ecd4f3SMax Laier 
31967ecd4f3SMax Laier int
poll_del(void * arg,struct event * ev)32067ecd4f3SMax Laier poll_del(void *arg, struct event *ev)
32167ecd4f3SMax Laier {
32267ecd4f3SMax Laier 	struct pollop *pop = arg;
32367ecd4f3SMax Laier 	struct pollfd *pfd = NULL;
32467ecd4f3SMax Laier 	int i;
32567ecd4f3SMax Laier 
32667ecd4f3SMax Laier 	if (ev->ev_events & EV_SIGNAL)
32767ecd4f3SMax Laier 		return (evsignal_del(ev));
32867ecd4f3SMax Laier 
32967ecd4f3SMax Laier 	if (!(ev->ev_events & (EV_READ|EV_WRITE)))
33067ecd4f3SMax Laier 		return (0);
33167ecd4f3SMax Laier 
33267ecd4f3SMax Laier 	poll_check_ok(pop);
33367ecd4f3SMax Laier 	i = pop->idxplus1_by_fd[ev->ev_fd] - 1;
33467ecd4f3SMax Laier 	if (i < 0)
33567ecd4f3SMax Laier 		return (-1);
33667ecd4f3SMax Laier 
33767ecd4f3SMax Laier 	/* Do we still want to read or write? */
33867ecd4f3SMax Laier 	pfd = &pop->event_set[i];
33967ecd4f3SMax Laier 	if (ev->ev_events & EV_READ) {
34067ecd4f3SMax Laier 		pfd->events &= ~POLLIN;
34167ecd4f3SMax Laier 		pop->event_r_back[i] = NULL;
34267ecd4f3SMax Laier 	}
34367ecd4f3SMax Laier 	if (ev->ev_events & EV_WRITE) {
34467ecd4f3SMax Laier 		pfd->events &= ~POLLOUT;
34567ecd4f3SMax Laier 		pop->event_w_back[i] = NULL;
34667ecd4f3SMax Laier 	}
34767ecd4f3SMax Laier 	poll_check_ok(pop);
34867ecd4f3SMax Laier 	if (pfd->events)
34967ecd4f3SMax Laier 		/* Another event cares about that fd. */
35067ecd4f3SMax Laier 		return (0);
35167ecd4f3SMax Laier 
35267ecd4f3SMax Laier 	/* Okay, so we aren't interested in that fd anymore. */
35367ecd4f3SMax Laier 	pop->idxplus1_by_fd[ev->ev_fd] = 0;
35467ecd4f3SMax Laier 
35567ecd4f3SMax Laier 	--pop->nfds;
35667ecd4f3SMax Laier 	if (i != pop->nfds) {
35767ecd4f3SMax Laier 		/*
35867ecd4f3SMax Laier 		 * Shift the last pollfd down into the now-unoccupied
35967ecd4f3SMax Laier 		 * position.
36067ecd4f3SMax Laier 		 */
36167ecd4f3SMax Laier 		memcpy(&pop->event_set[i], &pop->event_set[pop->nfds],
36267ecd4f3SMax Laier 		       sizeof(struct pollfd));
36367ecd4f3SMax Laier 		pop->event_r_back[i] = pop->event_r_back[pop->nfds];
36467ecd4f3SMax Laier 		pop->event_w_back[i] = pop->event_w_back[pop->nfds];
36567ecd4f3SMax Laier 		pop->idxplus1_by_fd[pop->event_set[i].fd] = i + 1;
36667ecd4f3SMax Laier 	}
36767ecd4f3SMax Laier 
36867ecd4f3SMax Laier 	poll_check_ok(pop);
36967ecd4f3SMax Laier 	return (0);
37067ecd4f3SMax Laier }
37167ecd4f3SMax Laier 
37267ecd4f3SMax Laier void
poll_dealloc(void * arg)37367ecd4f3SMax Laier poll_dealloc(void *arg)
37467ecd4f3SMax Laier {
37567ecd4f3SMax Laier 	struct pollop *pop = arg;
37667ecd4f3SMax Laier 
37767ecd4f3SMax Laier 	if (pop->event_set)
37867ecd4f3SMax Laier 		free(pop->event_set);
37967ecd4f3SMax Laier 	if (pop->event_r_back)
38067ecd4f3SMax Laier 		free(pop->event_r_back);
38167ecd4f3SMax Laier 	if (pop->event_w_back)
38267ecd4f3SMax Laier 		free(pop->event_w_back);
38367ecd4f3SMax Laier 	if (pop->idxplus1_by_fd)
38467ecd4f3SMax Laier 		free(pop->idxplus1_by_fd);
38567ecd4f3SMax Laier 
38667ecd4f3SMax Laier 	memset(pop, 0, sizeof(struct pollop));
38767ecd4f3SMax Laier 	free(pop);
38867ecd4f3SMax Laier }
389