2 Unix SMB/CIFS implementation.
3 main select loop and event handling
4 Copyright (C) Andrew Tridgell 2003
5 Copyright (C) Stefan Metzmacher 2009
7 ** NOTE! The following LGPL license applies to the tevent
8 ** library. This does NOT imply that all of Samba is released
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Lesser General Public
13 License as published by the Free Software Foundation; either
14 version 3 of the License, or (at your option) any later version.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, see <http://www.gnu.org/licenses/>.
26 PLEASE READ THIS BEFORE MODIFYING!
28 This module is a general abstraction for the main select loop and
29 event handling. Do not ever put any localised hacks in here, instead
30 register one of the possible event types and implement that event
33 There are 2 types of event handling that are handled in this module:
35 1) a file descriptor becoming readable or writeable. This is mostly
36 used for network sockets, but can be used for any type of file
37 descriptor. You may only register one handler for each file
38 descriptor/io combination or you will get unpredictable results
39 (this means that you can have a handler for read events, and a
40 separate handler for write events, but not two handlers that are
41 both handling read events)
43 2) a timed event. You can register an event that happens at a
44 specific time. You can register as many of these as you
45 like. They are single shot - add a new timed event in the event
46 handler to get another event.
48 To setup a set of events you first need to create a event_context
49 structure using the function tevent_context_init(); This returns a
50 'struct tevent_context' that you use in all subsequent calls.
52 After that you can add/remove events that you are interested in
53 using tevent_add_*() and talloc_free()
55 Finally, you call tevent_loop_wait_once() to block waiting for one of the
56 events to occor or tevent_loop_wait() which will loop
61 #include "system/filesys.h"
63 #include "system/threads.h"
65 #define TEVENT_DEPRECATED 1
67 #include "tevent_internal.h"
68 #include "tevent_util.h"
70 #include <sys/eventfd.h>
73 static void tevent_abort(struct tevent_context *ev, const char *reason);
75 struct tevent_ops_list {
76 struct tevent_ops_list *next, *prev;
78 const struct tevent_ops *ops;
81 /* list of registered event backends */
82 static struct tevent_ops_list *tevent_backends = NULL;
83 static char *tevent_default_backend = NULL;
86 register an events backend
88 bool tevent_register_backend(const char *name, const struct tevent_ops *ops)
90 struct tevent_ops_list *e;
92 for (e = tevent_backends; e != NULL; e = e->next) {
93 if (0 == strcmp(e->name, name)) {
94 /* already registered, skip it */
99 e = talloc(NULL, struct tevent_ops_list);
100 if (e == NULL) return false;
104 DLIST_ADD(tevent_backends, e);
110 set the default event backend
112 void tevent_set_default_backend(const char *backend)
114 talloc_free(tevent_default_backend);
115 tevent_default_backend = talloc_strdup(NULL, backend);
119 initialise backends if not already done
121 static void tevent_backend_init(void)
131 tevent_select_init();
133 tevent_poll_mt_init();
134 #if defined(HAVE_EPOLL)
136 #elif defined(HAVE_SOLARIS_PORTS)
140 tevent_standard_init();
143 _PRIVATE_ const struct tevent_ops *tevent_find_ops_byname(const char *name)
145 struct tevent_ops_list *e;
147 tevent_backend_init();
150 name = tevent_default_backend;
156 for (e = tevent_backends; e != NULL; e = e->next) {
157 if (0 == strcmp(e->name, name)) {
166 list available backends
168 const char **tevent_backend_list(TALLOC_CTX *mem_ctx)
170 const char **list = NULL;
171 struct tevent_ops_list *e;
173 tevent_backend_init();
175 for (e=tevent_backends;e;e=e->next) {
176 list = ev_str_list_add(list, e->name);
179 talloc_steal(mem_ctx, list);
184 static void tevent_common_wakeup_fini(struct tevent_context *ev);
188 static pthread_mutex_t tevent_contexts_mutex = PTHREAD_MUTEX_INITIALIZER;
189 static struct tevent_context *tevent_contexts = NULL;
190 static pthread_once_t tevent_atfork_initialized = PTHREAD_ONCE_INIT;
192 static void tevent_atfork_prepare(void)
194 struct tevent_context *ev;
197 ret = pthread_mutex_lock(&tevent_contexts_mutex);
202 for (ev = tevent_contexts; ev != NULL; ev = ev->next) {
203 ret = pthread_mutex_lock(&ev->scheduled_mutex);
205 tevent_abort(ev, "pthread_mutex_lock failed");
210 static void tevent_atfork_parent(void)
212 struct tevent_context *ev;
215 for (ev = DLIST_TAIL(tevent_contexts); ev != NULL;
216 ev = DLIST_PREV(ev)) {
217 ret = pthread_mutex_unlock(&ev->scheduled_mutex);
219 tevent_abort(ev, "pthread_mutex_unlock failed");
223 ret = pthread_mutex_unlock(&tevent_contexts_mutex);
229 static void tevent_atfork_child(void)
231 struct tevent_context *ev;
234 for (ev = DLIST_TAIL(tevent_contexts); ev != NULL;
235 ev = DLIST_PREV(ev)) {
236 struct tevent_threaded_context *tctx;
238 for (tctx = ev->threaded_contexts; tctx != NULL;
240 tctx->event_ctx = NULL;
243 ev->threaded_contexts = NULL;
245 ret = pthread_mutex_unlock(&ev->scheduled_mutex);
247 tevent_abort(ev, "pthread_mutex_unlock failed");
251 ret = pthread_mutex_unlock(&tevent_contexts_mutex);
257 static void tevent_prep_atfork(void)
261 ret = pthread_atfork(tevent_atfork_prepare,
262 tevent_atfork_parent,
263 tevent_atfork_child);
271 int tevent_common_context_destructor(struct tevent_context *ev)
273 struct tevent_fd *fd, *fn;
274 struct tevent_timer *te, *tn;
275 struct tevent_immediate *ie, *in;
276 struct tevent_signal *se, *sn;
281 ret = pthread_mutex_lock(&tevent_contexts_mutex);
286 DLIST_REMOVE(tevent_contexts, ev);
288 ret = pthread_mutex_unlock(&tevent_contexts_mutex);
294 if (ev->threaded_contexts != NULL) {
296 * Threaded contexts are indicators that threads are
297 * about to send us immediates via
298 * tevent_threaded_schedule_immediate. The caller
299 * needs to make sure that the tevent context lives
300 * long enough to receive immediates from all threads.
302 tevent_abort(ev, "threaded contexts exist");
305 tevent_common_wakeup_fini(ev);
307 for (fd = ev->fd_events; fd; fd = fn) {
309 fd->event_ctx = NULL;
310 DLIST_REMOVE(ev->fd_events, fd);
313 ev->last_zero_timer = NULL;
314 for (te = ev->timer_events; te; te = tn) {
316 te->event_ctx = NULL;
317 DLIST_REMOVE(ev->timer_events, te);
320 for (ie = ev->immediate_events; ie; ie = in) {
322 ie->event_ctx = NULL;
323 ie->cancel_fn = NULL;
324 DLIST_REMOVE(ev->immediate_events, ie);
327 for (se = ev->signal_events; se; se = sn) {
329 se->event_ctx = NULL;
330 DLIST_REMOVE(ev->signal_events, se);
332 * This is important, Otherwise signals
333 * are handled twice in child. eg, SIGHUP.
334 * one added in parent, and another one in
335 * the child. -- BoYang
337 tevent_cleanup_pending_signal_handlers(se);
340 /* removing nesting hook or we get an abort when nesting is
341 * not allowed. -- SSS
342 * Note that we need to leave the allowed flag at its current
343 * value, otherwise the use in tevent_re_initialise() will
344 * leave the event context with allowed forced to false, which
345 * will break users that expect nesting to be allowed
347 ev->nesting.level = 0;
348 ev->nesting.hook_fn = NULL;
349 ev->nesting.hook_private = NULL;
355 create a event_context structure for a specific implemementation.
356 This must be the first events call, and all subsequent calls pass
357 this event_context as the first element. Event handlers also
358 receive this as their first argument.
360 This function is for allowing third-party-applications to hook in gluecode
361 to their own event loop code, so that they can make async usage of our client libs
363 NOTE: use tevent_context_init() inside of samba!
365 struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx,
366 const struct tevent_ops *ops,
367 void *additional_data)
369 struct tevent_context *ev;
372 ev = talloc_zero(mem_ctx, struct tevent_context);
373 if (!ev) return NULL;
377 ret = pthread_once(&tevent_atfork_initialized, tevent_prep_atfork);
383 ret = pthread_mutex_init(&ev->scheduled_mutex, NULL);
389 ret = pthread_mutex_lock(&tevent_contexts_mutex);
391 pthread_mutex_destroy(&ev->scheduled_mutex);
396 DLIST_ADD(tevent_contexts, ev);
398 ret = pthread_mutex_unlock(&tevent_contexts_mutex);
405 talloc_set_destructor(ev, tevent_common_context_destructor);
408 ev->additional_data = additional_data;
410 ret = ev->ops->context_init(ev);
420 create a event_context structure. This must be the first events
421 call, and all subsequent calls pass this event_context as the first
422 element. Event handlers also receive this as their first argument.
424 struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx,
427 const struct tevent_ops *ops;
429 ops = tevent_find_ops_byname(name);
434 return tevent_context_init_ops(mem_ctx, ops, NULL);
439 create a event_context structure. This must be the first events
440 call, and all subsequent calls pass this event_context as the first
441 element. Event handlers also receive this as their first argument.
443 struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx)
445 return tevent_context_init_byname(mem_ctx, NULL);
450 return NULL on failure (memory allocation error)
452 struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
456 tevent_fd_handler_t handler,
458 const char *handler_name,
459 const char *location)
461 return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data,
462 handler_name, location);
466 set a close function on the fd event
468 void tevent_fd_set_close_fn(struct tevent_fd *fde,
469 tevent_fd_close_fn_t close_fn)
472 if (!fde->event_ctx) return;
473 fde->event_ctx->ops->set_fd_close_fn(fde, close_fn);
476 static void tevent_fd_auto_close_fn(struct tevent_context *ev,
477 struct tevent_fd *fde,
484 void tevent_fd_set_auto_close(struct tevent_fd *fde)
486 tevent_fd_set_close_fn(fde, tevent_fd_auto_close_fn);
490 return the fd event flags
492 uint16_t tevent_fd_get_flags(struct tevent_fd *fde)
495 if (!fde->event_ctx) return 0;
496 return fde->event_ctx->ops->get_fd_flags(fde);
500 set the fd event flags
502 void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags)
505 if (!fde->event_ctx) return;
506 fde->event_ctx->ops->set_fd_flags(fde, flags);
509 bool tevent_signal_support(struct tevent_context *ev)
511 if (ev->ops->add_signal) {
517 static void (*tevent_abort_fn)(const char *reason);
519 void tevent_set_abort_fn(void (*abort_fn)(const char *reason))
521 tevent_abort_fn = abort_fn;
524 static void tevent_abort(struct tevent_context *ev, const char *reason)
526 tevent_debug(ev, TEVENT_DEBUG_FATAL,
527 "abort: %s\n", reason);
529 if (!tevent_abort_fn) {
533 tevent_abort_fn(reason);
538 return NULL on failure
540 struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
542 struct timeval next_event,
543 tevent_timer_handler_t handler,
545 const char *handler_name,
546 const char *location)
548 return ev->ops->add_timer(ev, mem_ctx, next_event, handler, private_data,
549 handler_name, location);
553 allocate an immediate event
554 return NULL on failure (memory allocation error)
556 struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx,
557 const char *location)
559 struct tevent_immediate *im;
561 im = talloc(mem_ctx, struct tevent_immediate);
562 if (im == NULL) return NULL;
566 im->event_ctx = NULL;
567 im->create_location = location;
569 im->private_data = NULL;
570 im->handler_name = NULL;
571 im->schedule_location = NULL;
572 im->cancel_fn = NULL;
573 im->additional_data = NULL;
579 schedule an immediate event
581 void _tevent_schedule_immediate(struct tevent_immediate *im,
582 struct tevent_context *ev,
583 tevent_immediate_handler_t handler,
585 const char *handler_name,
586 const char *location)
588 ev->ops->schedule_immediate(im, ev, handler, private_data,
589 handler_name, location);
595 sa_flags are flags to sigaction(2)
597 return NULL on failure
599 struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
603 tevent_signal_handler_t handler,
605 const char *handler_name,
606 const char *location)
608 return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data,
609 handler_name, location);
612 void tevent_loop_allow_nesting(struct tevent_context *ev)
614 ev->nesting.allowed = true;
617 void tevent_loop_set_nesting_hook(struct tevent_context *ev,
618 tevent_nesting_hook hook,
621 if (ev->nesting.hook_fn &&
622 (ev->nesting.hook_fn != hook ||
623 ev->nesting.hook_private != private_data)) {
624 /* the way the nesting hook code is currently written
625 we cannot support two different nesting hooks at the
627 tevent_abort(ev, "tevent: Violation of nesting hook rules\n");
629 ev->nesting.hook_fn = hook;
630 ev->nesting.hook_private = private_data;
633 static void tevent_abort_nesting(struct tevent_context *ev, const char *location)
637 reason = talloc_asprintf(NULL, "tevent_loop_once() nesting at %s",
640 reason = "tevent_loop_once() nesting";
643 tevent_abort(ev, reason);
647 do a single event loop using the events defined in ev
649 int _tevent_loop_once(struct tevent_context *ev, const char *location)
652 void *nesting_stack_ptr = NULL;
656 if (ev->nesting.level > 1) {
657 if (!ev->nesting.allowed) {
658 tevent_abort_nesting(ev, location);
663 if (ev->nesting.level > 0) {
664 if (ev->nesting.hook_fn) {
666 ret2 = ev->nesting.hook_fn(ev,
667 ev->nesting.hook_private,
670 (void *)&nesting_stack_ptr,
679 tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE);
680 ret = ev->ops->loop_once(ev, location);
681 tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE);
683 if (ev->nesting.level > 0) {
684 if (ev->nesting.hook_fn) {
686 ret2 = ev->nesting.hook_fn(ev,
687 ev->nesting.hook_private,
690 (void *)&nesting_stack_ptr,
705 this is a performance optimization for the samba4 nested event loop problems
707 int _tevent_loop_until(struct tevent_context *ev,
708 bool (*finished)(void *private_data),
710 const char *location)
713 void *nesting_stack_ptr = NULL;
717 if (ev->nesting.level > 1) {
718 if (!ev->nesting.allowed) {
719 tevent_abort_nesting(ev, location);
724 if (ev->nesting.level > 0) {
725 if (ev->nesting.hook_fn) {
727 ret2 = ev->nesting.hook_fn(ev,
728 ev->nesting.hook_private,
731 (void *)&nesting_stack_ptr,
740 while (!finished(private_data)) {
741 tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE);
742 ret = ev->ops->loop_once(ev, location);
743 tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE);
749 if (ev->nesting.level > 0) {
750 if (ev->nesting.hook_fn) {
752 ret2 = ev->nesting.hook_fn(ev,
753 ev->nesting.hook_private,
756 (void *)&nesting_stack_ptr,
770 bool tevent_common_have_events(struct tevent_context *ev)
772 if (ev->fd_events != NULL) {
773 if (ev->fd_events != ev->wakeup_fde) {
776 if (ev->fd_events->next != NULL) {
781 * At this point we just have the wakeup pipe event as
782 * the only fd_event. That one does not count as a
783 * regular event, so look at the other event types.
787 return ((ev->timer_events != NULL) ||
788 (ev->immediate_events != NULL) ||
789 (ev->signal_events != NULL));
793 return on failure or (with 0) if all fd events are removed
795 int tevent_common_loop_wait(struct tevent_context *ev,
796 const char *location)
799 * loop as long as we have events pending
801 while (tevent_common_have_events(ev)) {
803 ret = _tevent_loop_once(ev, location);
805 tevent_debug(ev, TEVENT_DEBUG_FATAL,
806 "_tevent_loop_once() failed: %d - %s\n",
807 ret, strerror(errno));
812 tevent_debug(ev, TEVENT_DEBUG_WARNING,
813 "tevent_common_loop_wait() out of events\n");
818 return on failure or (with 0) if all fd events are removed
820 int _tevent_loop_wait(struct tevent_context *ev, const char *location)
822 return ev->ops->loop_wait(ev, location);
827 re-initialise a tevent context. This leaves you with the same
828 event context, but all events are wiped and the structure is
829 re-initialised. This is most useful after a fork()
831 zero is returned on success, non-zero on failure
833 int tevent_re_initialise(struct tevent_context *ev)
835 tevent_common_context_destructor(ev);
837 return ev->ops->context_init(ev);
840 static void wakeup_pipe_handler(struct tevent_context *ev,
841 struct tevent_fd *fde,
842 uint16_t flags, void *_private)
848 * This is the boilerplate for eventfd, but it works
849 * for pipes too. And as we don't care about the data
850 * we read, we're fine.
853 ret = read(fde->fd, &val, sizeof(val));
854 } while (ret == -1 && errno == EINTR);
858 * Initialize the wakeup pipe and pipe fde
861 int tevent_common_wakeup_init(struct tevent_context *ev)
865 if (ev->wakeup_fde != NULL) {
870 ret = eventfd(0, EFD_NONBLOCK);
878 ret = pipe(pipe_fds);
882 ev->wakeup_fd = pipe_fds[0];
883 ev->wakeup_write_fd = pipe_fds[1];
885 ev_set_blocking(ev->wakeup_fd, false);
886 ev_set_blocking(ev->wakeup_write_fd, false);
890 ev->wakeup_fde = tevent_add_fd(ev, ev, ev->wakeup_fd,
892 wakeup_pipe_handler, NULL);
893 if (ev->wakeup_fde == NULL) {
894 close(ev->wakeup_fd);
896 close(ev->wakeup_write_fd);
904 int tevent_common_wakeup(struct tevent_context *ev)
908 if (ev->wakeup_fde == NULL) {
915 ret = write(ev->wakeup_fd, &val, sizeof(val));
918 ret = write(ev->wakeup_write_fd, &c, 1);
920 } while ((ret == -1) && (errno == EINTR));
925 static void tevent_common_wakeup_fini(struct tevent_context *ev)
927 if (ev->wakeup_fde == NULL) {
931 TALLOC_FREE(ev->wakeup_fde);
933 close(ev->wakeup_fd);
935 close(ev->wakeup_write_fd);