Skip to content

Commit

Permalink
ctdb-client: Do not use sync functions in async computation
Browse files Browse the repository at this point in the history
This leads to nested event loops.

Signed-off-by: Amitay Isaacs <[email protected]>
Reviewed-by: Martin Schwenke <[email protected]>
  • Loading branch information
amitay authored and Martin Schwenke committed Feb 24, 2016
1 parent b4239ca commit e8d4b5d
Showing 1 changed file with 39 additions and 24 deletions.
63 changes: 39 additions & 24 deletions ctdb/client/client_connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit e8d4b5d

Please sign in to comment.