Skip to content
Newer
Older
100644 242 lines (198 sloc) 5.5 KB
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
1 /* $OpenBSD: poll.c,v 1.2 2002/06/25 15:50:15 mickey Exp $ */
2
3 /*
4 * Copyright 2000-2003 Niels Provos <provos@citi.umich.edu>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
c3f496c @provos minor corrections; change license to 3-clause BSD license
provos authored Oct 4, 2003
15 * 3. The name of the author may not be used to endorse or promote products
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
3c2916a @provos ifdef config.h
provos authored Mar 1, 2003
29 #ifdef HAVE_CONFIG_H
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
30 #include "config.h"
3c2916a @provos ifdef config.h
provos authored Mar 1, 2003
31 #endif
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
32
33 #include <sys/types.h>
34 #ifdef HAVE_SYS_TIME_H
35 #include <sys/time.h>
36 #else
37 #include <sys/_time.h>
38 #endif
39 #include <sys/queue.h>
8773c4c @provos make libevent thread-safe; first cut
provos authored Nov 25, 2004
40 #include <sys/tree.h>
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
41 #include <poll.h>
42 #include <signal.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47 #include <errno.h>
48
49 #include "event.h"
8773c4c @provos make libevent thread-safe; first cut
provos authored Nov 25, 2004
50 #include "event-internal.h"
cde7a35 @provos fix signal usage
provos authored Mar 8, 2003
51 #include "evsignal.h"
fbdaf3a @provos debugging callbacks from Nick Mathewson <nickm@freehaven.net>
provos authored Mar 29, 2005
52 #include "log.h"
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
53
54 extern volatile sig_atomic_t evsignal_caught;
55
56 struct pollop {
57 int event_count; /* Highest number alloc */
58 struct pollfd *event_set;
59 struct event **event_back;
60 sigset_t evsigmask;
3ba224d @provos fixes for threaded operations from Andrew Danforth
provos authored Jan 3, 2005
61 };
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
62
63 void *poll_init (void);
64 int poll_add (void *, struct event *);
65 int poll_del (void *, struct event *);
8773c4c @provos make libevent thread-safe; first cut
provos authored Nov 25, 2004
66 int poll_recalc (struct event_base *, void *, int);
67 int poll_dispatch (struct event_base *, void *, struct timeval *);
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
68
69 struct eventop pollops = {
70 "poll",
71 poll_init,
72 poll_add,
73 poll_del,
74 poll_recalc,
75 poll_dispatch
76 };
77
78 void *
79 poll_init(void)
80 {
3ba224d @provos fixes for threaded operations from Andrew Danforth
provos authored Jan 3, 2005
81 struct pollop *pollop;
82
b5b585c @provos support disabling of event mechanisms via the environment; error out
provos authored Mar 1, 2003
83 /* Disable kqueue when this environment variable is set */
84 if (getenv("EVENT_NOPOLL"))
85 return (NULL);
86
3ba224d @provos fixes for threaded operations from Andrew Danforth
provos authored Jan 3, 2005
87 if (!(pollop = calloc(1, sizeof(struct pollop))))
88 return (NULL);
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
89
3ba224d @provos fixes for threaded operations from Andrew Danforth
provos authored Jan 3, 2005
90 evsignal_init(&pollop->evsigmask);
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
91
3ba224d @provos fixes for threaded operations from Andrew Danforth
provos authored Jan 3, 2005
92 return (pollop);
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
93 }
94
95 /*
96 * Called with the highest fd that we know about. If it is 0, completely
97 * recalculate everything.
98 */
99
100 int
8773c4c @provos make libevent thread-safe; first cut
provos authored Nov 25, 2004
101 poll_recalc(struct event_base *base, void *arg, int max)
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
102 {
103 struct pollop *pop = arg;
104
105 return (evsignal_recalc(&pop->evsigmask));
106 }
107
108 int
8773c4c @provos make libevent thread-safe; first cut
provos authored Nov 25, 2004
109 poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
110 {
111 int res, i, count, sec, nfds;
e72dff1 @provos replace references to __FUNCTION__ with __func__
provos authored Mar 1, 2003
112 struct event *ev;
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
113 struct pollop *pop = arg;
114
115 count = pop->event_count;
116 nfds = 0;
8773c4c @provos make libevent thread-safe; first cut
provos authored Nov 25, 2004
117 TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
118 if (nfds + 1 >= count) {
119 if (count < 32)
120 count = 32;
121 else
122 count *= 2;
123
124 /* We need more file descriptors */
125 pop->event_set = realloc(pop->event_set,
126 count * sizeof(struct pollfd));
127 if (pop->event_set == NULL) {
fbdaf3a @provos debugging callbacks from Nick Mathewson <nickm@freehaven.net>
provos authored Mar 29, 2005
128 event_warn("realloc");
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
129 return (-1);
130 }
131 pop->event_back = realloc(pop->event_back,
132 count * sizeof(struct event *));
133 if (pop->event_back == NULL) {
fbdaf3a @provos debugging callbacks from Nick Mathewson <nickm@freehaven.net>
provos authored Mar 29, 2005
134 event_warn("realloc");
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
135 return (-1);
136 }
137 pop->event_count = count;
138 }
139 if (ev->ev_events & EV_WRITE) {
140 struct pollfd *pfd = &pop->event_set[nfds];
141 pfd->fd = ev->ev_fd;
142 pfd->events = POLLOUT;
143 pfd->revents = 0;
144
145 pop->event_back[nfds] = ev;
146
147 nfds++;
148 }
149 if (ev->ev_events & EV_READ) {
150 struct pollfd *pfd = &pop->event_set[nfds];
151
152 pfd->fd = ev->ev_fd;
153 pfd->events = POLLIN;
154 pfd->revents = 0;
155
156 pop->event_back[nfds] = ev;
157
158 nfds++;
159 }
160 }
161
cde7a35 @provos fix signal usage
provos authored Mar 8, 2003
162 if (evsignal_deliver(&pop->evsigmask) == -1)
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
163 return (-1);
164
96a25ae @provos when converting usec to msec round up; so that libevent does not spin…
provos authored Sep 19, 2004
165 sec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
166 res = poll(pop->event_set, nfds, sec);
167
168 if (evsignal_recalc(&pop->evsigmask) == -1)
169 return (-1);
170
171 if (res == -1) {
172 if (errno != EINTR) {
fbdaf3a @provos debugging callbacks from Nick Mathewson <nickm@freehaven.net>
provos authored Mar 29, 2005
173 event_warn("poll");
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
174 return (-1);
175 }
176
177 evsignal_process();
178 return (0);
179 } else if (evsignal_caught)
180 evsignal_process();
181
fbdaf3a @provos debugging callbacks from Nick Mathewson <nickm@freehaven.net>
provos authored Mar 29, 2005
182 event_debug(("%s: poll reports %d", __func__, res));
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
183
184 if (res == 0)
185 return (0);
186
187 for (i = 0; i < nfds; i++) {
e1cd86d @provos fixes to handle error cases by Anatoly Vorobey at pobox.com
provos authored Oct 25, 2003
188 int what = pop->event_set[i].revents;
189
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
190 res = 0;
e1cd86d @provos fixes to handle error cases by Anatoly Vorobey at pobox.com
provos authored Oct 25, 2003
191
e506eaf @provos constify; some windows stuff by mike davis; fix a poll bug
provos authored Sep 25, 2003
192 /* If the file gets closed notify */
e1cd86d @provos fixes to handle error cases by Anatoly Vorobey at pobox.com
provos authored Oct 25, 2003
193 if (what & POLLHUP)
194 what |= POLLIN|POLLOUT;
195 if (what & POLLERR)
196 what |= POLLIN|POLLOUT;
197 if (what & POLLIN)
f08bf53 @provos fix poll hup support
provos authored Sep 25, 2003
198 res |= EV_READ;
e1cd86d @provos fixes to handle error cases by Anatoly Vorobey at pobox.com
provos authored Oct 25, 2003
199 if (what & POLLOUT)
f08bf53 @provos fix poll hup support
provos authored Sep 25, 2003
200 res |= EV_WRITE;
b3d1c6a @provos support poll(2) and split out the signal handling
provos authored Feb 28, 2003
201 if (res == 0)
202 continue;
203
204 ev = pop->event_back[i];
205 res &= ev->ev_events;
206
207 if (res) {
208 if (!(ev->ev_events & EV_PERSIST))
209 event_del(ev);
210 event_active(ev, res, 1);
211 }
212 }
213
214 return (0);
215 }
216
217 int
218 poll_add(void *arg, struct event *ev)
219 {
220 struct pollop *pop = arg;
221
222 if (ev->ev_events & EV_SIGNAL)
223 return (evsignal_add(&pop->evsigmask, ev));
224
225 return (0);
226 }
227
228 /*
229 * Nothing to be done here.
230 */
231
232 int
233 poll_del(void *arg, struct event *ev)
234 {
235 struct pollop *pop = arg;
236
237 if (!(ev->ev_events & EV_SIGNAL))
238 return (0);
239
240 return (evsignal_del(&pop->evsigmask, ev));
241 }
Something went wrong with that request. Please try again.