summaryrefslogtreecommitdiff
path: root/lib/tevent/tevent.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tevent/tevent.h')
-rw-r--r--lib/tevent/tevent.h390
1 files changed, 375 insertions, 15 deletions
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index ad1f2c9cc3..edddcdf1d5 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -40,6 +40,16 @@ struct tevent_timer;
struct tevent_immediate;
struct tevent_signal;
+/**
+ * @defgroup tevent The tevent API
+ *
+ * The tevent low-level API
+ *
+ * @todo description
+ *
+ * @{
+ */
+
/* event handler types */
typedef void (*tevent_fd_handler_t)(struct tevent_context *ev,
struct tevent_fd *fde,
@@ -63,11 +73,86 @@ typedef void (*tevent_signal_handler_t)(struct tevent_context *ev,
void *siginfo,
void *private_data);
+/**
+ * @brief Create a event_context structure.
+ *
+ * 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
+ * their first argument.
+ *
+ * @param[in] mem_ctx The memory context to use.
+ *
+ * @return An allocated tevent context, NULL on error.
+ *
+ * @see tevent_context_init()
+ */
struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx);
+
+/**
+ * @brief Create a event_context structure and name it.
+ *
+ * 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
+ * their first argument.
+ *
+ * @param[in] mem_ctx The memory context to use.
+ *
+ * @param[in] name The name for the tevent context.
+ *
+ * @return An allocated tevent context, NULL on error.
+ */
struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
+
+/**
+ * @brief List available backends.
+ *
+ * @param[in] mem_ctx The memory context to use.
+ *
+ * @return A string vector with a terminating NULL element, NULL
+ * on error.
+ */
const char **tevent_backend_list(TALLOC_CTX *mem_ctx);
+
+/**
+ * @brief Set the default tevent backent.
+ *
+ * @param[in] backend The name of the backend to set.
+ */
void tevent_set_default_backend(const char *backend);
+#if DOXYGEN
+/**
+ * @brief Add a file descriptor based event.
+ *
+ * If flags contains TEVENT_FD_AUTOCLOSE then the fd will be closed when
+ * the returned fd_event context is freed.
+ *
+ * @param[in] ev The event context to work on.
+ *
+ * @param[in] mem_ctx The talloc memory context to use.
+ *
+ * @param[in] fd The file descriptor to base the event on.
+ *
+ * @param[in] flags
+ *
+ * @param[in] handler The callback handler for the event.
+ *
+ * @param[in] private_data The private data passed to the callback handler.
+ *
+ * @param[in] handler_name The name to identify the callback handler.
+ *
+ * @return The file descriptor based event, NULL on error.
+ *
+ * @todo Document flags
+ */
+struct tevent_fd *tevent_add_fd(struct tevent_context *ev,
+ TALLOC_CTX *mem_ctx,
+ int fd,
+ uint16_t flags,
+ tevent_fd_handler_t handler,
+ void *private_data,
+ const char *handler_name);
+#else
struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
TALLOC_CTX *mem_ctx,
int fd,
@@ -79,6 +164,7 @@ struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
#define tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \
_tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \
#handler, __location__)
+#endif
struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
TALLOC_CTX *mem_ctx,
@@ -150,7 +236,9 @@ void tevent_set_abort_fn(void (*abort_fn)(const char *reason));
#define TEVENT_FD_NOT_READABLE(fde) \
tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ)
-/* DEBUG */
+/**
+ * Debug level of tevent
+ */
enum tevent_debug_level {
TEVENT_DEBUG_FATAL,
TEVENT_DEBUG_ERROR,
@@ -167,6 +255,28 @@ int tevent_set_debug(struct tevent_context *ev,
int tevent_set_debug_stderr(struct tevent_context *ev);
/**
+ * @}
+ */
+
+/**
+ * @defgroup tevent_request The tevent request functions.
+ * @ingroup tevent
+ *
+ * This represents an async request being processed by callbacks via an event
+ * context. A user can issue for example a write request to a socket, giving
+ * an implementation function the fd, the buffer and the number of bytes to
+ * transfer. The function issuing the request will immediately return without
+ * blocking most likely without having sent anything. The API user then fills
+ * in req->async.fn and req->async.private_data, functions that are called
+ * when the request is finished.
+ *
+ * It is up to the user of the async request to talloc_free it after it has
+ * finished. This can happen while the completion function is called.
+ *
+ * @{
+ */
+
+/**
* An async request moves between the following 4 states:
*/
enum tevent_req_state {
@@ -202,50 +312,132 @@ enum tevent_req_state {
/**
* @brief An async request
- *
- * This represents an async request being processed by callbacks via an event
- * context. A user can issue for example a write request to a socket, giving
- * an implementation function the fd, the buffer and the number of bytes to
- * transfer. The function issuing the request will immediately return without
- * blocking most likely without having sent anything. The API user then fills
- * in req->async.fn and req->async.private_data, functions that are called
- * when the request is finished.
- *
- * It is up to the user of the async request to talloc_free it after it has
- * finished. This can happen while the completion function is called.
*/
-
struct tevent_req;
typedef void (*tevent_req_fn)(struct tevent_req *);
void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt);
-void *_tevent_req_callback_data(struct tevent_req *req);
-void *_tevent_req_data(struct tevent_req *req);
+void *_tevent_req_callback_data(struct tevent_req *req);
#define tevent_req_callback_data(_req, _type) \
talloc_get_type_abort(_tevent_req_callback_data(_req), _type)
+
#define tevent_req_callback_data_void(_req) \
_tevent_req_callback_data(_req)
+
+void *_tevent_req_data(struct tevent_req *req);
#define tevent_req_data(_req, _type) \
talloc_get_type_abort(_tevent_req_data(_req), _type)
typedef char *(*tevent_req_print_fn)(struct tevent_req *, TALLOC_CTX *);
+/**
+ * @brief This function sets a print function for the given request.
+ *
+ * This function can be used to setup a print function for the given request.
+ * This will be triggered if the tevent_req_print() function was
+ * called on the given request.
+ *
+ * @param[in] req The request to use.
+ *
+ * @param[in] fn A pointer to the print function
+ *
+ * @note This function should only be used for debugging.
+ */
void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn);
+/**
+ * @brief The default print function for creating debug messages.
+ *
+ * The function should not be used by users of the async API,
+ * but custom print function can use it and append custom text
+ * to the string.
+ *
+ * @param[in] req The request to be printed.
+ *
+ * @param[in] mem_ctx The memory context for the result.
+ *
+ * @return Text representation of request.
+ *
+ */
char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx);
+/**
+ * @brief Print an tevent_req structure in debug messages.
+ *
+ * This function should be used by callers of the async API.
+ *
+ * @param[in] mem_ctx The memory context for the result.
+ *
+ * @param[in] req The request to be printed.
+ *
+ * @return Text representation of request.
+ */
char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req);
typedef bool (*tevent_req_cancel_fn)(struct tevent_req *);
+/**
+ * @brief This function sets a cancel function for the given tevent request.
+ *
+ * This function can be used to setup a cancel function for the given request.
+ * This will be triggered if the tevent_req_cancel() function was
+ * called on the given request.
+ *
+ * @param[in] req The request to use.
+ *
+ * @param[in] fn A pointer to the cancel function.
+ */
void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn);
+#ifdef DOXYGEN
+/**
+ * @brief Try to cancel the given tevent request.
+ *
+ * This function can be used to cancel the given request.
+ *
+ * It is only possible to cancel a request when the implementation
+ * has registered a cancel function via the tevent_req_set_cancel_fn().
+ *
+ * @param[in] req The request to use.
+ *
+ * @return This function returns true is the request is cancelable,
+ * othererwise false is returned.
+ *
+ * @note Even if the function returns true, the caller need to wait
+ * for the function to complete normally.
+ * Only the _recv() function of the given request indicates
+ * if the request was really canceled.
+ */
+bool tevent_req_cancel(struct tevent_req *req);
+#else
bool _tevent_req_cancel(struct tevent_req *req, const char *location);
#define tevent_req_cancel(req) \
_tevent_req_cancel(req, __location__)
+#endif
+#if DOXYGEN
+/**
+ * @brief Create an async tevent request.
+ *
+ * The new async request will be initialized in state ASYNC_REQ_IN_PROGRESS.
+ *
+ * @param[in] mem_ctx The memory context for the result.
+ *
+ * @param[in] pstate The private state of the request.
+ *
+ * @param[in] state_size The size of the private state of the request.
+ *
+ * @param[in] type The name of the request.
+ *
+ * @return A new async request. NULL on error.
+ */
+struct tevent_req *tevent_req_create(TALLOC_CTX *mem_ctx,
+ void *pstate,
+ size_t state_size,
+ const char *type);
+#else
struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
void *pstate,
size_t state_size,
@@ -255,6 +447,7 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
#define tevent_req_create(_mem_ctx, _pstate, _type) \
_tevent_req_create((_mem_ctx), (_pstate), sizeof(_type), \
#_type, __location__)
+#endif
bool tevent_req_set_endtime(struct tevent_req *req,
struct tevent_context *ev,
@@ -264,28 +457,152 @@ void _tevent_req_notify_callback(struct tevent_req *req, const char *location);
#define tevent_req_notify_callback(req) \
_tevent_req_notify_callback(req, __location__)
+#ifdef DOXYGEN
+/**
+ * @brief An async request has successfully finished.
+ *
+ * This function is to be used by implementors of async requests. When a
+ * request is successfully finished, this function calls the user's completion
+ * function.
+ *
+ * @param[in] req The finished request.
+ */
+void tevent_req_done(struct tevent_req *req);
+#else
void _tevent_req_done(struct tevent_req *req,
const char *location);
#define tevent_req_done(req) \
_tevent_req_done(req, __location__)
+#endif
+#ifdef DOXYGEN
+/**
+ * @brief An async request has seen an error.
+ *
+ * This function is to be used by implementors of async requests. When a
+ * request can not successfully completed, the implementation should call this
+ * function with the appropriate status code.
+ *
+ * If error is 0 the function returns false and does nothing more.
+ *
+ * @param[in] req The request with an error.
+ *
+ * @param[in] error The error code.
+ *
+ * @return On success true is returned, false if error is 0.
+ *
+ * @code
+ * int error = first_function();
+ * if (tevent_req_error(req, error)) {
+ * return;
+ * }
+ *
+ * error = second_function();
+ * if (tevent_req_error(req, error)) {
+ * return;
+ * }
+ *
+ * tevent_req_done(req);
+ * return;
+ * @endcode
+ */
+bool tevent_req_error(struct tevent_req *req,
+ uint64_t error);
+#else
bool _tevent_req_error(struct tevent_req *req,
uint64_t error,
const char *location);
#define tevent_req_error(req, error) \
_tevent_req_error(req, error, __location__)
+#endif
+#ifdef DOXYGEN
+/**
+ * @brief Helper function for nomem check.
+ *
+ * Convenience helper to easily check alloc failure within a callback
+ * implementing the next step of an async request.
+ *
+ * @param[in] p The pointer to be checked.
+ *
+ * @param[in] req The request being processed.
+ *
+ * @code
+ * p = talloc(mem_ctx, bla);
+ * if (tevent_req_nomem(p, req)) {
+ * return;
+ * }
+ * @endcode
+ */
+bool tevent_req_nomem(const void *p,
+ struct tevent_req *req);
+#else
bool _tevent_req_nomem(const void *p,
struct tevent_req *req,
const char *location);
#define tevent_req_nomem(p, req) \
_tevent_req_nomem(p, req, __location__)
+#endif
+/**
+ * @brief Finish a request before the caller had the change to set the callback.
+ *
+ * An implementation of an async request might find that it can either finish
+ * the request without waiting for an external event, or it can't even start
+ * the engine. To present the illusion of a callback to the user of the API,
+ * the implementation can call this helper function which triggers an
+ * immediate timed event. This way the caller can use the same calling
+ * conventions, independent of whether the request was actually deferred.
+ *
+ * @param[in] req The finished request.
+ *
+ * @param[in] ev The tevent_context for the timed event.
+ *
+ * @return The given request will be returned.
+ */
struct tevent_req *tevent_req_post(struct tevent_req *req,
struct tevent_context *ev);
+/**
+ * @brief Check if the given request is still in progress.
+ *
+ * It is typically used by sync wrapper functions.
+ *
+ * This function destroys the attached private data.
+ *
+ * @param[in] req The request to poll.
+ *
+ * @return The boolean form of "is in progress".
+ */
bool tevent_req_is_in_progress(struct tevent_req *req);
+/**
+ * @brief Actively poll for the given request to finish.
+ *
+ * This function is typically used by sync wrapper functions.
+ *
+ * @param[in] req The request to poll.
+ *
+ * @param[in] ev The tevent_context to be used.
+ *
+ * @return On success true is returned. If a critical error has
+ * happened in the tevent loop layer false is returned.
+ * This is not the return value of the given request!
+ *
+ * @note This should only be used if the given tevent context was created by the
+ * caller, to avoid event loop nesting.
+ *
+ * @code
+ * req = tstream_writev_queue_send(mem_ctx,
+ * ev_ctx,
+ * tstream,
+ * send_queue,
+ * iov, 2);
+ * ok = tevent_req_poll(req, tctx->ev);
+ * rc = tstream_writev_queue_recv(req, &sys_errno);
+ * TALLOC_FREE(req);
+ * @endcode
+ */
bool tevent_req_poll(struct tevent_req *req,
struct tevent_context *ev);
@@ -293,6 +610,13 @@ bool tevent_req_is_error(struct tevent_req *req,
enum tevent_req_state *state,
uint64_t *error);
+/**
+ * @brief Use as the last action of a _recv() function.
+ *
+ * This function destroys the attached private data.
+ *
+ * @param[in] req The finished request.
+ */
void tevent_req_received(struct tevent_req *req);
struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx,
@@ -300,6 +624,17 @@ struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx,
struct timeval wakeup_time);
bool tevent_wakeup_recv(struct tevent_req *req);
+/* @} */
+
+/**
+ * @defgroup tevent_helpers The tevent helper functiions
+ * @ingroup tevent
+ *
+ * @todo description
+ *
+ * @{
+ */
+
int tevent_timeval_compare(const struct timeval *tv1,
const struct timeval *tv2);
@@ -319,6 +654,16 @@ struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs,
struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs);
+/* @} */
+
+
+/**
+ * @defgroup tevent_queue The tevent queue functions
+ * @ingroup tevent
+ *
+ * @{
+ */
+
struct tevent_queue;
struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx,
@@ -368,11 +713,16 @@ int _tevent_loop_until(struct tevent_context *ev,
int tevent_re_initialise(struct tevent_context *ev);
+/* @} */
/**
+ * @defgroup tevent_ops The tevent operation functions
+ * @ingroup tevent
+ *
* The following structure and registration functions are exclusively
* needed for people writing and pluggin a different event engine.
* There is nothing useful for normal tevent user in here.
+ * @{
*/
struct tevent_ops {
@@ -425,11 +775,19 @@ struct tevent_ops {
bool tevent_register_backend(const char *name, const struct tevent_ops *ops);
+/* @} */
/**
+ * @defgroup tevent_compat The tevent compatibility functions
+ * @ingroup tevent
+ *
* The following definitions are usueful only for compatibility with the
* implementation originally developed within the samba4 code and will be
* soon removed. Please NEVER use in new code.
+ *
+ * @todo Ignore it?
+ *
+ * @{
*/
#ifdef TEVENT_COMPAT_DEFINES
@@ -506,4 +864,6 @@ bool tevent_register_backend(const char *name, const struct tevent_ops *ops);
#endif /* TEVENT_COMPAT_DEFINES */
+/* @} */
+
#endif /* __TEVENT_H__ */