OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2000-2003 Niels Provos <provos@citi.umich.edu> | 2 * Copyright 2000-2003 Niels Provos <provos@citi.umich.edu> |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 int nevents; | 68 int nevents; |
69 int epfd; | 69 int epfd; |
70 }; | 70 }; |
71 | 71 |
72 static void *epoll_init (struct event_base *); | 72 static void *epoll_init (struct event_base *); |
73 static int epoll_add (void *, struct event *); | 73 static int epoll_add (void *, struct event *); |
74 static int epoll_del (void *, struct event *); | 74 static int epoll_del (void *, struct event *); |
75 static int epoll_dispatch (struct event_base *, void *, struct timeval *); | 75 static int epoll_dispatch (struct event_base *, void *, struct timeval *); |
76 static void epoll_dealloc (struct event_base *, void *); | 76 static void epoll_dealloc (struct event_base *, void *); |
77 | 77 |
78 struct eventop epollops = { | 78 const struct eventop epollops = { |
79 "epoll", | 79 "epoll", |
80 epoll_init, | 80 epoll_init, |
81 epoll_add, | 81 epoll_add, |
82 epoll_del, | 82 epoll_del, |
83 epoll_dispatch, | 83 epoll_dispatch, |
84 epoll_dealloc, | 84 epoll_dealloc, |
85 1 /* need reinit */ | 85 1 /* need reinit */ |
86 }; | 86 }; |
87 | 87 |
88 #ifdef HAVE_SETFD | 88 #ifdef HAVE_SETFD |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 evsignal_init(base); | 159 evsignal_init(base); |
160 | 160 |
161 return (epollop); | 161 return (epollop); |
162 } | 162 } |
163 | 163 |
164 static int | 164 static int |
165 epoll_recalc(struct event_base *base, void *arg, int max) | 165 epoll_recalc(struct event_base *base, void *arg, int max) |
166 { | 166 { |
167 struct epollop *epollop = arg; | 167 struct epollop *epollop = arg; |
168 | 168 |
169 » if (max > epollop->nfds) { | 169 » if (max >= epollop->nfds) { |
170 struct evepoll *fds; | 170 struct evepoll *fds; |
171 int nfds; | 171 int nfds; |
172 | 172 |
173 nfds = epollop->nfds; | 173 nfds = epollop->nfds; |
174 while (nfds < max) | 174 while (nfds < max) |
175 nfds <<= 1; | 175 nfds <<= 1; |
176 | 176 |
177 fds = realloc(epollop->fds, nfds * sizeof(struct evepoll)); | 177 fds = realloc(epollop->fds, nfds * sizeof(struct evepoll)); |
178 if (fds == NULL) { | 178 if (fds == NULL) { |
179 event_warn("realloc"); | 179 event_warn("realloc"); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 return (0); | 217 return (0); |
218 } else if (base->sig.evsignal_caught) { | 218 } else if (base->sig.evsignal_caught) { |
219 evsignal_process(base); | 219 evsignal_process(base); |
220 } | 220 } |
221 | 221 |
222 event_debug(("%s: epoll_wait reports %d", __func__, res)); | 222 event_debug(("%s: epoll_wait reports %d", __func__, res)); |
223 | 223 |
224 for (i = 0; i < res; i++) { | 224 for (i = 0; i < res; i++) { |
225 int what = events[i].events; | 225 int what = events[i].events; |
226 struct event *evread = NULL, *evwrite = NULL; | 226 struct event *evread = NULL, *evwrite = NULL; |
| 227 int fd = events[i].data.fd; |
227 | 228 |
228 » » evep = (struct evepoll *)events[i].data.ptr; | 229 » » if (fd < 0 && fd >= epollop->nfds) |
| 230 » » » continue; |
| 231 » » evep = &epollop->fds[fd]; |
229 | 232 |
230 if (what & (EPOLLHUP|EPOLLERR)) { | 233 if (what & (EPOLLHUP|EPOLLERR)) { |
231 evread = evep->evread; | 234 evread = evep->evread; |
232 evwrite = evep->evwrite; | 235 evwrite = evep->evwrite; |
233 } else { | 236 } else { |
234 if (what & EPOLLIN) { | 237 if (what & EPOLLIN) { |
235 evread = evep->evread; | 238 evread = evep->evread; |
236 } | 239 } |
237 | 240 |
238 if (what & EPOLLOUT) { | 241 if (what & EPOLLOUT) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 if (evep->evwrite != NULL) { | 283 if (evep->evwrite != NULL) { |
281 events |= EPOLLOUT; | 284 events |= EPOLLOUT; |
282 op = EPOLL_CTL_MOD; | 285 op = EPOLL_CTL_MOD; |
283 } | 286 } |
284 | 287 |
285 if (ev->ev_events & EV_READ) | 288 if (ev->ev_events & EV_READ) |
286 events |= EPOLLIN; | 289 events |= EPOLLIN; |
287 if (ev->ev_events & EV_WRITE) | 290 if (ev->ev_events & EV_WRITE) |
288 events |= EPOLLOUT; | 291 events |= EPOLLOUT; |
289 | 292 |
290 » epev.data.ptr = evep; | 293 » epev.data.fd = fd; |
291 epev.events = events; | 294 epev.events = events; |
292 if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) | 295 if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) |
293 return (-1); | 296 return (-1); |
294 | 297 |
295 /* Update events responsible */ | 298 /* Update events responsible */ |
296 if (ev->ev_events & EV_READ) | 299 if (ev->ev_events & EV_READ) |
297 evep->evread = ev; | 300 evep->evread = ev; |
298 if (ev->ev_events & EV_WRITE) | 301 if (ev->ev_events & EV_WRITE) |
299 evep->evwrite = ev; | 302 evep->evwrite = ev; |
300 | 303 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 events = EPOLLOUT; | 335 events = EPOLLOUT; |
333 op = EPOLL_CTL_MOD; | 336 op = EPOLL_CTL_MOD; |
334 } else if ((events & EPOLLOUT) && evep->evread != NULL) { | 337 } else if ((events & EPOLLOUT) && evep->evread != NULL) { |
335 needreaddelete = 0; | 338 needreaddelete = 0; |
336 events = EPOLLIN; | 339 events = EPOLLIN; |
337 op = EPOLL_CTL_MOD; | 340 op = EPOLL_CTL_MOD; |
338 } | 341 } |
339 } | 342 } |
340 | 343 |
341 epev.events = events; | 344 epev.events = events; |
342 » epev.data.ptr = evep; | 345 » epev.data.fd = fd; |
343 | 346 |
344 if (needreaddelete) | 347 if (needreaddelete) |
345 evep->evread = NULL; | 348 evep->evread = NULL; |
346 if (needwritedelete) | 349 if (needwritedelete) |
347 evep->evwrite = NULL; | 350 evep->evwrite = NULL; |
348 | 351 |
349 if (epoll_ctl(epollop->epfd, op, fd, &epev) == -1) | 352 if (epoll_ctl(epollop->epfd, op, fd, &epev) == -1) |
350 return (-1); | 353 return (-1); |
351 | 354 |
352 return (0); | 355 return (0); |
353 } | 356 } |
354 | 357 |
355 static void | 358 static void |
356 epoll_dealloc(struct event_base *base, void *arg) | 359 epoll_dealloc(struct event_base *base, void *arg) |
357 { | 360 { |
358 struct epollop *epollop = arg; | 361 struct epollop *epollop = arg; |
359 | 362 |
360 evsignal_dealloc(base); | 363 evsignal_dealloc(base); |
361 if (epollop->fds) | 364 if (epollop->fds) |
362 free(epollop->fds); | 365 free(epollop->fds); |
363 if (epollop->events) | 366 if (epollop->events) |
364 free(epollop->events); | 367 free(epollop->events); |
365 if (epollop->epfd >= 0) | 368 if (epollop->epfd >= 0) |
366 close(epollop->epfd); | 369 close(epollop->epfd); |
367 | 370 |
368 memset(epollop, 0, sizeof(struct epollop)); | 371 memset(epollop, 0, sizeof(struct epollop)); |
369 free(epollop); | 372 free(epollop); |
370 } | 373 } |
OLD | NEW |