struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx);
/**
- * @brief Create a event_context structure and name it.
+ * @brief Create a event_context structure and select a specific backend.
*
* This must be the first events call, and all subsequent calls pass this
* event_context as the first element. Event handlers also receive this as
*
* @param[in] mem_ctx The memory context to use.
*
- * @param[in] name The name for the tevent context.
+ * @param[in] name The name of the backend to use.
*
* @return An allocated tevent context, NULL on error.
*/
struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
+/**
+ * @brief Create a custom event context
+ *
+ * @param[in] mem_ctx The memory context to use.
+ * @param[in] ops The function pointer table of the backend.
+ * @param[in] additional_data The additional/private data to this instance
+ *
+ * @return An allocated tevent context, NULL on error.
+ *
+ */
+struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx,
+ const struct tevent_ops *ops,
+ void *additional_data);
+
/**
* @brief List available backends.
*
*/
int tevent_set_debug_stderr(struct tevent_context *ev);
+enum tevent_trace_point {
+ /**
+ * Corresponds to a trace point just before waiting
+ */
+ TEVENT_TRACE_BEFORE_WAIT,
+ /**
+ * Corresponds to a trace point just after waiting
+ */
+ TEVENT_TRACE_AFTER_WAIT,
+#define TEVENT_HAS_LOOP_ONCE_TRACE_POINTS 1
+ /**
+ * Corresponds to a trace point just before calling
+ * the loop_once() backend function.
+ */
+ TEVENT_TRACE_BEFORE_LOOP_ONCE,
+ /**
+ * Corresponds to a trace point right after the
+ * loop_once() backend function has returned.
+ */
+ TEVENT_TRACE_AFTER_LOOP_ONCE,
+};
+
+typedef void (*tevent_trace_callback_t)(enum tevent_trace_point,
+ void *private_data);
+
+/**
+ * Register a callback to be called at certain trace points
+ *
+ * @param[in] ev Event context
+ * @param[in] cb Trace callback
+ * @param[in] private_data Data to be passed to callback
+ *
+ * @note The callback will be called at trace points defined by
+ * tevent_trace_point. Call with NULL to reset.
+ */
+void tevent_set_trace_callback(struct tevent_context *ev,
+ tevent_trace_callback_t cb,
+ void *private_data);
+
+/**
+ * Retrieve the current trace callback
+ *
+ * @param[in] ev Event context
+ * @param[out] cb Registered trace callback
+ * @param[out] private_data Registered data to be passed to callback
+ *
+ * @note This can be used to allow one component that wants to
+ * register a callback to respect the callback that another component
+ * has already registered.
+ */
+void tevent_get_trace_callback(struct tevent_context *ev,
+ tevent_trace_callback_t *cb,
+ void *private_data);
+
/**
* @}
*/
* req = tevent_req_create(mem_ctx, &state, struct computation_state);
* @endcode
*
- * Tevent_req_create() creates the state variable as a talloc child of
- * its result. The state variable should be used as the talloc parent
- * for all temporary variables that are allocated during the async
+ * Tevent_req_create() allocates and zeros the state variable as a talloc
+ * child of its result. The state variable should be used as the talloc
+ * parent for all temporary variables that are allocated during the async
* computation. This way, when the user of the async computation frees
* the request, the state as a talloc child will be free'd along with
* all the temporary variables hanging off the state.
struct tevent_req *tevent_req_post(struct tevent_req *req,
struct tevent_context *ev);
+/**
+ * @brief Finish multiple requests within one function
+ *
+ * Normally tevent_req_notify_callback() and all wrappers
+ * (e.g. tevent_req_done() and tevent_req_error())
+ * need to be the last thing an event handler should call.
+ * This is because the callback is likely to destroy the
+ * context of the current function.
+ *
+ * If a function wants to notify more than one caller,
+ * it is dangerous if it just triggers multiple callbacks
+ * in a row. With tevent_req_defer_callback() it is possible
+ * to set an event context that will be used to defer the callback
+ * via an immediate event (similar to tevent_req_post()).
+ *
+ * @code
+ * struct complete_state {
+ * struct tevent_context *ev;
+ *
+ * struct tevent_req **reqs;
+ * };
+ *
+ * void complete(struct complete_state *state)
+ * {
+ * size_t i, c = talloc_array_length(state->reqs);
+ *
+ * for (i=0; i < c; i++) {
+ * tevent_req_defer_callback(state->reqs[i], state->ev);
+ * tevent_req_done(state->reqs[i]);
+ * }
+ * }
+ * @endcode
+ *
+ * @param[in] req The finished request.
+ *
+ * @param[in] ev The tevent_context for the immediate event.
+ *
+ * @return The given request will be returned.
+ */
+void tevent_req_defer_callback(struct tevent_req *req,
+ struct tevent_context *ev);
+
/**
* @brief Check if the given request is still in progress.
*
*/
struct tevent_queue;
+struct tevent_queue_entry;
#ifdef DOXYGEN
/**
*
* @return An allocated tevent queue on success, NULL on error.
*
- * @see tevent_start()
- * @see tevent_stop()
+ * @see tevent_queue_start()
+ * @see tevent_queue_stop()
*/
struct tevent_queue *tevent_queue_create(TALLOC_CTX *mem_ctx,
const char *name);
* tevent_queue_add().
*
* @see tevent_queue_add()
+ * @see tevent_queue_add_entry()
+ * @see tevent_queue_add_optimize_empty()
*/
typedef void (*tevent_queue_trigger_fn_t)(struct tevent_req *req,
void *private_data);
* @param[in] req The tevent request to add to the queue.
*
* @param[in] trigger The function triggered by the queue when the request
- * is called.
+ * is called. Since tevent 0.9.14 it's possible to
+ * pass NULL, in order to just add a "blocker" to the
+ * queue.
*
* @param[in] private_data The private data passed to the trigger function.
*
tevent_queue_trigger_fn_t trigger,
void *private_data);
+/**
+ * @brief Add a tevent request to the queue.
+ *
+ * The request can be removed from the queue by calling talloc_free()
+ * (or a similar function) on the returned queue entry. This
+ * is the only difference to tevent_queue_add().
+ *
+ * @param[in] queue The queue to add the request.
+ *
+ * @param[in] ev The event handle to use for the request.
+ *
+ * @param[in] req The tevent request to add to the queue.
+ *
+ * @param[in] trigger The function triggered by the queue when the request
+ * is called. Since tevent 0.9.14 it's possible to
+ * pass NULL, in order to just add a "blocker" to the
+ * queue.
+ *
+ * @param[in] private_data The private data passed to the trigger function.
+ *
+ * @return a pointer to the tevent_queue_entry if the request
+ * has been successfully added, NULL otherwise.
+ *
+ * @see tevent_queue_add()
+ * @see tevent_queue_add_optimize_empty()
+ */
+struct tevent_queue_entry *tevent_queue_add_entry(
+ struct tevent_queue *queue,
+ struct tevent_context *ev,
+ struct tevent_req *req,
+ tevent_queue_trigger_fn_t trigger,
+ void *private_data);
+
+/**
+ * @brief Add a tevent request to the queue using a possible optimization.
+ *
+ * This tries to optimize for the empty queue case and may calls
+ * the trigger function directly. This is the only difference compared
+ * to tevent_queue_add_entry().
+ *
+ * The caller needs to be prepared that the trigger function has
+ * already called tevent_req_notify_callback(), tevent_req_error(),
+ * tevent_req_done() or a similar function.
+ *
+ * The request can be removed from the queue by calling talloc_free()
+ * (or a similar function) on the returned queue entry.
+ *
+ * @param[in] queue The queue to add the request.
+ *
+ * @param[in] ev The event handle to use for the request.
+ *
+ * @param[in] req The tevent request to add to the queue.
+ *
+ * @param[in] trigger The function triggered by the queue when the request
+ * is called. Since tevent 0.9.14 it's possible to
+ * pass NULL, in order to just add a "blocker" to the
+ * queue.
+ *
+ * @param[in] private_data The private data passed to the trigger function.
+ *
+ * @return a pointer to the tevent_queue_entry if the request
+ * has been successfully added, NULL otherwise.
+ *
+ * @see tevent_queue_add()
+ * @see tevent_queue_add_entry()
+ */
+struct tevent_queue_entry *tevent_queue_add_optimize_empty(
+ struct tevent_queue *queue,
+ struct tevent_context *ev,
+ struct tevent_req *req,
+ tevent_queue_trigger_fn_t trigger,
+ void *private_data);
+
/**
* @brief Start a tevent queue.
*
*/
size_t tevent_queue_length(struct tevent_queue *queue);
+/**
+ * @brief Is the tevent queue running.
+ *
+ * The queue is started by default.
+ *
+ * @param[in] queue The queue.
+ *
+ * @return Wether the queue is running or not..
+ */
+bool tevent_queue_running(struct tevent_queue *queue);
+
typedef int (*tevent_nesting_hook)(struct tevent_context *ev,
void *private_data,
uint32_t level,