summaryrefslogtreecommitdiff
path: root/ctdb/common
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2017-01-11 20:37:00 +1100
committerStefan Metzmacher <metze@samba.org>2017-01-16 21:16:51 +0100
commited722c3aa9690873af495cb467dd440c1a714d82 (patch)
tree802765d15755698a1169dcc4c33c77669065c538 /ctdb/common
parentd09469e575233242eab2a8c1c0767f52e7cad1e5 (diff)
downloadsamba-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.c47
-rw-r--r--ctdb/common/sock_daemon.h14
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);
};
/**