xref: /aosp_15_r20/external/cronet/third_party/libevent/select.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker /*	$OpenBSD: select.c,v 1.2 2002/06/25 15:50:15 mickey Exp $	*/
2*6777b538SAndroid Build Coastguard Worker 
3*6777b538SAndroid Build Coastguard Worker /*
4*6777b538SAndroid Build Coastguard Worker  * Copyright 2000-2002 Niels Provos <[email protected]>
5*6777b538SAndroid Build Coastguard Worker  * All rights reserved.
6*6777b538SAndroid Build Coastguard Worker  *
7*6777b538SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
8*6777b538SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
9*6777b538SAndroid Build Coastguard Worker  * are met:
10*6777b538SAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
11*6777b538SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer.
12*6777b538SAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
13*6777b538SAndroid Build Coastguard Worker  *    notice, this list of conditions and the following disclaimer in the
14*6777b538SAndroid Build Coastguard Worker  *    documentation and/or other materials provided with the distribution.
15*6777b538SAndroid Build Coastguard Worker  * 3. The name of the author may not be used to endorse or promote products
16*6777b538SAndroid Build Coastguard Worker  *    derived from this software without specific prior written permission.
17*6777b538SAndroid Build Coastguard Worker  *
18*6777b538SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19*6777b538SAndroid Build Coastguard Worker  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20*6777b538SAndroid Build Coastguard Worker  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21*6777b538SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22*6777b538SAndroid Build Coastguard Worker  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23*6777b538SAndroid Build Coastguard Worker  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*6777b538SAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*6777b538SAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*6777b538SAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27*6777b538SAndroid Build Coastguard Worker  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*6777b538SAndroid Build Coastguard Worker  */
29*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
30*6777b538SAndroid Build Coastguard Worker #include "config.h"
31*6777b538SAndroid Build Coastguard Worker #endif
32*6777b538SAndroid Build Coastguard Worker 
33*6777b538SAndroid Build Coastguard Worker #include <sys/types.h>
34*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_SYS_TIME_H
35*6777b538SAndroid Build Coastguard Worker #include <sys/time.h>
36*6777b538SAndroid Build Coastguard Worker #else
37*6777b538SAndroid Build Coastguard Worker #include <sys/_libevent_time.h>
38*6777b538SAndroid Build Coastguard Worker #endif
39*6777b538SAndroid Build Coastguard Worker #ifdef HAVE_SYS_SELECT_H
40*6777b538SAndroid Build Coastguard Worker #include <sys/select.h>
41*6777b538SAndroid Build Coastguard Worker #endif
42*6777b538SAndroid Build Coastguard Worker #include <sys/queue.h>
43*6777b538SAndroid Build Coastguard Worker #include <signal.h>
44*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
45*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
46*6777b538SAndroid Build Coastguard Worker #include <string.h>
47*6777b538SAndroid Build Coastguard Worker #include <unistd.h>
48*6777b538SAndroid Build Coastguard Worker #include <errno.h>
49*6777b538SAndroid Build Coastguard Worker #ifdef CHECK_INVARIANTS
50*6777b538SAndroid Build Coastguard Worker #include <assert.h>
51*6777b538SAndroid Build Coastguard Worker #endif
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker #include "event.h"
54*6777b538SAndroid Build Coastguard Worker #include "evutil.h"
55*6777b538SAndroid Build Coastguard Worker #include "event-internal.h"
56*6777b538SAndroid Build Coastguard Worker #include "evsignal.h"
57*6777b538SAndroid Build Coastguard Worker #include "log.h"
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker #ifndef howmany
60*6777b538SAndroid Build Coastguard Worker #define        howmany(x, y)   (((x)+((y)-1))/(y))
61*6777b538SAndroid Build Coastguard Worker #endif
62*6777b538SAndroid Build Coastguard Worker 
63*6777b538SAndroid Build Coastguard Worker #ifndef _EVENT_HAVE_FD_MASK
64*6777b538SAndroid Build Coastguard Worker /* This type is mandatory, but Android doesn't define it. */
65*6777b538SAndroid Build Coastguard Worker #undef NFDBITS
66*6777b538SAndroid Build Coastguard Worker #define NFDBITS (sizeof(long)*8)
67*6777b538SAndroid Build Coastguard Worker typedef unsigned long fd_mask;
68*6777b538SAndroid Build Coastguard Worker #endif
69*6777b538SAndroid Build Coastguard Worker 
70*6777b538SAndroid Build Coastguard Worker struct selectop {
71*6777b538SAndroid Build Coastguard Worker 	int event_fds;		/* Highest fd in fd set */
72*6777b538SAndroid Build Coastguard Worker 	int event_fdsz;
73*6777b538SAndroid Build Coastguard Worker 	fd_set *event_readset_in;
74*6777b538SAndroid Build Coastguard Worker 	fd_set *event_writeset_in;
75*6777b538SAndroid Build Coastguard Worker 	fd_set *event_readset_out;
76*6777b538SAndroid Build Coastguard Worker 	fd_set *event_writeset_out;
77*6777b538SAndroid Build Coastguard Worker 	struct event **event_r_by_fd;
78*6777b538SAndroid Build Coastguard Worker 	struct event **event_w_by_fd;
79*6777b538SAndroid Build Coastguard Worker };
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker static void *select_init	(struct event_base *);
82*6777b538SAndroid Build Coastguard Worker static int select_add		(void *, struct event *);
83*6777b538SAndroid Build Coastguard Worker static int select_del		(void *, struct event *);
84*6777b538SAndroid Build Coastguard Worker static int select_dispatch	(struct event_base *, void *, struct timeval *);
85*6777b538SAndroid Build Coastguard Worker static void select_dealloc     (struct event_base *, void *);
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker const struct eventop selectops = {
88*6777b538SAndroid Build Coastguard Worker 	"select",
89*6777b538SAndroid Build Coastguard Worker 	select_init,
90*6777b538SAndroid Build Coastguard Worker 	select_add,
91*6777b538SAndroid Build Coastguard Worker 	select_del,
92*6777b538SAndroid Build Coastguard Worker 	select_dispatch,
93*6777b538SAndroid Build Coastguard Worker 	select_dealloc,
94*6777b538SAndroid Build Coastguard Worker 	0
95*6777b538SAndroid Build Coastguard Worker };
96*6777b538SAndroid Build Coastguard Worker 
97*6777b538SAndroid Build Coastguard Worker static int select_resize(struct selectop *sop, int fdsz);
98*6777b538SAndroid Build Coastguard Worker 
99*6777b538SAndroid Build Coastguard Worker static void *
select_init(struct event_base * base)100*6777b538SAndroid Build Coastguard Worker select_init(struct event_base *base)
101*6777b538SAndroid Build Coastguard Worker {
102*6777b538SAndroid Build Coastguard Worker 	struct selectop *sop;
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker 	/* Disable select when this environment variable is set */
105*6777b538SAndroid Build Coastguard Worker 	if (evutil_getenv("EVENT_NOSELECT"))
106*6777b538SAndroid Build Coastguard Worker 		return (NULL);
107*6777b538SAndroid Build Coastguard Worker 
108*6777b538SAndroid Build Coastguard Worker 	if (!(sop = calloc(1, sizeof(struct selectop))))
109*6777b538SAndroid Build Coastguard Worker 		return (NULL);
110*6777b538SAndroid Build Coastguard Worker 
111*6777b538SAndroid Build Coastguard Worker 	select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask));
112*6777b538SAndroid Build Coastguard Worker 
113*6777b538SAndroid Build Coastguard Worker 	evsignal_init(base);
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker 	return (sop);
116*6777b538SAndroid Build Coastguard Worker }
117*6777b538SAndroid Build Coastguard Worker 
118*6777b538SAndroid Build Coastguard Worker #ifdef CHECK_INVARIANTS
119*6777b538SAndroid Build Coastguard Worker static void
check_selectop(struct selectop * sop)120*6777b538SAndroid Build Coastguard Worker check_selectop(struct selectop *sop)
121*6777b538SAndroid Build Coastguard Worker {
122*6777b538SAndroid Build Coastguard Worker 	int i;
123*6777b538SAndroid Build Coastguard Worker 	for (i = 0; i <= sop->event_fds; ++i) {
124*6777b538SAndroid Build Coastguard Worker 		if (FD_ISSET(i, sop->event_readset_in)) {
125*6777b538SAndroid Build Coastguard Worker 			assert(sop->event_r_by_fd[i]);
126*6777b538SAndroid Build Coastguard Worker 			assert(sop->event_r_by_fd[i]->ev_events & EV_READ);
127*6777b538SAndroid Build Coastguard Worker 			assert(sop->event_r_by_fd[i]->ev_fd == i);
128*6777b538SAndroid Build Coastguard Worker 		} else {
129*6777b538SAndroid Build Coastguard Worker 			assert(! sop->event_r_by_fd[i]);
130*6777b538SAndroid Build Coastguard Worker 		}
131*6777b538SAndroid Build Coastguard Worker 		if (FD_ISSET(i, sop->event_writeset_in)) {
132*6777b538SAndroid Build Coastguard Worker 			assert(sop->event_w_by_fd[i]);
133*6777b538SAndroid Build Coastguard Worker 			assert(sop->event_w_by_fd[i]->ev_events & EV_WRITE);
134*6777b538SAndroid Build Coastguard Worker 			assert(sop->event_w_by_fd[i]->ev_fd == i);
135*6777b538SAndroid Build Coastguard Worker 		} else {
136*6777b538SAndroid Build Coastguard Worker 			assert(! sop->event_w_by_fd[i]);
137*6777b538SAndroid Build Coastguard Worker 		}
138*6777b538SAndroid Build Coastguard Worker 	}
139*6777b538SAndroid Build Coastguard Worker 
140*6777b538SAndroid Build Coastguard Worker }
141*6777b538SAndroid Build Coastguard Worker #else
142*6777b538SAndroid Build Coastguard Worker #define check_selectop(sop) do { (void) sop; } while (0)
143*6777b538SAndroid Build Coastguard Worker #endif
144*6777b538SAndroid Build Coastguard Worker 
145*6777b538SAndroid Build Coastguard Worker static int
select_dispatch(struct event_base * base,void * arg,struct timeval * tv)146*6777b538SAndroid Build Coastguard Worker select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
147*6777b538SAndroid Build Coastguard Worker {
148*6777b538SAndroid Build Coastguard Worker 	int res, i, j;
149*6777b538SAndroid Build Coastguard Worker 	struct selectop *sop = arg;
150*6777b538SAndroid Build Coastguard Worker 
151*6777b538SAndroid Build Coastguard Worker 	check_selectop(sop);
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker 	memcpy(sop->event_readset_out, sop->event_readset_in,
154*6777b538SAndroid Build Coastguard Worker 	       sop->event_fdsz);
155*6777b538SAndroid Build Coastguard Worker 	memcpy(sop->event_writeset_out, sop->event_writeset_in,
156*6777b538SAndroid Build Coastguard Worker 	       sop->event_fdsz);
157*6777b538SAndroid Build Coastguard Worker 
158*6777b538SAndroid Build Coastguard Worker 	res = select(sop->event_fds + 1, sop->event_readset_out,
159*6777b538SAndroid Build Coastguard Worker 	    sop->event_writeset_out, NULL, tv);
160*6777b538SAndroid Build Coastguard Worker 
161*6777b538SAndroid Build Coastguard Worker 	check_selectop(sop);
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker 	if (res == -1) {
164*6777b538SAndroid Build Coastguard Worker 		if (errno != EINTR) {
165*6777b538SAndroid Build Coastguard Worker 			event_warn("select");
166*6777b538SAndroid Build Coastguard Worker 			return (-1);
167*6777b538SAndroid Build Coastguard Worker 		}
168*6777b538SAndroid Build Coastguard Worker 
169*6777b538SAndroid Build Coastguard Worker 		evsignal_process(base);
170*6777b538SAndroid Build Coastguard Worker 		return (0);
171*6777b538SAndroid Build Coastguard Worker 	} else if (base->sig.evsignal_caught) {
172*6777b538SAndroid Build Coastguard Worker 		evsignal_process(base);
173*6777b538SAndroid Build Coastguard Worker 	}
174*6777b538SAndroid Build Coastguard Worker 
175*6777b538SAndroid Build Coastguard Worker 	event_debug(("%s: select reports %d", __func__, res));
176*6777b538SAndroid Build Coastguard Worker 
177*6777b538SAndroid Build Coastguard Worker 	check_selectop(sop);
178*6777b538SAndroid Build Coastguard Worker 	i = random() % (sop->event_fds+1);
179*6777b538SAndroid Build Coastguard Worker 	for (j = 0; j <= sop->event_fds; ++j) {
180*6777b538SAndroid Build Coastguard Worker 		struct event *r_ev = NULL, *w_ev = NULL;
181*6777b538SAndroid Build Coastguard Worker 		if (++i >= sop->event_fds+1)
182*6777b538SAndroid Build Coastguard Worker 			i = 0;
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker 		res = 0;
185*6777b538SAndroid Build Coastguard Worker 		if (FD_ISSET(i, sop->event_readset_out)) {
186*6777b538SAndroid Build Coastguard Worker 			r_ev = sop->event_r_by_fd[i];
187*6777b538SAndroid Build Coastguard Worker 			res |= EV_READ;
188*6777b538SAndroid Build Coastguard Worker 		}
189*6777b538SAndroid Build Coastguard Worker 		if (FD_ISSET(i, sop->event_writeset_out)) {
190*6777b538SAndroid Build Coastguard Worker 			w_ev = sop->event_w_by_fd[i];
191*6777b538SAndroid Build Coastguard Worker 			res |= EV_WRITE;
192*6777b538SAndroid Build Coastguard Worker 		}
193*6777b538SAndroid Build Coastguard Worker 		if (r_ev && (res & r_ev->ev_events)) {
194*6777b538SAndroid Build Coastguard Worker 			event_active(r_ev, res & r_ev->ev_events, 1);
195*6777b538SAndroid Build Coastguard Worker 		}
196*6777b538SAndroid Build Coastguard Worker 		if (w_ev && w_ev != r_ev && (res & w_ev->ev_events)) {
197*6777b538SAndroid Build Coastguard Worker 			event_active(w_ev, res & w_ev->ev_events, 1);
198*6777b538SAndroid Build Coastguard Worker 		}
199*6777b538SAndroid Build Coastguard Worker 	}
200*6777b538SAndroid Build Coastguard Worker 	check_selectop(sop);
201*6777b538SAndroid Build Coastguard Worker 
202*6777b538SAndroid Build Coastguard Worker 	return (0);
203*6777b538SAndroid Build Coastguard Worker }
204*6777b538SAndroid Build Coastguard Worker 
205*6777b538SAndroid Build Coastguard Worker 
206*6777b538SAndroid Build Coastguard Worker static int
select_resize(struct selectop * sop,int fdsz)207*6777b538SAndroid Build Coastguard Worker select_resize(struct selectop *sop, int fdsz)
208*6777b538SAndroid Build Coastguard Worker {
209*6777b538SAndroid Build Coastguard Worker 	int n_events, n_events_old;
210*6777b538SAndroid Build Coastguard Worker 
211*6777b538SAndroid Build Coastguard Worker 	fd_set *readset_in = NULL;
212*6777b538SAndroid Build Coastguard Worker 	fd_set *writeset_in = NULL;
213*6777b538SAndroid Build Coastguard Worker 	fd_set *readset_out = NULL;
214*6777b538SAndroid Build Coastguard Worker 	fd_set *writeset_out = NULL;
215*6777b538SAndroid Build Coastguard Worker 	struct event **r_by_fd = NULL;
216*6777b538SAndroid Build Coastguard Worker 	struct event **w_by_fd = NULL;
217*6777b538SAndroid Build Coastguard Worker 
218*6777b538SAndroid Build Coastguard Worker 	n_events = (fdsz/sizeof(fd_mask)) * NFDBITS;
219*6777b538SAndroid Build Coastguard Worker 	n_events_old = (sop->event_fdsz/sizeof(fd_mask)) * NFDBITS;
220*6777b538SAndroid Build Coastguard Worker 
221*6777b538SAndroid Build Coastguard Worker 	if (sop->event_readset_in)
222*6777b538SAndroid Build Coastguard Worker 		check_selectop(sop);
223*6777b538SAndroid Build Coastguard Worker 
224*6777b538SAndroid Build Coastguard Worker 	if ((readset_in = realloc(sop->event_readset_in, fdsz)) == NULL)
225*6777b538SAndroid Build Coastguard Worker 		goto error;
226*6777b538SAndroid Build Coastguard Worker 	sop->event_readset_in = readset_in;
227*6777b538SAndroid Build Coastguard Worker 	if ((readset_out = realloc(sop->event_readset_out, fdsz)) == NULL)
228*6777b538SAndroid Build Coastguard Worker 		goto error;
229*6777b538SAndroid Build Coastguard Worker 	sop->event_readset_out = readset_out;
230*6777b538SAndroid Build Coastguard Worker 	if ((writeset_in = realloc(sop->event_writeset_in, fdsz)) == NULL)
231*6777b538SAndroid Build Coastguard Worker 		goto error;
232*6777b538SAndroid Build Coastguard Worker 	sop->event_writeset_in = writeset_in;
233*6777b538SAndroid Build Coastguard Worker 	if ((writeset_out = realloc(sop->event_writeset_out, fdsz)) == NULL)
234*6777b538SAndroid Build Coastguard Worker 		goto error;
235*6777b538SAndroid Build Coastguard Worker 	sop->event_writeset_out = writeset_out;
236*6777b538SAndroid Build Coastguard Worker 	if ((r_by_fd = realloc(sop->event_r_by_fd,
237*6777b538SAndroid Build Coastguard Worker 		 n_events*sizeof(struct event*))) == NULL)
238*6777b538SAndroid Build Coastguard Worker 		goto error;
239*6777b538SAndroid Build Coastguard Worker 	sop->event_r_by_fd = r_by_fd;
240*6777b538SAndroid Build Coastguard Worker 	if ((w_by_fd = realloc(sop->event_w_by_fd,
241*6777b538SAndroid Build Coastguard Worker 		 n_events * sizeof(struct event*))) == NULL)
242*6777b538SAndroid Build Coastguard Worker 		goto error;
243*6777b538SAndroid Build Coastguard Worker 	sop->event_w_by_fd = w_by_fd;
244*6777b538SAndroid Build Coastguard Worker 
245*6777b538SAndroid Build Coastguard Worker 	memset((char *)sop->event_readset_in + sop->event_fdsz, 0,
246*6777b538SAndroid Build Coastguard Worker 	    fdsz - sop->event_fdsz);
247*6777b538SAndroid Build Coastguard Worker 	memset((char *)sop->event_writeset_in + sop->event_fdsz, 0,
248*6777b538SAndroid Build Coastguard Worker 	    fdsz - sop->event_fdsz);
249*6777b538SAndroid Build Coastguard Worker 	memset(sop->event_r_by_fd + n_events_old, 0,
250*6777b538SAndroid Build Coastguard Worker 	    (n_events-n_events_old) * sizeof(struct event*));
251*6777b538SAndroid Build Coastguard Worker 	memset(sop->event_w_by_fd + n_events_old, 0,
252*6777b538SAndroid Build Coastguard Worker 	    (n_events-n_events_old) * sizeof(struct event*));
253*6777b538SAndroid Build Coastguard Worker 
254*6777b538SAndroid Build Coastguard Worker 	sop->event_fdsz = fdsz;
255*6777b538SAndroid Build Coastguard Worker 	check_selectop(sop);
256*6777b538SAndroid Build Coastguard Worker 
257*6777b538SAndroid Build Coastguard Worker 	return (0);
258*6777b538SAndroid Build Coastguard Worker 
259*6777b538SAndroid Build Coastguard Worker  error:
260*6777b538SAndroid Build Coastguard Worker 	event_warn("malloc");
261*6777b538SAndroid Build Coastguard Worker 	return (-1);
262*6777b538SAndroid Build Coastguard Worker }
263*6777b538SAndroid Build Coastguard Worker 
264*6777b538SAndroid Build Coastguard Worker 
265*6777b538SAndroid Build Coastguard Worker static int
select_add(void * arg,struct event * ev)266*6777b538SAndroid Build Coastguard Worker select_add(void *arg, struct event *ev)
267*6777b538SAndroid Build Coastguard Worker {
268*6777b538SAndroid Build Coastguard Worker 	struct selectop *sop = arg;
269*6777b538SAndroid Build Coastguard Worker 
270*6777b538SAndroid Build Coastguard Worker 	if (ev->ev_events & EV_SIGNAL)
271*6777b538SAndroid Build Coastguard Worker 		return (evsignal_add(ev));
272*6777b538SAndroid Build Coastguard Worker 
273*6777b538SAndroid Build Coastguard Worker 	check_selectop(sop);
274*6777b538SAndroid Build Coastguard Worker 	/*
275*6777b538SAndroid Build Coastguard Worker 	 * Keep track of the highest fd, so that we can calculate the size
276*6777b538SAndroid Build Coastguard Worker 	 * of the fd_sets for select(2)
277*6777b538SAndroid Build Coastguard Worker 	 */
278*6777b538SAndroid Build Coastguard Worker 	if (sop->event_fds < ev->ev_fd) {
279*6777b538SAndroid Build Coastguard Worker 		int fdsz = sop->event_fdsz;
280*6777b538SAndroid Build Coastguard Worker 
281*6777b538SAndroid Build Coastguard Worker 		if (fdsz < sizeof(fd_mask))
282*6777b538SAndroid Build Coastguard Worker 			fdsz = sizeof(fd_mask);
283*6777b538SAndroid Build Coastguard Worker 
284*6777b538SAndroid Build Coastguard Worker 		while (fdsz <
285*6777b538SAndroid Build Coastguard Worker 		    (howmany(ev->ev_fd + 1, NFDBITS) * sizeof(fd_mask)))
286*6777b538SAndroid Build Coastguard Worker 			fdsz *= 2;
287*6777b538SAndroid Build Coastguard Worker 
288*6777b538SAndroid Build Coastguard Worker 		if (fdsz != sop->event_fdsz) {
289*6777b538SAndroid Build Coastguard Worker 			if (select_resize(sop, fdsz)) {
290*6777b538SAndroid Build Coastguard Worker 				check_selectop(sop);
291*6777b538SAndroid Build Coastguard Worker 				return (-1);
292*6777b538SAndroid Build Coastguard Worker 			}
293*6777b538SAndroid Build Coastguard Worker 		}
294*6777b538SAndroid Build Coastguard Worker 
295*6777b538SAndroid Build Coastguard Worker 		sop->event_fds = ev->ev_fd;
296*6777b538SAndroid Build Coastguard Worker 	}
297*6777b538SAndroid Build Coastguard Worker 
298*6777b538SAndroid Build Coastguard Worker 	if (ev->ev_events & EV_READ) {
299*6777b538SAndroid Build Coastguard Worker 		FD_SET(ev->ev_fd, sop->event_readset_in);
300*6777b538SAndroid Build Coastguard Worker 		sop->event_r_by_fd[ev->ev_fd] = ev;
301*6777b538SAndroid Build Coastguard Worker 	}
302*6777b538SAndroid Build Coastguard Worker 	if (ev->ev_events & EV_WRITE) {
303*6777b538SAndroid Build Coastguard Worker 		FD_SET(ev->ev_fd, sop->event_writeset_in);
304*6777b538SAndroid Build Coastguard Worker 		sop->event_w_by_fd[ev->ev_fd] = ev;
305*6777b538SAndroid Build Coastguard Worker 	}
306*6777b538SAndroid Build Coastguard Worker 	check_selectop(sop);
307*6777b538SAndroid Build Coastguard Worker 
308*6777b538SAndroid Build Coastguard Worker 	return (0);
309*6777b538SAndroid Build Coastguard Worker }
310*6777b538SAndroid Build Coastguard Worker 
311*6777b538SAndroid Build Coastguard Worker /*
312*6777b538SAndroid Build Coastguard Worker  * Nothing to be done here.
313*6777b538SAndroid Build Coastguard Worker  */
314*6777b538SAndroid Build Coastguard Worker 
315*6777b538SAndroid Build Coastguard Worker static int
select_del(void * arg,struct event * ev)316*6777b538SAndroid Build Coastguard Worker select_del(void *arg, struct event *ev)
317*6777b538SAndroid Build Coastguard Worker {
318*6777b538SAndroid Build Coastguard Worker 	struct selectop *sop = arg;
319*6777b538SAndroid Build Coastguard Worker 
320*6777b538SAndroid Build Coastguard Worker 	check_selectop(sop);
321*6777b538SAndroid Build Coastguard Worker 	if (ev->ev_events & EV_SIGNAL)
322*6777b538SAndroid Build Coastguard Worker 		return (evsignal_del(ev));
323*6777b538SAndroid Build Coastguard Worker 
324*6777b538SAndroid Build Coastguard Worker 	if (sop->event_fds < ev->ev_fd) {
325*6777b538SAndroid Build Coastguard Worker 		check_selectop(sop);
326*6777b538SAndroid Build Coastguard Worker 		return (0);
327*6777b538SAndroid Build Coastguard Worker 	}
328*6777b538SAndroid Build Coastguard Worker 
329*6777b538SAndroid Build Coastguard Worker 	if (ev->ev_events & EV_READ) {
330*6777b538SAndroid Build Coastguard Worker 		FD_CLR(ev->ev_fd, sop->event_readset_in);
331*6777b538SAndroid Build Coastguard Worker 		sop->event_r_by_fd[ev->ev_fd] = NULL;
332*6777b538SAndroid Build Coastguard Worker 	}
333*6777b538SAndroid Build Coastguard Worker 
334*6777b538SAndroid Build Coastguard Worker 	if (ev->ev_events & EV_WRITE) {
335*6777b538SAndroid Build Coastguard Worker 		FD_CLR(ev->ev_fd, sop->event_writeset_in);
336*6777b538SAndroid Build Coastguard Worker 		sop->event_w_by_fd[ev->ev_fd] = NULL;
337*6777b538SAndroid Build Coastguard Worker 	}
338*6777b538SAndroid Build Coastguard Worker 
339*6777b538SAndroid Build Coastguard Worker 	check_selectop(sop);
340*6777b538SAndroid Build Coastguard Worker 	return (0);
341*6777b538SAndroid Build Coastguard Worker }
342*6777b538SAndroid Build Coastguard Worker 
343*6777b538SAndroid Build Coastguard Worker static void
select_dealloc(struct event_base * base,void * arg)344*6777b538SAndroid Build Coastguard Worker select_dealloc(struct event_base *base, void *arg)
345*6777b538SAndroid Build Coastguard Worker {
346*6777b538SAndroid Build Coastguard Worker 	struct selectop *sop = arg;
347*6777b538SAndroid Build Coastguard Worker 
348*6777b538SAndroid Build Coastguard Worker 	evsignal_dealloc(base);
349*6777b538SAndroid Build Coastguard Worker 	if (sop->event_readset_in)
350*6777b538SAndroid Build Coastguard Worker 		free(sop->event_readset_in);
351*6777b538SAndroid Build Coastguard Worker 	if (sop->event_writeset_in)
352*6777b538SAndroid Build Coastguard Worker 		free(sop->event_writeset_in);
353*6777b538SAndroid Build Coastguard Worker 	if (sop->event_readset_out)
354*6777b538SAndroid Build Coastguard Worker 		free(sop->event_readset_out);
355*6777b538SAndroid Build Coastguard Worker 	if (sop->event_writeset_out)
356*6777b538SAndroid Build Coastguard Worker 		free(sop->event_writeset_out);
357*6777b538SAndroid Build Coastguard Worker 	if (sop->event_r_by_fd)
358*6777b538SAndroid Build Coastguard Worker 		free(sop->event_r_by_fd);
359*6777b538SAndroid Build Coastguard Worker 	if (sop->event_w_by_fd)
360*6777b538SAndroid Build Coastguard Worker 		free(sop->event_w_by_fd);
361*6777b538SAndroid Build Coastguard Worker 
362*6777b538SAndroid Build Coastguard Worker 	memset(sop, 0, sizeof(struct selectop));
363*6777b538SAndroid Build Coastguard Worker 	free(sop);
364*6777b538SAndroid Build Coastguard Worker }
365