ctdb-client: Add async version of transaction cancel
authorAmitay Isaacs <amitay@gmail.com>
Thu, 21 Apr 2016 07:47:43 +0000 (17:47 +1000)
committerMartin Schwenke <martins@samba.org>
Tue, 5 Jul 2016 08:53:15 +0000 (10:53 +0200)
Transaction cancel should get rid of g_lock lock.

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/client/client.h
ctdb/client/client_db.c

index f5b8601..6937639 100644 (file)
@@ -835,6 +835,14 @@ bool ctdb_transaction_commit_recv(struct tevent_req *req, int *perr);
 
 int ctdb_transaction_commit(struct ctdb_transaction_handle *h);
 
+struct tevent_req *ctdb_transaction_cancel_send(
+                                       TALLOC_CTX *mem_ctx,
+                                       struct tevent_context *ev,
+                                       struct timeval timeout,
+                                       struct ctdb_transaction_handle *h);
+
+bool ctdb_transaction_cancel_recv(struct tevent_req *req, int *perr);
+
 int ctdb_transaction_cancel(struct ctdb_transaction_handle *h);
 
 /* from client/client_util.c */
index c353ece..c1c7712 100644 (file)
@@ -2159,6 +2159,79 @@ int ctdb_transaction_commit(struct ctdb_transaction_handle *h)
        return 0;
 }
 
+struct ctdb_transaction_cancel_state {
+       struct tevent_context *ev;
+       struct ctdb_transaction_handle *h;
+       struct timeval timeout;
+};
+
+static void ctdb_transaction_cancel_done(struct tevent_req *subreq);
+
+struct tevent_req *ctdb_transaction_cancel_send(
+                                       TALLOC_CTX *mem_ctx,
+                                       struct tevent_context *ev,
+                                       struct timeval timeout,
+                                       struct ctdb_transaction_handle *h)
+{
+       struct tevent_req *req, *subreq;
+       struct ctdb_transaction_cancel_state *state;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct ctdb_transaction_cancel_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       state->ev = ev;
+       state->h = h;
+       state->timeout = timeout;
+
+       subreq = ctdb_g_lock_unlock_send(state, state->ev, state->h->client,
+                                        state->h->db_g_lock,
+                                        state->h->lock_name, state->h->sid);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, ctdb_transaction_cancel_done,
+                               req);
+
+       return req;
+}
+
+static void ctdb_transaction_cancel_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct ctdb_transaction_cancel_state *state = tevent_req_data(
+               req, struct ctdb_transaction_cancel_state);
+       int ret;
+       bool status;
+
+       status = ctdb_g_lock_unlock_recv(subreq, &ret);
+       TALLOC_FREE(subreq);
+       if (! status) {
+               tevent_req_error(req, ret);
+               return;
+       }
+
+       talloc_free(state->h);
+       tevent_req_done(req);
+}
+
+bool ctdb_transaction_cancel_recv(struct tevent_req *req, int *perr)
+{
+       int err;
+
+       if (tevent_req_is_unix_error(req, &err)) {
+               if (perr != NULL) {
+                       *perr = err;
+               }
+               return false;
+       }
+
+       return true;
+}
+
 int ctdb_transaction_cancel(struct ctdb_transaction_handle *h)
 {
        talloc_free(h);