2 Unix SMB/CIFS implementation.
4 generalised event loop handling
6 Copyright (C) Andrew Tridgell 2005
7 Copyright (C) Stefan Metzmacher 2005-2009
8 Copyright (C) Volker Lendecke 2008
10 ** NOTE! The following LGPL license applies to the tevent
11 ** library. This does NOT imply that all of Samba is released
14 This library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Lesser General Public
16 License as published by the Free Software Foundation; either
17 version 3 of the License, or (at your option) any later version.
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
24 You should have received a copy of the GNU Lesser General Public
25 License along with this library; if not, see <http://www.gnu.org/licenses/>.
33 #include <ccan/talloc/talloc.h>
34 #include <ccan/compiler/compiler.h>
36 struct tevent_context;
40 struct tevent_immediate;
44 * @defgroup tevent The tevent API
46 * The tevent low-level API
48 * This API provides the public interface to manage events in the tevent
49 * mainloop. Functions are provided for managing low-level events such
50 * as timer events, fd events and signal handling.
55 /* event handler types */
57 * Called when a file descriptor monitored by tevent has
58 * data to be read or written on it.
60 typedef void (*tevent_fd_handler_t)(struct tevent_context *ev,
61 struct tevent_fd *fde,
66 * Called when tevent is ceasing the monitoring of a file descriptor.
68 typedef void (*tevent_fd_close_fn_t)(struct tevent_context *ev,
69 struct tevent_fd *fde,
74 * Called when a tevent timer has fired.
76 typedef void (*tevent_timer_handler_t)(struct tevent_context *ev,
77 struct tevent_timer *te,
78 struct timeval current_time,
82 * Called when a tevent immediate event is invoked.
84 typedef void (*tevent_immediate_handler_t)(struct tevent_context *ctx,
85 struct tevent_immediate *im,
89 * Called after tevent detects the specified signal.
91 typedef void (*tevent_signal_handler_t)(struct tevent_context *ev,
92 struct tevent_signal *se,
99 * @brief Create a event_context structure.
101 * This must be the first events call, and all subsequent calls pass this
102 * event_context as the first element. Event handlers also receive this as
103 * their first argument.
105 * @param[in] mem_ctx The memory context to use.
107 * @return An allocated tevent context, NULL on error.
109 * @see tevent_context_init()
111 struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx);
114 * @brief Create a event_context structure and name it.
116 * This must be the first events call, and all subsequent calls pass this
117 * event_context as the first element. Event handlers also receive this as
118 * their first argument.
120 * @param[in] mem_ctx The memory context to use.
122 * @param[in] name The name for the tevent context.
124 * @return An allocated tevent context, NULL on error.
126 struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
129 * @brief List available backends.
131 * @param[in] mem_ctx The memory context to use.
133 * @return A string vector with a terminating NULL element, NULL
136 const char **tevent_backend_list(TALLOC_CTX *mem_ctx);
139 * @brief Set the default tevent backent.
141 * @param[in] backend The name of the backend to set.
143 void tevent_set_default_backend(const char *backend);
147 * @brief Add a file descriptor based event.
149 * @param[in] ev The event context to work on.
151 * @param[in] mem_ctx The talloc memory context to use.
153 * @param[in] fd The file descriptor to base the event on.
155 * @param[in] flags #TEVENT_FD_READ or #TEVENT_FD_WRITE
157 * @param[in] handler The callback handler for the event.
159 * @param[in] private_data The private data passed to the callback handler.
161 * @return The file descriptor based event, NULL on error.
163 * @note To cancel the monitoring of a file descriptor, call talloc_free()
164 * on the object returned by this function.
166 struct tevent_fd *tevent_add_fd(struct tevent_context *ev,
170 tevent_fd_handler_t handler,
173 struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
177 tevent_fd_handler_t handler,
179 const char *handler_name,
180 const char *location);
181 #define tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \
182 _tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \
183 #handler, __location__)
188 * @brief Add a timed event
190 * @param[in] ev The event context to work on.
192 * @param[in] mem_ctx The talloc memory context to use.
194 * @param[in] next_event Timeval specifying the absolute time to fire this
195 * event. This is not an offset.
197 * @param[in] handler The callback handler for the event.
199 * @param[in] private_data The private data passed to the callback handler.
201 * @return The newly-created timer event, or NULL on error.
203 * @note To cancel a timer event before it fires, call talloc_free() on the
204 * event returned from this function. This event is automatically
205 * talloc_free()-ed after its event handler files, if it hasn't been freed yet.
207 * @note Unlike some mainloops, tevent timers are one-time events. To set up
208 * a recurring event, it is necessary to call tevent_add_timer() again during
209 * the handler processing.
211 * @note Due to the internal mainloop processing, a timer set to run
212 * immediately will do so after any other pending timers fire, but before
213 * any further file descriptor or signal handling events fire. Callers should
214 * not rely on this behavior!
216 struct tevent_timer *tevent_add_timer(struct tevent_context *ev,
218 struct timeval next_event,
219 tevent_timer_handler_t handler,
222 struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
224 struct timeval next_event,
225 tevent_timer_handler_t handler,
227 const char *handler_name,
228 const char *location);
229 #define tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) \
230 _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \
231 #handler, __location__)
236 * Initialize an immediate event object
238 * This object can be used to trigger an event to occur immediately after
239 * returning from the current event (before any other event occurs)
241 * @param[in] mem_ctx The talloc memory context to use as the parent
243 * @return An empty tevent_immediate object. Use tevent_schedule_immediate
244 * to populate and use it.
246 * @note Available as of tevent 0.9.8
248 struct tevent_immediate *tevent_create_immediate(TALLOC_CTX *mem_ctx);
250 struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx,
251 const char *location);
252 #define tevent_create_immediate(mem_ctx) \
253 _tevent_create_immediate(mem_ctx, __location__)
259 * Schedule an event for immediate execution. This event will occur
260 * immediately after returning from the current event (before any other
263 * @param[in] im The tevent_immediate object to populate and use
264 * @param[in] ctx The tevent_context to run this event
265 * @param[in] handler The event handler to run when this event fires
266 * @param[in] private_data Data to pass to the event handler
268 void tevent_schedule_immediate(struct tevent_immediate *im,
269 struct tevent_context *ctx,
270 tevent_immediate_handler_t handler,
273 void _tevent_schedule_immediate(struct tevent_immediate *im,
274 struct tevent_context *ctx,
275 tevent_immediate_handler_t handler,
277 const char *handler_name,
278 const char *location);
279 #define tevent_schedule_immediate(im, ctx, handler, private_data) \
280 _tevent_schedule_immediate(im, ctx, handler, private_data, \
281 #handler, __location__);
286 * @brief Add a tevent signal handler
288 * tevent_add_signal() creates a new event for handling a signal the next
289 * time through the mainloop. It implements a very simple traditional signal
290 * handler whose only purpose is to add the handler event into the mainloop.
292 * @param[in] ev The event context to work on.
294 * @param[in] mem_ctx The talloc memory context to use.
296 * @param[in] signum The signal to trap
298 * @param[in] handler The callback handler for the signal.
300 * @param[in] sa_flags sigaction flags for this signal handler.
302 * @param[in] private_data The private data passed to the callback handler.
304 * @return The newly-created signal handler event, or NULL on error.
306 * @note To cancel a signal handler, call talloc_free() on the event returned
307 * from this function.
309 struct tevent_signal *tevent_add_signal(struct tevent_context *ev,
313 tevent_signal_handler_t handler,
316 struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
320 tevent_signal_handler_t handler,
322 const char *handler_name,
323 const char *location);
324 #define tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \
325 _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \
326 #handler, __location__)
331 * @brief Pass a single time through the mainloop
333 * This will process any appropriate signal, immediate, fd and timer events
335 * @param[in] ev The event context to process
337 * @return Zero on success, nonzero if an internal error occurred
339 int tevent_loop_once(struct tevent_context *ev);
341 int _tevent_loop_once(struct tevent_context *ev, const char *location);
342 #define tevent_loop_once(ev) \
343 _tevent_loop_once(ev, __location__)
348 * @brief Run the mainloop
350 * The mainloop will run until there are no events remaining to be processed
352 * @param[in] ev The event context to process
354 * @return Zero if all events have been processed. Nonzero if an internal
357 int tevent_loop_wait(struct tevent_context *ev);
359 int _tevent_loop_wait(struct tevent_context *ev, const char *location);
360 #define tevent_loop_wait(ev) \
361 _tevent_loop_wait(ev, __location__)
366 * Assign a function to run when a tevent_fd is freed
368 * This function is a destructor for the tevent_fd. It does not automatically
369 * close the file descriptor. If this is the desired behavior, then it must be
370 * performed by the close_fn.
372 * @param[in] fde File descriptor event on which to set the destructor
373 * @param[in] close_fn Destructor to execute when fde is freed
375 void tevent_fd_set_close_fn(struct tevent_fd *fde,
376 tevent_fd_close_fn_t close_fn);
379 * Automatically close the file descriptor when the tevent_fd is freed
381 * This function calls close(fd) internally.
383 * @param[in] fde File descriptor event to auto-close
385 void tevent_fd_set_auto_close(struct tevent_fd *fde);
388 * Return the flags set on this file descriptor event
390 * @param[in] fde File descriptor event to query
392 * @return The flags set on the event. See #TEVENT_FD_READ and
395 uint16_t tevent_fd_get_flags(struct tevent_fd *fde);
398 * Set flags on a file descriptor event
400 * @param[in] fde File descriptor event to set
401 * @param[in] flags Flags to set on the event. See #TEVENT_FD_READ and
404 void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
407 * Query whether tevent supports signal handling
409 * @param[in] ev An initialized tevent context
411 * @return True if this platform and tevent context support signal handling
413 bool tevent_signal_support(struct tevent_context *ev);
415 void tevent_set_abort_fn(void (*abort_fn)(const char *reason));
417 /* bits for file descriptor event flags */
420 * Monitor a file descriptor for write availability
422 #define TEVENT_FD_READ 1
424 * Monitor a file descriptor for data to be read
426 #define TEVENT_FD_WRITE 2
429 * Convenience function for declaring a tevent_fd writable
431 #define TEVENT_FD_WRITEABLE(fde) \
432 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_WRITE)
435 * Convenience function for declaring a tevent_fd readable
437 #define TEVENT_FD_READABLE(fde) \
438 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_READ)
441 * Convenience function for declaring a tevent_fd non-writable
443 #define TEVENT_FD_NOT_WRITEABLE(fde) \
444 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_WRITE)
447 * Convenience function for declaring a tevent_fd non-readable
449 #define TEVENT_FD_NOT_READABLE(fde) \
450 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ)
453 * Debug level of tevent
455 enum tevent_debug_level {
458 TEVENT_DEBUG_WARNING,
463 * @brief The tevent debug callbac.
465 * @param[in] context The memory context to use.
467 * @param[in] level The debug level.
469 * @param[in] fmt The format string.
471 * @param[in] ap The arguments for the format string.
473 typedef void (*tevent_debug_fn)(void *context,
474 enum tevent_debug_level level,
476 va_list ap) PRINTF_FMT(3,0);
479 * Set destination for tevent debug messages
481 * @param[in] ev Event context to debug
482 * @param[in] debug Function to handle output printing
483 * @param[in] context The context to pass to the debug function.
485 * @return Always returns 0 as of version 0.9.8
487 * @note Default is to emit no debug messages
489 int tevent_set_debug(struct tevent_context *ev,
490 tevent_debug_fn debug,
494 * Designate stderr for debug message output
496 * @param[in] ev Event context to debug
498 * @note This function will only output TEVENT_DEBUG_FATAL, TEVENT_DEBUG_ERROR
499 * and TEVENT_DEBUG_WARNING messages. For TEVENT_DEBUG_TRACE, please define a
500 * function for tevent_set_debug()
502 int tevent_set_debug_stderr(struct tevent_context *ev);
505 * @defgroup tevent_helpers The tevent helper functiions
514 * @brief Compare two timeval values.
516 * @param[in] tv1 The first timeval value to compare.
518 * @param[in] tv2 The second timeval value to compare.
520 * @return 0 if they are equal.
521 * 1 if the first time is greater than the second.
522 * -1 if the first time is smaller than the second.
524 int tevent_timeval_compare(const struct timeval *tv1,
525 const struct timeval *tv2);
528 * @brief Get a zero timval value.
530 * @return A zero timval value.
532 struct timeval tevent_timeval_zero(void);
535 * @brief Get a timeval value for the current time.
537 * @return A timval value with the current time.
539 struct timeval tevent_timeval_current(void);
542 * @brief Get a timeval structure with the given values.
544 * @param[in] secs The seconds to set.
546 * @param[in] usecs The milliseconds to set.
548 * @return A timeval structure with the given values.
550 struct timeval tevent_timeval_set(uint32_t secs, uint32_t usecs);
553 * @brief Get the difference between two timeval values.
555 * @param[in] tv1 The first timeval.
557 * @param[in] tv2 The second timeval.
559 * @return A timeval structure with the difference between the
560 * first and the second value.
562 struct timeval tevent_timeval_until(const struct timeval *tv1,
563 const struct timeval *tv2);
566 * @brief Check if a given timeval structure is zero.
568 * @param[in] tv The timeval to check if it is zero.
570 * @return True if it is zero, false otherwise.
572 bool tevent_timeval_is_zero(const struct timeval *tv);
575 * @brief Add the given amount of time to a timeval structure.
577 * @param[in] tv The timeval structure to add the time.
579 * @param[in] secs The seconds to add to the timeval.
581 * @param[in] usecs The milliseconds to add to the timeval.
583 * @return The timeval structure with the new time.
585 struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs,
589 * @brief Get a timeval in the future with a specified offset from now.
591 * @param[in] secs The seconds of the offset from now.
593 * @param[in] usecs The milliseconds of the offset from now.
595 * @return A timval with the given offset in the future.
597 struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs);
602 * @defgroup tevent_ops The tevent operation functions
605 * The following structure and registration functions are exclusively
606 * needed for people writing and pluggin a different event engine.
607 * There is nothing useful for normal tevent user in here.
613 int (*context_init)(struct tevent_context *ev);
615 /* fd_event functions */
616 struct tevent_fd *(*add_fd)(struct tevent_context *ev,
618 int fd, uint16_t flags,
619 tevent_fd_handler_t handler,
621 const char *handler_name,
622 const char *location);
623 void (*set_fd_close_fn)(struct tevent_fd *fde,
624 tevent_fd_close_fn_t close_fn);
625 uint16_t (*get_fd_flags)(struct tevent_fd *fde);
626 void (*set_fd_flags)(struct tevent_fd *fde, uint16_t flags);
628 /* timed_event functions */
629 struct tevent_timer *(*add_timer)(struct tevent_context *ev,
631 struct timeval next_event,
632 tevent_timer_handler_t handler,
634 const char *handler_name,
635 const char *location);
637 /* immediate event functions */
638 void (*schedule_immediate)(struct tevent_immediate *im,
639 struct tevent_context *ev,
640 tevent_immediate_handler_t handler,
642 const char *handler_name,
643 const char *location);
645 /* signal functions */
646 struct tevent_signal *(*add_signal)(struct tevent_context *ev,
648 int signum, int sa_flags,
649 tevent_signal_handler_t handler,
651 const char *handler_name,
652 const char *location);
655 int (*loop_once)(struct tevent_context *ev, const char *location);
656 int (*loop_wait)(struct tevent_context *ev, const char *location);
659 bool tevent_register_backend(const char *name, const struct tevent_ops *ops);
664 #endif /* __TEVENT_H__ */