tevent: add tevent_req_cancel() infrastructure
authorStefan Metzmacher <metze@samba.org>
Sat, 15 Aug 2009 07:46:23 +0000 (09:46 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 17 Aug 2009 07:25:44 +0000 (09:25 +0200)
This offers a generic way for callers to cancel an
async request.

metze

lib/tevent/tevent.h
lib/tevent/tevent_internal.h
lib/tevent/tevent_req.c

index 56ae0ee0820e4f2fc86bf0777fa11f04c0aa5e52..d3556053acc22f65477a1d6b702606b79ba13813 100644 (file)
@@ -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,
index e260524208796c7ba5dd3a5595e8dfb0edd6aee6..513ca1c7325b769d2fc0abb325a595c18bfbdf70 100644 (file)
@@ -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
                 *
index c6b11601dc28dfbf410e81d3460932655899059f..345a2fdcd1aa75a4e48f60be5b0e7c097a7ab4f0 100644 (file)
@@ -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);
+}