diff options
author | Stefan Metzmacher <metze@samba.org> | 2009-08-15 09:46:23 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2009-08-17 09:25:44 +0200 |
commit | 45e4be0d96abdc729252df1e97bb9a56302e5a4a (patch) | |
tree | a9bcfc8d68dee0b58d6534029c9012733b588484 | |
parent | 26e114b83ce1de7515bfbf365da03ec3f18c95fd (diff) | |
download | samba-45e4be0d96abdc729252df1e97bb9a56302e5a4a.tar.gz samba-45e4be0d96abdc729252df1e97bb9a56302e5a4a.tar.bz2 samba-45e4be0d96abdc729252df1e97bb9a56302e5a4a.zip |
tevent: add tevent_req_cancel() infrastructure
This offers a generic way for callers to cancel an
async request.
metze
-rw-r--r-- | lib/tevent/tevent.h | 8 | ||||
-rw-r--r-- | lib/tevent/tevent_internal.h | 19 | ||||
-rw-r--r-- | lib/tevent/tevent_req.c | 43 |
3 files changed, 70 insertions, 0 deletions
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 56ae0ee082..d3556053ac 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 e260524208..513ca1c732 100644 --- a/lib/tevent/tevent_internal.h +++ b/lib/tevent/tevent_internal.h @@ -65,6 +65,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 * * Callers should only access this via functions and never directly. @@ -100,6 +109,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 * * While the async request is being processed, state will remain in diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index c6b11601dc..345a2fdcd1 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); +} |