pthreadpool: add pthreadpool_tevent_job_cancel()
authorStefan Metzmacher <metze@samba.org>
Wed, 25 Apr 2018 12:43:22 +0000 (14:43 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 12 Jul 2018 12:25:19 +0000 (14:25 +0200)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
lib/pthreadpool/pthreadpool_tevent.c

index 7c8015d2f5943b7896698514650b30701adb8a8d..bfd178c09a6795b2f0d9ca11ca15e8032cf425aa 100644 (file)
@@ -267,6 +267,7 @@ static void pthreadpool_tevent_job_fn(void *private_data);
 static void pthreadpool_tevent_job_done(struct tevent_context *ctx,
                                        struct tevent_immediate *im,
                                        void *private_data);
+static bool pthreadpool_tevent_job_cancel(struct tevent_req *req);
 
 static int pthreadpool_tevent_job_destructor(struct pthreadpool_tevent_job *job)
 {
@@ -441,6 +442,7 @@ struct tevent_req *pthreadpool_tevent_job_send(
                return tevent_req_post(req, ev);
        }
 
+       tevent_req_set_cancel_fn(req, pthreadpool_tevent_job_cancel);
        return req;
 }
 
@@ -522,6 +524,44 @@ static void pthreadpool_tevent_job_done(struct tevent_context *ctx,
        tevent_req_done(state->req);
 }
 
+static bool pthreadpool_tevent_job_cancel(struct tevent_req *req)
+{
+       struct pthreadpool_tevent_job_state *state =
+               tevent_req_data(req,
+               struct pthreadpool_tevent_job_state);
+       struct pthreadpool_tevent_job *job = state->job;
+       size_t num;
+
+       if (job == NULL) {
+               return false;
+       }
+
+       num = pthreadpool_cancel_job(job->pool->pool, 0,
+                                    pthreadpool_tevent_job_fn,
+                                    job);
+       if (num == 0) {
+               /*
+                * It was too late to cancel the request.
+                */
+               return false;
+       }
+
+       /*
+        * It was not too late to cancel the request.
+        *
+        * We can remove job->im, as it will never be used.
+        */
+       TALLOC_FREE(job->im);
+
+       /*
+        * pthreadpool_tevent_job_cleanup()
+        * will destroy the job.
+        */
+       tevent_req_defer_callback(req, state->ev);
+       tevent_req_error(req, ECANCELED);
+       return true;
+}
+
 int pthreadpool_tevent_job_recv(struct tevent_req *req)
 {
        return tevent_req_simple_recv_unix(req);