From: Stefan Metzmacher Date: Sat, 15 Aug 2009 07:46:23 +0000 (+0200) Subject: tevent: add tevent_req_cancel() infrastructure X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=commitdiff_plain;h=45e4be0d96abdc729252df1e97bb9a56302e5a4a tevent: add tevent_req_cancel() infrastructure This offers a generic way for callers to cancel an async request. metze --- diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 56ae0ee0820e..d3556053acc2 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -238,6 +238,14 @@ char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx); char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req); +typedef bool (*tevent_req_cancel_fn)(struct tevent_req *); + +void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn); + +bool _tevent_req_cancel(struct tevent_req *req, const char *location); +#define tevent_req_cancel(req) \ + _tevent_req_cancel(req, __location__) + struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, void *pstate, size_t state_size, diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h index e26052420879..513ca1c7325b 100644 --- a/lib/tevent/tevent_internal.h +++ b/lib/tevent/tevent_internal.h @@ -64,6 +64,15 @@ struct tevent_req { */ tevent_req_print_fn private_print; + /** + * @brief A function to cancel the request + * + * The implementation might want to set a function + * that is called when the tevent_req_cancel() function + * was called. + */ + tevent_req_cancel_fn private_cancel; + /** * @brief Internal state of the request * @@ -99,6 +108,16 @@ struct tevent_req { */ const char *finish_location; + /** + * @brief The location where the request was canceled + * + * This uses the __location__ macro via the + * tevent_req_cancel() macro. + * + * This for debugging only. + */ + const char *cancel_location; + /** * @brief The external state - will be queried by the caller * diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index c6b11601dc28..345a2fdcd1aa 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -398,3 +398,46 @@ void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn) { req->private_print = fn; } + +/** + * @brief This function sets a cancel function for the given request + * @param[in] req The given request + * @param[in] fn A pointer to the cancel function + * + * 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. + * + */ +void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn) +{ + req->private_cancel = fn; +} + +/** + * @brief This function tries to cancel the given request + * @param[in] req The given request + * @param[in] location Automaticly filled with the __location__ macro + * via the tevent_req_cancel() macro. This is for debugging + * only! + * @retval This function returns true is the request is cancelable. + * Otherwise false is returned. + * + * 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(). + * + * 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, const char *location) +{ + if (req->private_cancel == NULL) { + return false; + } + + return req->private_cancel(req); +}