diff --git a/ctdb/client/client.h b/ctdb/client/client.h index 88ee5768d76..5f174035e28 100644 --- a/ctdb/client/client.h +++ b/ctdb/client/client.h @@ -170,6 +170,28 @@ uint32_t ctdb_client_pnn(struct ctdb_client_context *client); */ void ctdb_client_wait(struct tevent_context *ev, bool *done); +/** + * @brief Client event loop waiting for function to return true with timeout + * + * This can be used to wait for asynchronous computations to complete. + * When this function is called, it will run tevent event loop and wait + * till the done function returns true or if the timeout occurs. + * + * This function will return when either + * - done function returns true, or + * - timeout has occurred. + * + * @param[in] ev Tevent context + * @param[in] done_func Function flag to indicate when to stop waiting + * @param[in] private_data Passed to done function + * @param[in] timeout How long to wait + * @return 0 on success, ETIMEDOUT on timeout, and errno on failure + */ +int ctdb_client_wait_func_timeout(struct tevent_context *ev, + bool (*done_func)(void *private_data), + void *private_data, + struct timeval timeout); + /** * @brief Client event loop waiting for a flag with timeout * diff --git a/ctdb/client/client_connect.c b/ctdb/client/client_connect.c index 0977d717608..a942871b1d2 100644 --- a/ctdb/client/client_connect.c +++ b/ctdb/client/client_connect.c @@ -336,8 +336,10 @@ static void ctdb_client_wait_timeout_handler(struct tevent_context *ev, *timed_out = true; } -int ctdb_client_wait_timeout(struct tevent_context *ev, bool *done, - struct timeval timeout) +int ctdb_client_wait_func_timeout(struct tevent_context *ev, + bool (*done_func)(void *private_data), + void *private_data, + struct timeval timeout) { TALLOC_CTX *mem_ctx; struct tevent_timer *timer; @@ -356,7 +358,7 @@ int ctdb_client_wait_timeout(struct tevent_context *ev, bool *done, return ENOMEM; } - while (! (*done) && ! timed_out) { + while (! (done_func(private_data)) && ! timed_out) { tevent_loop_once(ev); } @@ -369,6 +371,28 @@ int ctdb_client_wait_timeout(struct tevent_context *ev, bool *done, return 0; } +static bool client_wait_done(void *private_data) +{ + bool *done = (bool *)private_data; + + return *done; +} + +int ctdb_client_wait_timeout(struct tevent_context *ev, + bool *done, + struct timeval timeout) + +{ + int ret; + + ret = ctdb_client_wait_func_timeout(ev, + client_wait_done, + done, + timeout); + + return ret; +} + struct ctdb_recovery_wait_state { struct tevent_context *ev; struct ctdb_client_context *client;