2 Unix SMB/CIFS implementation.
3 main select loop and event handling
4 Copyright (C) Andrew Tridgell 2003-2005
5 Copyright (C) Stefan Metzmacher 2005
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 This is SAMBA's default event loop code
25 - we try to use epoll if configure detected support for it
26 otherwise we use select()
27 - if epoll is broken on the system or the kernel doesn't support it
28 at runtime we fallback to select()
32 #include "system/filesys.h"
33 #include "system/select.h" /* needed for WITH_EPOLL */
34 #include "dlinklist.h"
35 #include "lib/events/events.h"
36 #include "lib/events/events_internal.h"
38 struct std_event_context {
39 /* a pointer back to the generic event_context */
40 struct event_context *ev;
42 /* list of filedescriptor events */
43 struct fd_event *fd_events;
45 /* list of timed events */
46 struct timed_event *timed_events;
48 /* the maximum file descriptor number in fd_events */
51 /* information for exiting from the event loop */
54 /* this is changed by the destructors for the fd event
55 type. It is used to detect event destruction by event
56 handlers, which means the code that is calling the event
57 handler needs to assume that the linked list is no longer
60 uint32_t destruction_count;
62 /* when using epoll this is the handle from epoll_create */
66 static void std_event_loop_timer(struct std_event_context *std_ev);
68 /* use epoll if it is available */
71 called when a epoll call fails, and we should fallback
74 static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason)
76 DEBUG(0,("%s (%s) - falling back to select()\n", reason, strerror(errno)));
77 close(std_ev->epoll_fd);
78 std_ev->epoll_fd = -1;
79 talloc_set_destructor(std_ev, NULL);
83 map from EVENT_FD_* to EPOLLIN/EPOLLOUT
85 static uint32_t epoll_map_flags(uint16_t flags)
88 if (flags & EVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
89 if (flags & EVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
96 static int epoll_ctx_destructor(void *ptr)
98 struct std_event_context *std_ev = talloc_get_type(ptr,
99 struct std_event_context);
100 close(std_ev->epoll_fd);
101 std_ev->epoll_fd = -1;
108 static void epoll_init_ctx(struct std_event_context *std_ev, BOOL try_epoll)
110 if (!try_epoll) return;
111 std_ev->epoll_fd = epoll_create(64);
112 talloc_set_destructor(std_ev, epoll_ctx_destructor);
115 #define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
116 #define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
117 #define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
120 add the epoll event to the given fd_event
122 static void epoll_add_event(struct std_event_context *std_ev, struct fd_event *fde)
124 struct epoll_event event;
125 if (std_ev->epoll_fd == -1) return;
127 fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
129 /* if we don't want events yet, don't add an epoll_event */
130 if (fde->flags == 0) return;
133 event.events = epoll_map_flags(fde->flags);
134 event.data.ptr = fde;
135 if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
136 epoll_fallback_to_select(std_ev, "EPOLL_CTL_ADD failed");
138 fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
140 /* only if we want to read we want to tell the event handler about errors */
141 if (fde->flags & EVENT_FD_READ) {
142 fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
147 delete the epoll event for given fd_event
149 static void epoll_del_event(struct std_event_context *std_ev, struct fd_event *fde)
151 struct epoll_event event;
152 if (std_ev->epoll_fd == -1) return;
154 fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
156 /* if there's no epoll_event, we don't need to delete it */
157 if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT)) return;
160 event.events = epoll_map_flags(fde->flags);
161 event.data.ptr = fde;
162 epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event);
163 fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
167 change the epoll event to the given fd_event
169 static void epoll_mod_event(struct std_event_context *std_ev, struct fd_event *fde)
171 struct epoll_event event;
172 if (std_ev->epoll_fd == -1) return;
174 fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
177 event.events = epoll_map_flags(fde->flags);
178 event.data.ptr = fde;
179 if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
180 epoll_fallback_to_select(std_ev, "EPOLL_CTL_MOD failed");
183 /* only if we want to read we want to tell the event handler about errors */
184 if (fde->flags & EVENT_FD_READ) {
185 fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
189 static void epoll_change_event(struct std_event_context *std_ev, struct fd_event *fde)
191 BOOL got_error = (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR);
192 BOOL want_read = (fde->flags & EVENT_FD_READ);
193 BOOL want_write= (fde->flags & EVENT_FD_WRITE);
195 if (std_ev->epoll_fd == -1) return;
197 fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
199 /* there's already an event */
200 if (fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT) {
201 if (want_read || (want_write && !got_error)) {
202 epoll_mod_event(std_ev, fde);
206 * if we want to match the select behavior, we need to remove the epoll_event
207 * when the caller isn't interested in events.
209 * this is because epoll reports EPOLLERR and EPOLLHUP, even without asking for them
211 epoll_del_event(std_ev, fde);
215 /* there's no epoll_event attached to the fde */
216 if (want_read || (want_write && !got_error)) {
217 epoll_add_event(std_ev, fde);
223 event loop handling using epoll
225 static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tvalp)
229 struct epoll_event events[MAXEVENTS];
230 uint32_t destruction_count = std_ev->destruction_count;
233 if (std_ev->epoll_fd == -1) return -1;
236 /* it's better to trigger timed events a bit later than to early */
237 timeout = ((tvalp->tv_usec+999) / 1000) + (tvalp->tv_sec*1000);
240 ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
242 if (ret == -1 && errno != EINTR) {
243 epoll_fallback_to_select(std_ev, "epoll_wait() failed");
247 if (ret == 0 && tvalp) {
248 std_event_loop_timer(std_ev);
252 for (i=0;i<ret;i++) {
253 struct fd_event *fde = talloc_get_type(events[i].data.ptr,
258 epoll_fallback_to_select(std_ev, "epoll_wait() gave bad data");
261 if (events[i].events & (EPOLLHUP|EPOLLERR)) {
262 fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR;
264 * if we only wait for EVENT_FD_WRITE, we should not tell the
265 * event handler about it, and remove the epoll_event,
266 * as we only report errors when waiting for read events,
267 * to match the select() behavior
269 if (!(fde->additional_flags & EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR)) {
270 epoll_del_event(std_ev, fde);
273 flags |= EVENT_FD_READ;
275 if (events[i].events & EPOLLIN) flags |= EVENT_FD_READ;
276 if (events[i].events & EPOLLOUT) flags |= EVENT_FD_WRITE;
278 fde->handler(std_ev->ev, fde, flags, fde->private_data);
279 if (destruction_count != std_ev->destruction_count) {
288 #define epoll_init_ctx(std_ev,try_epoll) if (try_epoll) {/* fix unused variable warning*/}
289 #define epoll_add_event(std_ev,fde)
290 #define epoll_del_event(std_ev,fde)
291 #define epoll_change_event(std_ev,fde)
292 #define epoll_event_loop(std_ev,tvalp) (-1)
296 create a std_event_context structure.
298 static int std_event_context_init(struct event_context *ev, void *private_data)
300 struct std_event_context *std_ev;
301 BOOL *_try_epoll = private_data;
302 BOOL try_epoll = (_try_epoll == NULL ? True : *_try_epoll);
304 std_ev = talloc_zero(ev, struct std_event_context);
305 if (!std_ev) return -1;
307 std_ev->epoll_fd = -1;
309 epoll_init_ctx(std_ev, try_epoll);
311 ev->additional_data = std_ev;
316 recalculate the maxfd
318 static void calc_maxfd(struct std_event_context *std_ev)
320 struct fd_event *fde;
323 for (fde = std_ev->fd_events; fde; fde = fde->next) {
324 if (fde->fd > std_ev->maxfd) {
325 std_ev->maxfd = fde->fd;
331 /* to mark the ev->maxfd invalid
332 * this means we need to recalculate it
334 #define EVENT_INVALID_MAXFD (-1)
339 static int std_event_fd_destructor(void *ptr)
341 struct fd_event *fde = talloc_get_type(ptr, struct fd_event);
342 struct event_context *ev = fde->event_ctx;
343 struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
344 struct std_event_context);
346 if (std_ev->maxfd == fde->fd) {
347 std_ev->maxfd = EVENT_INVALID_MAXFD;
350 DLIST_REMOVE(std_ev->fd_events, fde);
351 std_ev->destruction_count++;
353 epoll_del_event(std_ev, fde);
360 return NULL on failure (memory allocation error)
362 static struct fd_event *std_event_add_fd(struct event_context *ev, TALLOC_CTX *mem_ctx,
363 int fd, uint16_t flags,
364 event_fd_handler_t handler,
367 struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
368 struct std_event_context);
369 struct fd_event *fde;
371 fde = talloc(mem_ctx?mem_ctx:ev, struct fd_event);
372 if (!fde) return NULL;
377 fde->handler = handler;
378 fde->private_data = private_data;
379 fde->additional_flags = 0;
380 fde->additional_data = NULL;
382 DLIST_ADD(std_ev->fd_events, fde);
383 if (fde->fd > std_ev->maxfd) {
384 std_ev->maxfd = fde->fd;
386 talloc_set_destructor(fde, std_event_fd_destructor);
388 epoll_add_event(std_ev, fde);
395 return the fd event flags
397 static uint16_t std_event_get_fd_flags(struct fd_event *fde)
403 set the fd event flags
405 static void std_event_set_fd_flags(struct fd_event *fde, uint16_t flags)
407 struct event_context *ev;
408 struct std_event_context *std_ev;
410 if (fde->flags == flags) return;
413 std_ev = talloc_get_type(ev->additional_data, struct std_event_context);
417 epoll_change_event(std_ev, fde);
421 destroy a timed event
423 static int std_event_timed_destructor(void *ptr)
425 struct timed_event *te = talloc_get_type(ptr, struct timed_event);
426 struct std_event_context *std_ev = talloc_get_type(te->event_ctx->additional_data,
427 struct std_event_context);
428 DLIST_REMOVE(std_ev->timed_events, te);
432 static int std_event_timed_deny_destructor(void *ptr)
439 return NULL on failure (memory allocation error)
441 static struct timed_event *std_event_add_timed(struct event_context *ev, TALLOC_CTX *mem_ctx,
442 struct timeval next_event,
443 event_timed_handler_t handler,
446 struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
447 struct std_event_context);
448 struct timed_event *te, *last_te, *cur_te;
450 te = talloc(mem_ctx?mem_ctx:ev, struct timed_event);
451 if (te == NULL) return NULL;
454 te->next_event = next_event;
455 te->handler = handler;
456 te->private_data = private_data;
457 te->additional_data = NULL;
459 /* keep the list ordered */
461 for (cur_te = std_ev->timed_events; cur_te; cur_te = cur_te->next) {
462 /* if the new event comes before the current one break */
463 if (!timeval_is_zero(&cur_te->next_event) &&
464 timeval_compare(&te->next_event,
465 &cur_te->next_event) < 0) {
472 DLIST_ADD_AFTER(std_ev->timed_events, te, last_te);
474 talloc_set_destructor(te, std_event_timed_destructor);
480 a timer has gone off - call it
482 static void std_event_loop_timer(struct std_event_context *std_ev)
484 struct timeval t = timeval_current();
485 struct timed_event *te = std_ev->timed_events;
491 /* deny the handler to free the event */
492 talloc_set_destructor(te, std_event_timed_deny_destructor);
494 /* We need to remove the timer from the list before calling the
495 * handler because in a semi-async inner event loop called from the
496 * handler we don't want to come across this event again -- vl */
497 DLIST_REMOVE(std_ev->timed_events, te);
499 te->handler(std_ev->ev, te, t, te->private_data);
501 /* The destructor isn't necessary anymore, we've already removed the
502 * event from the list. */
503 talloc_set_destructor(te, NULL);
509 event loop handling using select()
511 static int std_event_loop_select(struct std_event_context *std_ev, struct timeval *tvalp)
514 struct fd_event *fde;
516 uint32_t destruction_count = std_ev->destruction_count;
518 /* we maybe need to recalculate the maxfd */
519 if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
526 /* setup any fd events */
527 for (fde = std_ev->fd_events; fde; fde = fde->next) {
528 if (fde->flags & EVENT_FD_READ) {
529 FD_SET(fde->fd, &r_fds);
531 if (fde->flags & EVENT_FD_WRITE) {
532 FD_SET(fde->fd, &w_fds);
536 selrtn = select(std_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
538 if (selrtn == -1 && errno == EBADF) {
539 /* the socket is dead! this should never
540 happen as the socket should have first been
541 made readable and that should have removed
542 the event, so this must be a bug. This is a
544 DEBUG(0,("ERROR: EBADF on std_event_loop_once\n"));
545 std_ev->exit_code = EBADF;
549 if (selrtn == 0 && tvalp) {
550 std_event_loop_timer(std_ev);
555 /* at least one file descriptor is ready - check
556 which ones and call the handler, being careful to allow
557 the handler to remove itself when called */
558 for (fde = std_ev->fd_events; fde; fde = fde->next) {
561 if (FD_ISSET(fde->fd, &r_fds)) flags |= EVENT_FD_READ;
562 if (FD_ISSET(fde->fd, &w_fds)) flags |= EVENT_FD_WRITE;
564 fde->handler(std_ev->ev, fde, flags, fde->private_data);
565 if (destruction_count != std_ev->destruction_count) {
576 do a single event loop using the events defined in ev
578 static int std_event_loop_once(struct event_context *ev)
580 struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
581 struct std_event_context);
584 /* work out the right timeout for all timed events */
585 if (std_ev->timed_events) {
586 struct timeval t = timeval_current();
587 tval = timeval_until(&t, &std_ev->timed_events->next_event);
588 if (timeval_is_zero(&tval)) {
589 std_event_loop_timer(std_ev);
593 /* have a default tick time of 30 seconds. This guarantees
594 that code that uses its own timeout checking will be
595 able to proceeed eventually */
596 tval = timeval_set(30, 0);
599 if (epoll_event_loop(std_ev, &tval) == 0) {
603 return std_event_loop_select(std_ev, &tval);
607 return on failure or (with 0) if all fd events are removed
609 static int std_event_loop_wait(struct event_context *ev)
611 struct std_event_context *std_ev = talloc_get_type(ev->additional_data,
612 struct std_event_context);
613 std_ev->exit_code = 0;
615 while (std_ev->fd_events && std_ev->exit_code == 0) {
616 if (std_event_loop_once(ev) != 0) {
621 return std_ev->exit_code;
624 static const struct event_ops std_event_ops = {
625 .context_init = std_event_context_init,
626 .add_fd = std_event_add_fd,
627 .get_fd_flags = std_event_get_fd_flags,
628 .set_fd_flags = std_event_set_fd_flags,
629 .add_timed = std_event_add_timed,
630 .loop_once = std_event_loop_once,
631 .loop_wait = std_event_loop_wait,
634 const struct event_ops *event_standard_get_ops(void)
636 return &std_event_ops;