tevent: document tevent_req_create state zeroing
[mat/samba.git] / lib / tevent / tevent.h
index 7f9f72a57aebf3b74458cd2d54552acf931410bd..2bc4e2d7ad761fcbc5bc4854b97616a97683bd03 100644 (file)
@@ -111,7 +111,7 @@ typedef void (*tevent_signal_handler_t)(struct tevent_context *ev,
 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
@@ -119,12 +119,26 @@ struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx);
  *
  * @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.
  *
@@ -501,6 +515,60 @@ int tevent_set_debug(struct tevent_context *ev,
  */
 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);
+
 /**
  * @}
  */
@@ -851,9 +919,9 @@ bool _tevent_req_cancel(struct tevent_req *req, const char *location);
  * 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.
@@ -1047,6 +1115,48 @@ void _tevent_req_oom(struct tevent_req *req,
 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.
  *
@@ -1305,6 +1415,7 @@ struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs);
  */
 
 struct tevent_queue;
+struct tevent_queue_entry;
 
 #ifdef DOXYGEN
 /**
@@ -1316,8 +1427,8 @@ struct tevent_queue;
  *
  * @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);
@@ -1339,6 +1450,8 @@ struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx,
  *                          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);
@@ -1353,7 +1466,9 @@ typedef void (*tevent_queue_trigger_fn_t)(struct tevent_req *req,
  * @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.
  *
@@ -1366,6 +1481,79 @@ bool tevent_queue_add(struct tevent_queue *queue,
                      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.
  *
@@ -1393,6 +1581,17 @@ void tevent_queue_stop(struct tevent_queue *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,