From 831072292212fb4e63ab6ebf51ccefd1547b98d0 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Thu, 21 Apr 2016 17:47:43 +1000 Subject: [PATCH] ctdb-client: Add async version of transaction cancel Transaction cancel should get rid of g_lock lock. Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke --- ctdb/client/client.h | 8 +++++ ctdb/client/client_db.c | 73 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/ctdb/client/client.h b/ctdb/client/client.h index f5b8601aa2c..693763903fb 100644 --- a/ctdb/client/client.h +++ b/ctdb/client/client.h @@ -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 */ diff --git a/ctdb/client/client_db.c b/ctdb/client/client_db.c index c353ece1ec7..c1c77124abc 100644 --- a/ctdb/client/client_db.c +++ b/ctdb/client/client_db.c @@ -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);