diff options
author | Amitay Isaacs <amitay@gmail.com> | 2017-11-17 12:38:47 +1100 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2017-11-21 08:58:45 +0100 |
commit | c1b4a74f272977ebdc735c040e976853c7ca800f (patch) | |
tree | 0bdeaa23d69829600a90cd1517d1c6764a034373 /ctdb/common/sock_daemon.c | |
parent | 41d888afbecfca6e4ea3c6c86c05101bd5e5b5c4 (diff) | |
download | samba-c1b4a74f272977ebdc735c040e976853c7ca800f.tar.gz |
ctdb-common: Add async version of shutdown in sock_daemon
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
Autobuild-User(master): Martin Schwenke <martins@samba.org>
Autobuild-Date(master): Tue Nov 21 08:58:45 CET 2017 on sn-devel-144
Diffstat (limited to 'ctdb/common/sock_daemon.c')
-rw-r--r-- | ctdb/common/sock_daemon.c | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c index ce6f9230a6d..7554cd6da07 100644 --- a/ctdb/common/sock_daemon.c +++ b/ctdb/common/sock_daemon.c @@ -524,6 +524,7 @@ struct sock_daemon_run_state { pid_t pid_watch; int fd; + int exit_code; }; static void sock_daemon_run_started(struct tevent_req *subreq); @@ -535,6 +536,8 @@ static void sock_daemon_run_signal_handler(struct tevent_context *ev, static void sock_daemon_run_reconfigure(struct tevent_req *req); static void sock_daemon_run_reconfigure_done(struct tevent_req *subreq); static void sock_daemon_run_shutdown(struct tevent_req *req); +static void sock_daemon_run_shutdown_done(struct tevent_req *subreq); +static void sock_daemon_run_exit(struct tevent_req *req); static bool sock_daemon_run_socket_listen(struct tevent_req *req); static void sock_daemon_run_socket_fail(struct tevent_req *subreq); static void sock_daemon_run_watch_pid(struct tevent_req *subreq); @@ -702,6 +705,8 @@ static void sock_daemon_run_signal_handler(struct tevent_context *ev, { struct tevent_req *req = talloc_get_type_abort( private_data, struct tevent_req); + struct sock_daemon_run_state *state = tevent_req_data( + req, struct sock_daemon_run_state); D_NOTICE("Received signal %d\n", signum); @@ -711,8 +716,8 @@ static void sock_daemon_run_signal_handler(struct tevent_context *ev, } if (signum == SIGINT || signum == SIGTERM) { + state->exit_code = EINTR; sock_daemon_run_shutdown(req); - tevent_req_error(req, EINTR); } } @@ -770,6 +775,7 @@ static void sock_daemon_run_reconfigure_done(struct tevent_req *subreq) static void sock_daemon_run_shutdown(struct tevent_req *req) { + struct tevent_req *subreq; struct sock_daemon_run_state *state = tevent_req_data( req, struct sock_daemon_run_state); struct sock_daemon_context *sockd = state->sockd; @@ -782,11 +788,53 @@ static void sock_daemon_run_shutdown(struct tevent_req *req) TALLOC_FREE(sock); } + if (sockd->funcs != NULL && sockd->funcs->shutdown_send != NULL && + sockd->funcs->shutdown_recv != NULL) { + subreq = sockd->funcs->shutdown_send(state, state->ev, + sockd->private_data); + if (subreq == NULL) { + sock_daemon_run_exit(req); + return; + } + tevent_req_set_callback(subreq, sock_daemon_run_shutdown_done, + req); + return; + } + if (sockd->funcs != NULL && sockd->funcs->shutdown != NULL) { sockd->funcs->shutdown(sockd->private_data); } + sock_daemon_run_exit(req); +} + +static void sock_daemon_run_shutdown_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct sock_daemon_run_state *state = tevent_req_data( + req, struct sock_daemon_run_state); + struct sock_daemon_context *sockd = state->sockd; + + sockd->funcs->shutdown_recv(subreq); + TALLOC_FREE(subreq); + + sock_daemon_run_exit(req); +} + +static void sock_daemon_run_exit(struct tevent_req *req) +{ + struct sock_daemon_run_state *state = tevent_req_data( + req, struct sock_daemon_run_state); + struct sock_daemon_context *sockd = state->sockd; + TALLOC_FREE(sockd->pid_ctx); + + if (state->exit_code == 0) { + tevent_req_done(req); + } else { + tevent_req_error(req, state->exit_code); + } } static bool sock_daemon_run_socket_listen(struct tevent_req *req) @@ -826,13 +874,14 @@ static void sock_daemon_run_socket_fail(struct tevent_req *subreq) status = sock_socket_start_recv(subreq, &ret, state, &sockpath); TALLOC_FREE(subreq); - sock_daemon_run_shutdown(req); if (! status) { D_ERR("socket %s closed unexpectedly\n", sockpath); - tevent_req_error(req, ret); + state->exit_code = ret; } else { - tevent_req_done(req); + state->exit_code = 0; } + + sock_daemon_run_shutdown(req); } static void sock_daemon_run_watch_pid(struct tevent_req *subreq) @@ -855,8 +904,8 @@ static void sock_daemon_run_watch_pid(struct tevent_req *subreq) if (ret == -1) { if (errno == ESRCH) { D_ERR("PID %d gone away, exiting\n", state->pid_watch); + state->exit_code = ESRCH; sock_daemon_run_shutdown(req); - tevent_req_error(req, ESRCH); return; } else { D_ERR("Failed to check PID status %d, ret=%d\n", @@ -898,17 +947,18 @@ static void sock_daemon_run_wait_done(struct tevent_req *subreq) struct sock_daemon_run_state *state = tevent_req_data( req, struct sock_daemon_run_state); struct sock_daemon_context *sockd = state->sockd; - int ret; + int ret = 0; bool status; status = sockd->funcs->wait_recv(subreq, &ret); TALLOC_FREE(subreq); - sock_daemon_run_shutdown(req); if (! status) { - tevent_req_error(req, ret); + state->exit_code = ret; } else { - tevent_req_done(req); + state->exit_code = 0; } + + sock_daemon_run_shutdown(req); } bool sock_daemon_run_recv(struct tevent_req *req, int *perr) |