1*6777b538SAndroid Build Coastguard Worker /* $OpenBSD: poll.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-2003 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 #include <sys/queue.h>
40*6777b538SAndroid Build Coastguard Worker #include <poll.h>
41*6777b538SAndroid Build Coastguard Worker #include <signal.h>
42*6777b538SAndroid Build Coastguard Worker #include <stdio.h>
43*6777b538SAndroid Build Coastguard Worker #include <stdlib.h>
44*6777b538SAndroid Build Coastguard Worker #include <string.h>
45*6777b538SAndroid Build Coastguard Worker #include <unistd.h>
46*6777b538SAndroid Build Coastguard Worker #include <errno.h>
47*6777b538SAndroid Build Coastguard Worker #ifdef CHECK_INVARIANTS
48*6777b538SAndroid Build Coastguard Worker #include <assert.h>
49*6777b538SAndroid Build Coastguard Worker #endif
50*6777b538SAndroid Build Coastguard Worker
51*6777b538SAndroid Build Coastguard Worker #include "event.h"
52*6777b538SAndroid Build Coastguard Worker #include "event-internal.h"
53*6777b538SAndroid Build Coastguard Worker #include "evsignal.h"
54*6777b538SAndroid Build Coastguard Worker #include "log.h"
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker struct pollop {
57*6777b538SAndroid Build Coastguard Worker int event_count; /* Highest number alloc */
58*6777b538SAndroid Build Coastguard Worker int nfds; /* Size of event_* */
59*6777b538SAndroid Build Coastguard Worker int fd_count; /* Size of idxplus1_by_fd */
60*6777b538SAndroid Build Coastguard Worker struct pollfd *event_set;
61*6777b538SAndroid Build Coastguard Worker struct event **event_r_back;
62*6777b538SAndroid Build Coastguard Worker struct event **event_w_back;
63*6777b538SAndroid Build Coastguard Worker int *idxplus1_by_fd; /* Index into event_set by fd; we add 1 so
64*6777b538SAndroid Build Coastguard Worker * that 0 (which is easy to memset) can mean
65*6777b538SAndroid Build Coastguard Worker * "no entry." */
66*6777b538SAndroid Build Coastguard Worker };
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard Worker static void *poll_init (struct event_base *);
69*6777b538SAndroid Build Coastguard Worker static int poll_add (void *, struct event *);
70*6777b538SAndroid Build Coastguard Worker static int poll_del (void *, struct event *);
71*6777b538SAndroid Build Coastguard Worker static int poll_dispatch (struct event_base *, void *, struct timeval *);
72*6777b538SAndroid Build Coastguard Worker static void poll_dealloc (struct event_base *, void *);
73*6777b538SAndroid Build Coastguard Worker
74*6777b538SAndroid Build Coastguard Worker const struct eventop pollops = {
75*6777b538SAndroid Build Coastguard Worker "poll",
76*6777b538SAndroid Build Coastguard Worker poll_init,
77*6777b538SAndroid Build Coastguard Worker poll_add,
78*6777b538SAndroid Build Coastguard Worker poll_del,
79*6777b538SAndroid Build Coastguard Worker poll_dispatch,
80*6777b538SAndroid Build Coastguard Worker poll_dealloc,
81*6777b538SAndroid Build Coastguard Worker 0
82*6777b538SAndroid Build Coastguard Worker };
83*6777b538SAndroid Build Coastguard Worker
84*6777b538SAndroid Build Coastguard Worker static void *
poll_init(struct event_base * base)85*6777b538SAndroid Build Coastguard Worker poll_init(struct event_base *base)
86*6777b538SAndroid Build Coastguard Worker {
87*6777b538SAndroid Build Coastguard Worker struct pollop *pollop;
88*6777b538SAndroid Build Coastguard Worker
89*6777b538SAndroid Build Coastguard Worker /* Disable poll when this environment variable is set */
90*6777b538SAndroid Build Coastguard Worker if (evutil_getenv("EVENT_NOPOLL"))
91*6777b538SAndroid Build Coastguard Worker return (NULL);
92*6777b538SAndroid Build Coastguard Worker
93*6777b538SAndroid Build Coastguard Worker if (!(pollop = calloc(1, sizeof(struct pollop))))
94*6777b538SAndroid Build Coastguard Worker return (NULL);
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker evsignal_init(base);
97*6777b538SAndroid Build Coastguard Worker
98*6777b538SAndroid Build Coastguard Worker return (pollop);
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker
101*6777b538SAndroid Build Coastguard Worker #ifdef CHECK_INVARIANTS
102*6777b538SAndroid Build Coastguard Worker static void
poll_check_ok(struct pollop * pop)103*6777b538SAndroid Build Coastguard Worker poll_check_ok(struct pollop *pop)
104*6777b538SAndroid Build Coastguard Worker {
105*6777b538SAndroid Build Coastguard Worker int i, idx;
106*6777b538SAndroid Build Coastguard Worker struct event *ev;
107*6777b538SAndroid Build Coastguard Worker
108*6777b538SAndroid Build Coastguard Worker for (i = 0; i < pop->fd_count; ++i) {
109*6777b538SAndroid Build Coastguard Worker idx = pop->idxplus1_by_fd[i]-1;
110*6777b538SAndroid Build Coastguard Worker if (idx < 0)
111*6777b538SAndroid Build Coastguard Worker continue;
112*6777b538SAndroid Build Coastguard Worker assert(pop->event_set[idx].fd == i);
113*6777b538SAndroid Build Coastguard Worker if (pop->event_set[idx].events & POLLIN) {
114*6777b538SAndroid Build Coastguard Worker ev = pop->event_r_back[idx];
115*6777b538SAndroid Build Coastguard Worker assert(ev);
116*6777b538SAndroid Build Coastguard Worker assert(ev->ev_events & EV_READ);
117*6777b538SAndroid Build Coastguard Worker assert(ev->ev_fd == i);
118*6777b538SAndroid Build Coastguard Worker }
119*6777b538SAndroid Build Coastguard Worker if (pop->event_set[idx].events & POLLOUT) {
120*6777b538SAndroid Build Coastguard Worker ev = pop->event_w_back[idx];
121*6777b538SAndroid Build Coastguard Worker assert(ev);
122*6777b538SAndroid Build Coastguard Worker assert(ev->ev_events & EV_WRITE);
123*6777b538SAndroid Build Coastguard Worker assert(ev->ev_fd == i);
124*6777b538SAndroid Build Coastguard Worker }
125*6777b538SAndroid Build Coastguard Worker }
126*6777b538SAndroid Build Coastguard Worker for (i = 0; i < pop->nfds; ++i) {
127*6777b538SAndroid Build Coastguard Worker struct pollfd *pfd = &pop->event_set[i];
128*6777b538SAndroid Build Coastguard Worker assert(pop->idxplus1_by_fd[pfd->fd] == i+1);
129*6777b538SAndroid Build Coastguard Worker }
130*6777b538SAndroid Build Coastguard Worker }
131*6777b538SAndroid Build Coastguard Worker #else
132*6777b538SAndroid Build Coastguard Worker #define poll_check_ok(pop)
133*6777b538SAndroid Build Coastguard Worker #endif
134*6777b538SAndroid Build Coastguard Worker
135*6777b538SAndroid Build Coastguard Worker static int
poll_dispatch(struct event_base * base,void * arg,struct timeval * tv)136*6777b538SAndroid Build Coastguard Worker poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
137*6777b538SAndroid Build Coastguard Worker {
138*6777b538SAndroid Build Coastguard Worker int res, i, j, msec = -1, nfds;
139*6777b538SAndroid Build Coastguard Worker struct pollop *pop = arg;
140*6777b538SAndroid Build Coastguard Worker
141*6777b538SAndroid Build Coastguard Worker poll_check_ok(pop);
142*6777b538SAndroid Build Coastguard Worker
143*6777b538SAndroid Build Coastguard Worker if (tv != NULL)
144*6777b538SAndroid Build Coastguard Worker msec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
145*6777b538SAndroid Build Coastguard Worker
146*6777b538SAndroid Build Coastguard Worker nfds = pop->nfds;
147*6777b538SAndroid Build Coastguard Worker res = poll(pop->event_set, nfds, msec);
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker if (res == -1) {
150*6777b538SAndroid Build Coastguard Worker if (errno != EINTR) {
151*6777b538SAndroid Build Coastguard Worker event_warn("poll");
152*6777b538SAndroid Build Coastguard Worker return (-1);
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker
155*6777b538SAndroid Build Coastguard Worker evsignal_process(base);
156*6777b538SAndroid Build Coastguard Worker return (0);
157*6777b538SAndroid Build Coastguard Worker } else if (base->sig.evsignal_caught) {
158*6777b538SAndroid Build Coastguard Worker evsignal_process(base);
159*6777b538SAndroid Build Coastguard Worker }
160*6777b538SAndroid Build Coastguard Worker
161*6777b538SAndroid Build Coastguard Worker event_debug(("%s: poll reports %d", __func__, res));
162*6777b538SAndroid Build Coastguard Worker
163*6777b538SAndroid Build Coastguard Worker if (res == 0 || nfds == 0)
164*6777b538SAndroid Build Coastguard Worker return (0);
165*6777b538SAndroid Build Coastguard Worker
166*6777b538SAndroid Build Coastguard Worker i = random() % nfds;
167*6777b538SAndroid Build Coastguard Worker for (j = 0; j < nfds; j++) {
168*6777b538SAndroid Build Coastguard Worker struct event *r_ev = NULL, *w_ev = NULL;
169*6777b538SAndroid Build Coastguard Worker int what;
170*6777b538SAndroid Build Coastguard Worker if (++i == nfds)
171*6777b538SAndroid Build Coastguard Worker i = 0;
172*6777b538SAndroid Build Coastguard Worker what = pop->event_set[i].revents;
173*6777b538SAndroid Build Coastguard Worker
174*6777b538SAndroid Build Coastguard Worker if (!what)
175*6777b538SAndroid Build Coastguard Worker continue;
176*6777b538SAndroid Build Coastguard Worker
177*6777b538SAndroid Build Coastguard Worker res = 0;
178*6777b538SAndroid Build Coastguard Worker
179*6777b538SAndroid Build Coastguard Worker /* If the file gets closed notify */
180*6777b538SAndroid Build Coastguard Worker if (what & (POLLHUP|POLLERR))
181*6777b538SAndroid Build Coastguard Worker what |= POLLIN|POLLOUT;
182*6777b538SAndroid Build Coastguard Worker if (what & POLLIN) {
183*6777b538SAndroid Build Coastguard Worker res |= EV_READ;
184*6777b538SAndroid Build Coastguard Worker r_ev = pop->event_r_back[i];
185*6777b538SAndroid Build Coastguard Worker }
186*6777b538SAndroid Build Coastguard Worker if (what & POLLOUT) {
187*6777b538SAndroid Build Coastguard Worker res |= EV_WRITE;
188*6777b538SAndroid Build Coastguard Worker w_ev = pop->event_w_back[i];
189*6777b538SAndroid Build Coastguard Worker }
190*6777b538SAndroid Build Coastguard Worker if (res == 0)
191*6777b538SAndroid Build Coastguard Worker continue;
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
201*6777b538SAndroid Build Coastguard Worker return (0);
202*6777b538SAndroid Build Coastguard Worker }
203*6777b538SAndroid Build Coastguard Worker
204*6777b538SAndroid Build Coastguard Worker static int
poll_add(void * arg,struct event * ev)205*6777b538SAndroid Build Coastguard Worker poll_add(void *arg, struct event *ev)
206*6777b538SAndroid Build Coastguard Worker {
207*6777b538SAndroid Build Coastguard Worker struct pollop *pop = arg;
208*6777b538SAndroid Build Coastguard Worker struct pollfd *pfd = NULL;
209*6777b538SAndroid Build Coastguard Worker int i;
210*6777b538SAndroid Build Coastguard Worker
211*6777b538SAndroid Build Coastguard Worker if (ev->ev_events & EV_SIGNAL)
212*6777b538SAndroid Build Coastguard Worker return (evsignal_add(ev));
213*6777b538SAndroid Build Coastguard Worker if (!(ev->ev_events & (EV_READ|EV_WRITE)))
214*6777b538SAndroid Build Coastguard Worker return (0);
215*6777b538SAndroid Build Coastguard Worker
216*6777b538SAndroid Build Coastguard Worker poll_check_ok(pop);
217*6777b538SAndroid Build Coastguard Worker if (pop->nfds + 1 >= pop->event_count) {
218*6777b538SAndroid Build Coastguard Worker struct pollfd *tmp_event_set;
219*6777b538SAndroid Build Coastguard Worker struct event **tmp_event_r_back;
220*6777b538SAndroid Build Coastguard Worker struct event **tmp_event_w_back;
221*6777b538SAndroid Build Coastguard Worker int tmp_event_count;
222*6777b538SAndroid Build Coastguard Worker
223*6777b538SAndroid Build Coastguard Worker if (pop->event_count < 32)
224*6777b538SAndroid Build Coastguard Worker tmp_event_count = 32;
225*6777b538SAndroid Build Coastguard Worker else
226*6777b538SAndroid Build Coastguard Worker tmp_event_count = pop->event_count * 2;
227*6777b538SAndroid Build Coastguard Worker
228*6777b538SAndroid Build Coastguard Worker /* We need more file descriptors */
229*6777b538SAndroid Build Coastguard Worker tmp_event_set = realloc(pop->event_set,
230*6777b538SAndroid Build Coastguard Worker tmp_event_count * sizeof(struct pollfd));
231*6777b538SAndroid Build Coastguard Worker if (tmp_event_set == NULL) {
232*6777b538SAndroid Build Coastguard Worker event_warn("realloc");
233*6777b538SAndroid Build Coastguard Worker return (-1);
234*6777b538SAndroid Build Coastguard Worker }
235*6777b538SAndroid Build Coastguard Worker pop->event_set = tmp_event_set;
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker tmp_event_r_back = realloc(pop->event_r_back,
238*6777b538SAndroid Build Coastguard Worker tmp_event_count * sizeof(struct event *));
239*6777b538SAndroid Build Coastguard Worker if (tmp_event_r_back == NULL) {
240*6777b538SAndroid Build Coastguard Worker /* event_set overallocated; that's okay. */
241*6777b538SAndroid Build Coastguard Worker event_warn("realloc");
242*6777b538SAndroid Build Coastguard Worker return (-1);
243*6777b538SAndroid Build Coastguard Worker }
244*6777b538SAndroid Build Coastguard Worker pop->event_r_back = tmp_event_r_back;
245*6777b538SAndroid Build Coastguard Worker
246*6777b538SAndroid Build Coastguard Worker tmp_event_w_back = realloc(pop->event_w_back,
247*6777b538SAndroid Build Coastguard Worker tmp_event_count * sizeof(struct event *));
248*6777b538SAndroid Build Coastguard Worker if (tmp_event_w_back == NULL) {
249*6777b538SAndroid Build Coastguard Worker /* event_set and event_r_back overallocated; that's
250*6777b538SAndroid Build Coastguard Worker * okay. */
251*6777b538SAndroid Build Coastguard Worker event_warn("realloc");
252*6777b538SAndroid Build Coastguard Worker return (-1);
253*6777b538SAndroid Build Coastguard Worker }
254*6777b538SAndroid Build Coastguard Worker pop->event_w_back = tmp_event_w_back;
255*6777b538SAndroid Build Coastguard Worker
256*6777b538SAndroid Build Coastguard Worker pop->event_count = tmp_event_count;
257*6777b538SAndroid Build Coastguard Worker }
258*6777b538SAndroid Build Coastguard Worker if (ev->ev_fd >= pop->fd_count) {
259*6777b538SAndroid Build Coastguard Worker int *tmp_idxplus1_by_fd;
260*6777b538SAndroid Build Coastguard Worker int new_count;
261*6777b538SAndroid Build Coastguard Worker if (pop->fd_count < 32)
262*6777b538SAndroid Build Coastguard Worker new_count = 32;
263*6777b538SAndroid Build Coastguard Worker else
264*6777b538SAndroid Build Coastguard Worker new_count = pop->fd_count * 2;
265*6777b538SAndroid Build Coastguard Worker while (new_count <= ev->ev_fd)
266*6777b538SAndroid Build Coastguard Worker new_count *= 2;
267*6777b538SAndroid Build Coastguard Worker tmp_idxplus1_by_fd =
268*6777b538SAndroid Build Coastguard Worker realloc(pop->idxplus1_by_fd, new_count * sizeof(int));
269*6777b538SAndroid Build Coastguard Worker if (tmp_idxplus1_by_fd == NULL) {
270*6777b538SAndroid Build Coastguard Worker event_warn("realloc");
271*6777b538SAndroid Build Coastguard Worker return (-1);
272*6777b538SAndroid Build Coastguard Worker }
273*6777b538SAndroid Build Coastguard Worker pop->idxplus1_by_fd = tmp_idxplus1_by_fd;
274*6777b538SAndroid Build Coastguard Worker memset(pop->idxplus1_by_fd + pop->fd_count,
275*6777b538SAndroid Build Coastguard Worker 0, sizeof(int)*(new_count - pop->fd_count));
276*6777b538SAndroid Build Coastguard Worker pop->fd_count = new_count;
277*6777b538SAndroid Build Coastguard Worker }
278*6777b538SAndroid Build Coastguard Worker
279*6777b538SAndroid Build Coastguard Worker i = pop->idxplus1_by_fd[ev->ev_fd] - 1;
280*6777b538SAndroid Build Coastguard Worker if (i >= 0) {
281*6777b538SAndroid Build Coastguard Worker pfd = &pop->event_set[i];
282*6777b538SAndroid Build Coastguard Worker } else {
283*6777b538SAndroid Build Coastguard Worker i = pop->nfds++;
284*6777b538SAndroid Build Coastguard Worker pfd = &pop->event_set[i];
285*6777b538SAndroid Build Coastguard Worker pfd->events = 0;
286*6777b538SAndroid Build Coastguard Worker pfd->fd = ev->ev_fd;
287*6777b538SAndroid Build Coastguard Worker pop->event_w_back[i] = pop->event_r_back[i] = NULL;
288*6777b538SAndroid Build Coastguard Worker pop->idxplus1_by_fd[ev->ev_fd] = i + 1;
289*6777b538SAndroid Build Coastguard Worker }
290*6777b538SAndroid Build Coastguard Worker
291*6777b538SAndroid Build Coastguard Worker pfd->revents = 0;
292*6777b538SAndroid Build Coastguard Worker if (ev->ev_events & EV_WRITE) {
293*6777b538SAndroid Build Coastguard Worker pfd->events |= POLLOUT;
294*6777b538SAndroid Build Coastguard Worker pop->event_w_back[i] = ev;
295*6777b538SAndroid Build Coastguard Worker }
296*6777b538SAndroid Build Coastguard Worker if (ev->ev_events & EV_READ) {
297*6777b538SAndroid Build Coastguard Worker pfd->events |= POLLIN;
298*6777b538SAndroid Build Coastguard Worker pop->event_r_back[i] = ev;
299*6777b538SAndroid Build Coastguard Worker }
300*6777b538SAndroid Build Coastguard Worker poll_check_ok(pop);
301*6777b538SAndroid Build Coastguard Worker
302*6777b538SAndroid Build Coastguard Worker return (0);
303*6777b538SAndroid Build Coastguard Worker }
304*6777b538SAndroid Build Coastguard Worker
305*6777b538SAndroid Build Coastguard Worker /*
306*6777b538SAndroid Build Coastguard Worker * Nothing to be done here.
307*6777b538SAndroid Build Coastguard Worker */
308*6777b538SAndroid Build Coastguard Worker
309*6777b538SAndroid Build Coastguard Worker static int
poll_del(void * arg,struct event * ev)310*6777b538SAndroid Build Coastguard Worker poll_del(void *arg, struct event *ev)
311*6777b538SAndroid Build Coastguard Worker {
312*6777b538SAndroid Build Coastguard Worker struct pollop *pop = arg;
313*6777b538SAndroid Build Coastguard Worker struct pollfd *pfd = NULL;
314*6777b538SAndroid Build Coastguard Worker int i;
315*6777b538SAndroid Build Coastguard Worker
316*6777b538SAndroid Build Coastguard Worker if (ev->ev_events & EV_SIGNAL)
317*6777b538SAndroid Build Coastguard Worker return (evsignal_del(ev));
318*6777b538SAndroid Build Coastguard Worker
319*6777b538SAndroid Build Coastguard Worker if (!(ev->ev_events & (EV_READ|EV_WRITE)))
320*6777b538SAndroid Build Coastguard Worker return (0);
321*6777b538SAndroid Build Coastguard Worker
322*6777b538SAndroid Build Coastguard Worker poll_check_ok(pop);
323*6777b538SAndroid Build Coastguard Worker i = pop->idxplus1_by_fd[ev->ev_fd] - 1;
324*6777b538SAndroid Build Coastguard Worker if (i < 0)
325*6777b538SAndroid Build Coastguard Worker return (-1);
326*6777b538SAndroid Build Coastguard Worker
327*6777b538SAndroid Build Coastguard Worker /* Do we still want to read or write? */
328*6777b538SAndroid Build Coastguard Worker pfd = &pop->event_set[i];
329*6777b538SAndroid Build Coastguard Worker if (ev->ev_events & EV_READ) {
330*6777b538SAndroid Build Coastguard Worker pfd->events &= ~POLLIN;
331*6777b538SAndroid Build Coastguard Worker pop->event_r_back[i] = NULL;
332*6777b538SAndroid Build Coastguard Worker }
333*6777b538SAndroid Build Coastguard Worker if (ev->ev_events & EV_WRITE) {
334*6777b538SAndroid Build Coastguard Worker pfd->events &= ~POLLOUT;
335*6777b538SAndroid Build Coastguard Worker pop->event_w_back[i] = NULL;
336*6777b538SAndroid Build Coastguard Worker }
337*6777b538SAndroid Build Coastguard Worker poll_check_ok(pop);
338*6777b538SAndroid Build Coastguard Worker if (pfd->events)
339*6777b538SAndroid Build Coastguard Worker /* Another event cares about that fd. */
340*6777b538SAndroid Build Coastguard Worker return (0);
341*6777b538SAndroid Build Coastguard Worker
342*6777b538SAndroid Build Coastguard Worker /* Okay, so we aren't interested in that fd anymore. */
343*6777b538SAndroid Build Coastguard Worker pop->idxplus1_by_fd[ev->ev_fd] = 0;
344*6777b538SAndroid Build Coastguard Worker
345*6777b538SAndroid Build Coastguard Worker --pop->nfds;
346*6777b538SAndroid Build Coastguard Worker if (i != pop->nfds) {
347*6777b538SAndroid Build Coastguard Worker /*
348*6777b538SAndroid Build Coastguard Worker * Shift the last pollfd down into the now-unoccupied
349*6777b538SAndroid Build Coastguard Worker * position.
350*6777b538SAndroid Build Coastguard Worker */
351*6777b538SAndroid Build Coastguard Worker memcpy(&pop->event_set[i], &pop->event_set[pop->nfds],
352*6777b538SAndroid Build Coastguard Worker sizeof(struct pollfd));
353*6777b538SAndroid Build Coastguard Worker pop->event_r_back[i] = pop->event_r_back[pop->nfds];
354*6777b538SAndroid Build Coastguard Worker pop->event_w_back[i] = pop->event_w_back[pop->nfds];
355*6777b538SAndroid Build Coastguard Worker pop->idxplus1_by_fd[pop->event_set[i].fd] = i + 1;
356*6777b538SAndroid Build Coastguard Worker }
357*6777b538SAndroid Build Coastguard Worker
358*6777b538SAndroid Build Coastguard Worker poll_check_ok(pop);
359*6777b538SAndroid Build Coastguard Worker return (0);
360*6777b538SAndroid Build Coastguard Worker }
361*6777b538SAndroid Build Coastguard Worker
362*6777b538SAndroid Build Coastguard Worker static void
poll_dealloc(struct event_base * base,void * arg)363*6777b538SAndroid Build Coastguard Worker poll_dealloc(struct event_base *base, void *arg)
364*6777b538SAndroid Build Coastguard Worker {
365*6777b538SAndroid Build Coastguard Worker struct pollop *pop = arg;
366*6777b538SAndroid Build Coastguard Worker
367*6777b538SAndroid Build Coastguard Worker evsignal_dealloc(base);
368*6777b538SAndroid Build Coastguard Worker if (pop->event_set)
369*6777b538SAndroid Build Coastguard Worker free(pop->event_set);
370*6777b538SAndroid Build Coastguard Worker if (pop->event_r_back)
371*6777b538SAndroid Build Coastguard Worker free(pop->event_r_back);
372*6777b538SAndroid Build Coastguard Worker if (pop->event_w_back)
373*6777b538SAndroid Build Coastguard Worker free(pop->event_w_back);
374*6777b538SAndroid Build Coastguard Worker if (pop->idxplus1_by_fd)
375*6777b538SAndroid Build Coastguard Worker free(pop->idxplus1_by_fd);
376*6777b538SAndroid Build Coastguard Worker
377*6777b538SAndroid Build Coastguard Worker memset(pop, 0, sizeof(struct pollop));
378*6777b538SAndroid Build Coastguard Worker free(pop);
379*6777b538SAndroid Build Coastguard Worker }
380