ctdb-client: Do not use sync functions in async computation
authorAmitay Isaacs <amitay@gmail.com>
Fri, 6 Nov 2015 04:44:27 +0000 (15:44 +1100)
committerMartin Schwenke <martins@samba.org>
Wed, 24 Feb 2016 07:44:37 +0000 (08:44 +0100)
This leads to nested event loops.

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

index d433f7ddc3fddd5cbb2012480e645a7a6fd49d52..0e144c68caa03f22232d6c7ac830486564a9b1f5 100644 (file)
@@ -244,6 +244,7 @@ struct ctdb_recovery_wait_state {
        struct ctdb_client_context *client;
 };
 
+static void ctdb_recovery_wait_recmode(struct tevent_req *subreq);
 static void ctdb_recovery_wait_retry(struct tevent_req *subreq);
 
 struct tevent_req *ctdb_recovery_wait_send(TALLOC_CTX *mem_ctx,
@@ -252,8 +253,7 @@ struct tevent_req *ctdb_recovery_wait_send(TALLOC_CTX *mem_ctx,
 {
        struct tevent_req *req, *subreq;
        struct ctdb_recovery_wait_state *state;
-       int recmode;
-       int ret;
+       struct ctdb_req_control request;
 
        req = tevent_req_create(mem_ctx, &state,
                                struct ctdb_recovery_wait_state);
@@ -264,47 +264,36 @@ struct tevent_req *ctdb_recovery_wait_send(TALLOC_CTX *mem_ctx,
        state->ev = ev;
        state->client = client;
 
-       ret = ctdb_ctrl_get_recmode(client, ev, client, client->pnn,
-                                   tevent_timeval_zero(), &recmode);
-       if (ret != 0) {
-               tevent_req_error(req, ret);
-               return tevent_req_post(req, ev);
-       }
-
-       if (recmode == CTDB_RECOVERY_NORMAL) {
-               tevent_req_done(req);
-               return tevent_req_post(req, ev);
-       }
-
-       subreq = tevent_wakeup_send(state, ev,
-                                   tevent_timeval_current_ofs(1, 0));
+       ctdb_req_control_get_recmode(&request);
+       subreq = ctdb_client_control_send(state, ev, client, client->pnn,
+                                         tevent_timeval_zero(), &request);
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       tevent_req_set_callback(subreq, ctdb_recovery_wait_retry, req);
+       tevent_req_set_callback(subreq, ctdb_recovery_wait_recmode, req);
 
        return req;
 }
 
-static void ctdb_recovery_wait_retry(struct tevent_req *subreq)
+static void ctdb_recovery_wait_recmode(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(
                subreq, struct tevent_req);
        struct ctdb_recovery_wait_state *state = tevent_req_data(
                req, struct ctdb_recovery_wait_state);
-       int ret, recmode;
+       struct ctdb_reply_control *reply;
+       int recmode;
+       int ret;
        bool status;
 
-       status = tevent_wakeup_recv(subreq);
+       status = ctdb_client_control_recv(subreq, &ret, state, &reply);
        TALLOC_FREE(subreq);
        if (! status) {
-               tevent_req_error(req, ENOMEM);
+               tevent_req_error(req, ret);
                return;
        }
 
-       ret = ctdb_ctrl_get_recmode(state, state->ev, state->client,
-                                   ctdb_client_pnn(state->client),
-                                   tevent_timeval_zero(), &recmode);
+       ret = ctdb_reply_control_get_recmode(reply, &recmode);
        if (ret != 0) {
                tevent_req_error(req, ret);
                return;
@@ -323,6 +312,32 @@ static void ctdb_recovery_wait_retry(struct tevent_req *subreq)
        tevent_req_set_callback(subreq, ctdb_recovery_wait_retry, req);
 }
 
+static void ctdb_recovery_wait_retry(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct ctdb_recovery_wait_state *state = tevent_req_data(
+               req, struct ctdb_recovery_wait_state);
+       struct ctdb_req_control request;
+       bool status;
+
+       status = tevent_wakeup_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (! status) {
+               tevent_req_error(req, ENOMEM);
+               return;
+       }
+
+       ctdb_req_control_get_recmode(&request);
+       subreq = ctdb_client_control_send(state, state->ev, state->client,
+                                         state->client->pnn,
+                                         tevent_timeval_zero(), &request);
+       if (tevent_req_nomem(subreq, req)) {
+               return;
+       }
+       tevent_req_set_callback(subreq, ctdb_recovery_wait_recmode, req);
+}
+
 bool ctdb_recovery_wait_recv(struct tevent_req *req, int *perr)
 {
        int err;