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_kqueue_init();
142 tevent_standard_init();
145 _PRIVATE_ const struct tevent_ops *tevent_find_ops_byname(const char *name)
147 struct tevent_ops_list *e;
149 tevent_backend_init();
152 name = tevent_default_backend;
158 for (e = tevent_backends; e != NULL; e = e->next) {
159 if (0 == strcmp(e->name, name)) {
168 list available backends
170 const char **tevent_backend_list(TALLOC_CTX *mem_ctx)
172 const char **list = NULL;
173 struct tevent_ops_list *e;
175 tevent_backend_init();
177 for (e=tevent_backends;e;e=e->next) {
178 list = ev_str_list_add(list, e->name);
181 talloc_steal(mem_ctx, list);
186 static void tevent_common_wakeup_fini(struct tevent_context *ev);
190 static pthread_mutex_t tevent_contexts_mutex = PTHREAD_MUTEX_INITIALIZER;
191 static struct tevent_context *tevent_contexts = NULL;
192 static pthread_once_t tevent_atfork_initialized = PTHREAD_ONCE_INIT;
194 static void tevent_atfork_prepare(void)
196 struct tevent_context *ev;
199 ret = pthread_mutex_lock(&tevent_contexts_mutex);
204 for (ev = tevent_contexts; ev != NULL; ev = ev->next) {
205 ret = pthread_mutex_lock(&ev->scheduled_mutex);
207 tevent_abort(ev, "pthread_mutex_lock failed");
212 static void tevent_atfork_parent(void)
214 struct tevent_context *ev;
217 for (ev = DLIST_TAIL(tevent_contexts); ev != NULL;
218 ev = DLIST_PREV(ev)) {
219 ret = pthread_mutex_unlock(&ev->scheduled_mutex);
221 tevent_abort(ev, "pthread_mutex_unlock failed");
225 ret = pthread_mutex_unlock(&tevent_contexts_mutex);
231 static void tevent_atfork_child(void)
233 struct tevent_context *ev;
236 for (ev = DLIST_TAIL(tevent_contexts); ev != NULL;
237 ev = DLIST_PREV(ev)) {
238 struct tevent_threaded_context *tctx;
240 for (tctx = ev->threaded_contexts; tctx != NULL;
242 tctx->event_ctx = NULL;
245 ev->threaded_contexts = NULL;
247 ret = pthread_mutex_unlock(&ev->scheduled_mutex);
249 tevent_abort(ev, "pthread_mutex_unlock failed");
253 ret = pthread_mutex_unlock(&tevent_contexts_mutex);
259 static void tevent_prep_atfork(void)
263 ret = pthread_atfork(tevent_atfork_prepare,
264 tevent_atfork_parent,
265 tevent_atfork_child);
273 int tevent_common_context_destructor(struct tevent_context *ev)
275 struct tevent_fd *fd, *fn;
276 struct tevent_timer *te, *tn;
277 struct tevent_immediate *ie, *in;
278 struct tevent_signal *se, *sn;
283 ret = pthread_mutex_lock(&tevent_contexts_mutex);
288 DLIST_REMOVE(tevent_contexts, ev);
290 ret = pthread_mutex_unlock(&tevent_contexts_mutex);
296 if (ev->threaded_contexts != NULL) {
298 * Threaded contexts are indicators that threads are
299 * about to send us immediates via
300 * tevent_threaded_schedule_immediate. The caller
301 * needs to make sure that the tevent context lives
302 * long enough to receive immediates from all threads.
304 tevent_abort(ev, "threaded contexts exist");
307 tevent_common_wakeup_fini(ev);
309 for (fd = ev->fd_events; fd; fd = fn) {
311 fd->event_ctx = NULL;
312 DLIST_REMOVE(ev->fd_events, fd);
315 ev->last_zero_timer = NULL;
316 for (te = ev->timer_events; te; te = tn) {
318 te->event_ctx = NULL;
319 DLIST_REMOVE(ev->timer_events, te);
322 for (ie = ev->immediate_events; ie; ie = in) {
324 ie->event_ctx = NULL;
325 ie->cancel_fn = NULL;
326 DLIST_REMOVE(ev->immediate_events, ie);
329 for (se = ev->signal_events; se; se = sn) {
331 se->event_ctx = NULL;
332 DLIST_REMOVE(ev->signal_events, se);
334 * This is important, Otherwise signals
335 * are handled twice in child. eg, SIGHUP.
336 * one added in parent, and another one in
337 * the child. -- BoYang
339 tevent_cleanup_pending_signal_handlers(se);
342 /* removing nesting hook or we get an abort when nesting is
343 * not allowed. -- SSS
344 * Note that we need to leave the allowed flag at its current
345 * value, otherwise the use in tevent_re_initialise() will
346 * leave the event context with allowed forced to false, which
347 * will break users that expect nesting to be allowed
349 ev->nesting.level = 0;
350 ev->nesting.hook_fn = NULL;
351 ev->nesting.hook_private = NULL;
357 create a event_context structure for a specific implemementation.
358 This must be the first events call, and all subsequent calls pass
359 this event_context as the first element. Event handlers also
360 receive this as their first argument.
362 This function is for allowing third-party-applications to hook in gluecode
363 to their own event loop code, so that they can make async usage of our client libs
365 NOTE: use tevent_context_init() inside of samba!
367 struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx,
368 const struct tevent_ops *ops,
369 void *additional_data)
371 struct tevent_context *ev;
374 ev = talloc_zero(mem_ctx, struct tevent_context);
375 if (!ev) return NULL;
379 ret = pthread_once(&tevent_atfork_initialized, tevent_prep_atfork);
385 ret = pthread_mutex_init(&ev->scheduled_mutex, NULL);
391 ret = pthread_mutex_lock(&tevent_contexts_mutex);
393 pthread_mutex_destroy(&ev->scheduled_mutex);
398 DLIST_ADD(tevent_contexts, ev);
400 ret = pthread_mutex_unlock(&tevent_contexts_mutex);
407 talloc_set_destructor(ev, tevent_common_context_destructor);
410 ev->additional_data = additional_data;
412 /* FD and TIMER events are always supported */
413 ev->features |= TEVENT_FEATURE_FD_SUPPORT;
414 ev->features |= TEVENT_FEATURE_TIMER_SUPPORT;
416 ret = ev->ops->context_init(ev);
426 create a event_context structure. This must be the first events
427 call, and all subsequent calls pass this event_context as the first
428 element. Event handlers also receive this as their first argument.
430 struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx,
433 const struct tevent_ops *ops;
435 ops = tevent_find_ops_byname(name);
440 return tevent_context_init_ops(mem_ctx, ops, NULL);
445 create a event_context structure. This must be the first events
446 call, and all subsequent calls pass this event_context as the first
447 element. Event handlers also receive this as their first argument.
449 struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx)
451 return tevent_context_init_byname(mem_ctx, NULL);
456 return NULL on failure (memory allocation error)
458 struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
462 tevent_fd_handler_t handler,
464 const char *handler_name,
465 const char *location)
467 return ev->ops->add_fd(ev, mem_ctx, fd, flags, handler, private_data,
468 handler_name, location);
472 set a close function on the fd event
474 void tevent_fd_set_close_fn(struct tevent_fd *fde,
475 tevent_fd_close_fn_t close_fn)
478 if (!fde->event_ctx) return;
479 fde->event_ctx->ops->set_fd_close_fn(fde, close_fn);
482 static void tevent_fd_auto_close_fn(struct tevent_context *ev,
483 struct tevent_fd *fde,
490 void tevent_fd_set_auto_close(struct tevent_fd *fde)
492 tevent_fd_set_close_fn(fde, tevent_fd_auto_close_fn);
496 return the fd event flags
498 uint16_t tevent_fd_get_flags(struct tevent_fd *fde)
501 if (!fde->event_ctx) return 0;
502 return fde->event_ctx->ops->get_fd_flags(fde);
506 set the fd event flags
508 void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags)
511 if (!fde->event_ctx) return;
512 fde->event_ctx->ops->set_fd_flags(fde, flags);
515 bool tevent_signal_support(struct tevent_context *ev)
517 if (ev->ops->add_signal) {
523 static void (*tevent_abort_fn)(const char *reason);
525 void tevent_set_abort_fn(void (*abort_fn)(const char *reason))
527 tevent_abort_fn = abort_fn;
530 static void tevent_abort(struct tevent_context *ev, const char *reason)
532 tevent_debug(ev, TEVENT_DEBUG_FATAL,
533 "abort: %s\n", reason);
535 if (!tevent_abort_fn) {
539 tevent_abort_fn(reason);
544 return NULL on failure
546 struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
548 struct timeval next_event,
549 tevent_timer_handler_t handler,
551 const char *handler_name,
552 const char *location)
554 return ev->ops->add_timer(ev, mem_ctx, next_event, handler, private_data,
555 handler_name, location);
559 allocate an immediate event
560 return NULL on failure (memory allocation error)
562 struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx,
563 const char *location)
565 struct tevent_immediate *im;
567 im = talloc(mem_ctx, struct tevent_immediate);
568 if (im == NULL) return NULL;
572 im->event_ctx = NULL;
573 im->create_location = location;
575 im->private_data = NULL;
576 im->handler_name = NULL;
577 im->schedule_location = NULL;
578 im->cancel_fn = NULL;
579 im->additional_data = NULL;
585 schedule an immediate event
587 void _tevent_schedule_immediate(struct tevent_immediate *im,
588 struct tevent_context *ev,
589 tevent_immediate_handler_t handler,
591 const char *handler_name,
592 const char *location)
594 ev->ops->schedule_immediate(im, ev, handler, private_data,
595 handler_name, location);
601 sa_flags are flags to sigaction(2)
603 return NULL on failure
605 struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
609 tevent_signal_handler_t handler,
611 const char *handler_name,
612 const char *location)
614 return ev->ops->add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data,
615 handler_name, location);
618 void tevent_loop_allow_nesting(struct tevent_context *ev)
620 ev->nesting.allowed = true;
623 void tevent_loop_set_nesting_hook(struct tevent_context *ev,
624 tevent_nesting_hook hook,
627 if (ev->nesting.hook_fn &&
628 (ev->nesting.hook_fn != hook ||
629 ev->nesting.hook_private != private_data)) {
630 /* the way the nesting hook code is currently written
631 we cannot support two different nesting hooks at the
633 tevent_abort(ev, "tevent: Violation of nesting hook rules\n");
635 ev->nesting.hook_fn = hook;
636 ev->nesting.hook_private = private_data;
639 static void tevent_abort_nesting(struct tevent_context *ev, const char *location)
643 reason = talloc_asprintf(NULL, "tevent_loop_once() nesting at %s",
646 reason = "tevent_loop_once() nesting";
649 tevent_abort(ev, reason);
653 do a single event loop using the events defined in ev
655 int _tevent_loop_once(struct tevent_context *ev, const char *location)
658 void *nesting_stack_ptr = NULL;
662 if (ev->nesting.level > 1) {
663 if (!ev->nesting.allowed) {
664 tevent_abort_nesting(ev, location);
669 if (ev->nesting.level > 0) {
670 if (ev->nesting.hook_fn) {
672 ret2 = ev->nesting.hook_fn(ev,
673 ev->nesting.hook_private,
676 (void *)&nesting_stack_ptr,
685 tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE);
686 ret = ev->ops->loop_once(ev, location);
687 tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE);
689 if (ev->nesting.level > 0) {
690 if (ev->nesting.hook_fn) {
692 ret2 = ev->nesting.hook_fn(ev,
693 ev->nesting.hook_private,
696 (void *)&nesting_stack_ptr,
711 this is a performance optimization for the samba4 nested event loop problems
713 int _tevent_loop_until(struct tevent_context *ev,
714 bool (*finished)(void *private_data),
716 const char *location)
719 void *nesting_stack_ptr = NULL;
723 if (ev->nesting.level > 1) {
724 if (!ev->nesting.allowed) {
725 tevent_abort_nesting(ev, location);
730 if (ev->nesting.level > 0) {
731 if (ev->nesting.hook_fn) {
733 ret2 = ev->nesting.hook_fn(ev,
734 ev->nesting.hook_private,
737 (void *)&nesting_stack_ptr,
746 while (!finished(private_data)) {
747 tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_LOOP_ONCE);
748 ret = ev->ops->loop_once(ev, location);
749 tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_LOOP_ONCE);
755 if (ev->nesting.level > 0) {
756 if (ev->nesting.hook_fn) {
758 ret2 = ev->nesting.hook_fn(ev,
759 ev->nesting.hook_private,
762 (void *)&nesting_stack_ptr,
776 bool tevent_common_have_events(struct tevent_context *ev)
778 if (ev->fd_events != NULL) {
779 if (ev->fd_events != ev->wakeup_fde) {
782 if (ev->fd_events->next != NULL) {
787 * At this point we just have the wakeup pipe event as
788 * the only fd_event. That one does not count as a
789 * regular event, so look at the other event types.
793 return ((ev->timer_events != NULL) ||
794 (ev->immediate_events != NULL) ||
795 (ev->signal_events != NULL));
799 return on failure or (with 0) if all fd events are removed
801 int tevent_common_loop_wait(struct tevent_context *ev,
802 const char *location)
805 * loop as long as we have events pending
807 while (tevent_common_have_events(ev)) {
809 ret = _tevent_loop_once(ev, location);
811 tevent_debug(ev, TEVENT_DEBUG_FATAL,
812 "_tevent_loop_once() failed: %d - %s\n",
813 ret, strerror(errno));
818 tevent_debug(ev, TEVENT_DEBUG_WARNING,
819 "tevent_common_loop_wait() out of events\n");
824 return on failure or (with 0) if all fd events are removed
826 int _tevent_loop_wait(struct tevent_context *ev, const char *location)
828 return ev->ops->loop_wait(ev, location);
833 re-initialise a tevent context. This leaves you with the same
834 event context, but all events are wiped and the structure is
835 re-initialised. This is most useful after a fork()
837 zero is returned on success, non-zero on failure
839 int tevent_re_initialise(struct tevent_context *ev)
841 tevent_common_context_destructor(ev);
843 return ev->ops->context_init(ev);
846 static void wakeup_pipe_handler(struct tevent_context *ev,
847 struct tevent_fd *fde,
848 uint16_t flags, void *_private)
854 * This is the boilerplate for eventfd, but it works
855 * for pipes too. And as we don't care about the data
856 * we read, we're fine.
859 ret = read(fde->fd, &val, sizeof(val));
860 } while (ret == -1 && errno == EINTR);
864 * Initialize the wakeup pipe and pipe fde
867 int tevent_common_wakeup_init(struct tevent_context *ev)
871 if (ev->wakeup_fde != NULL) {
876 ret = eventfd(0, EFD_NONBLOCK);
884 ret = pipe(pipe_fds);
888 ev->wakeup_fd = pipe_fds[0];
889 ev->wakeup_write_fd = pipe_fds[1];
891 ev_set_blocking(ev->wakeup_fd, false);
892 ev_set_blocking(ev->wakeup_write_fd, false);
896 ev->wakeup_fde = tevent_add_fd(ev, ev, ev->wakeup_fd,
898 wakeup_pipe_handler, NULL);
899 if (ev->wakeup_fde == NULL) {
900 close(ev->wakeup_fd);
902 close(ev->wakeup_write_fd);
910 int tevent_common_wakeup(struct tevent_context *ev)
914 if (ev->wakeup_fde == NULL) {
921 ret = write(ev->wakeup_fd, &val, sizeof(val));
924 ret = write(ev->wakeup_write_fd, &c, 1);
926 } while ((ret == -1) && (errno == EINTR));
931 static void tevent_common_wakeup_fini(struct tevent_context *ev)
933 if (ev->wakeup_fde == NULL) {
937 TALLOC_FREE(ev->wakeup_fde);
939 close(ev->wakeup_fd);
941 close(ev->wakeup_write_fd);