diff options
author | Amitay Isaacs <amitay@gmail.com> | 2017-01-11 20:37:00 +1100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2017-01-16 21:16:51 +0100 |
commit | ed722c3aa9690873af495cb467dd440c1a714d82 (patch) | |
tree | 802765d15755698a1169dcc4c33c77669065c538 /ctdb/common | |
parent | d09469e575233242eab2a8c1c0767f52e7cad1e5 (diff) | |
download | samba-ed722c3aa9690873af495cb467dd440c1a714d82.tar.gz |
ctdb-common: Add wait_send/wait_recv to sock_daemon_funcs
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12510
To be able to terminate the daemon from within the implementation,
create a subreq using wait_send() provided by the implementation.
When the subreq is finished, it signals the sock_daemon code to terminate
the daemon.
This avoids the need to keep track of the top level tevent_req causing
layer violation and keeps the code flow straighforward.
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Mon Jan 16 21:16:51 CET 2017 on sn-devel-144
Diffstat (limited to 'ctdb/common')
-rw-r--r-- | ctdb/common/sock_daemon.c | 47 | ||||
-rw-r--r-- | ctdb/common/sock_daemon.h | 14 |
2 files changed, 44 insertions, 17 deletions
diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c index 3b679ab1332..b53b4d85333 100644 --- a/ctdb/common/sock_daemon.c +++ b/ctdb/common/sock_daemon.c @@ -70,7 +70,6 @@ struct sock_daemon_context { struct pidfile_context *pid_ctx; struct sock_socket *socket_list; - struct tevent_req *req; }; /* @@ -451,8 +450,6 @@ bool sock_socket_write_recv(struct tevent_req *req, int *perr) * Socket daemon */ -static int sock_daemon_context_destructor(struct sock_daemon_context *sockd); - int sock_daemon_setup(TALLOC_CTX *mem_ctx, const char *daemon_name, const char *logging, const char *debug_level, const char *pidfile, @@ -487,21 +484,10 @@ int sock_daemon_setup(TALLOC_CTX *mem_ctx, const char *daemon_name, } } - talloc_set_destructor(sockd, sock_daemon_context_destructor); - *out = sockd; return 0; } -static int sock_daemon_context_destructor(struct sock_daemon_context *sockd) -{ - if (sockd->req != NULL) { - tevent_req_done(sockd->req); - } - - return 0; -} - int sock_daemon_add_unix(struct sock_daemon_context *sockd, const char *sockpath, struct sock_socket_funcs *funcs, @@ -546,6 +532,7 @@ static void sock_daemon_run_reconfigure(struct tevent_req *req); static void sock_daemon_run_shutdown(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); +static void sock_daemon_run_wait_done(struct tevent_req *subreq); struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -620,7 +607,16 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, req); } - sockd->req = req; + if (sockd->funcs != NULL && sockd->funcs->wait_send != NULL && + sockd->funcs->wait_recv != NULL) { + subreq = sockd->funcs->wait_send(state, ev, + sockd->private_data); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, sock_daemon_run_wait_done, + req); + } return req; } @@ -748,6 +744,26 @@ static void sock_daemon_run_watch_pid(struct tevent_req *subreq) tevent_req_set_callback(subreq, sock_daemon_run_watch_pid, req); } +static void sock_daemon_run_wait_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; + int ret; + bool status; + + status = sockd->funcs->wait_recv(subreq, &ret); + TALLOC_FREE(subreq); + sock_daemon_run_shutdown(req); + if (! status) { + tevent_req_error(req, ret); + } else { + tevent_req_done(req); + } +} + bool sock_daemon_run_recv(struct tevent_req *req, int *perr) { int ret; @@ -778,7 +794,6 @@ int sock_daemon_run(struct tevent_context *ev, tevent_req_poll(req, ev); status = sock_daemon_run_recv(req, &ret); - sockd->req = NULL; TALLOC_FREE(req); if (! status) { return ret; diff --git a/ctdb/common/sock_daemon.h b/ctdb/common/sock_daemon.h index 6c474acd021..81853f66446 100644 --- a/ctdb/common/sock_daemon.h +++ b/ctdb/common/sock_daemon.h @@ -50,12 +50,24 @@ struct sock_client_context; * startup() is called when the daemon starts running * either via sock_daemon_run() or via sock_daemon_run_send() * reconfigure() is called when process receives SIGUSR1 or SIGHUP - * shutdown() is called when process receives SIGINT or SIGTERM + * shutdown() is called when process receives SIGINT or SIGTERM or + * when wait computation has finished + * + * wait_send() starts the async computation to keep running the daemon + * wait_recv() ends the async computation to keep running the daemon + * + * If wait_send()/wait_recv() is NULL, then daemon will keep running forever. + * If wait_send() returns req, then when req is over, daemon will shutdown. */ struct sock_daemon_funcs { void (*startup)(void *private_data); void (*reconfigure)(void *private_data); void (*shutdown)(void *private_data); + + struct tevent_req * (*wait_send)(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + void *private_data); + bool (*wait_recv)(struct tevent_req *req, int *perr); }; /** |