From 648f995b4463d92808982b0c78a87c0a4999a6b8 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 11 Jan 2017 19:50:34 +1100 Subject: [PATCH 1/5] ctdb-common: Correct name of sock_daemon_run_send/recv state structure BUG: https://bugzilla.samba.org/show_bug.cgi?id=12510 Signed-off-by: Amitay Isaacs Reviewed-by: Stefan Metzmacher (cherry picked from commit 9e09a253b4ca1b5f9aa432c986c1755a173a9566) --- ctdb/common/sock_daemon.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c index ca4086d..87935fd 100644 --- a/ctdb/common/sock_daemon.c +++ b/ctdb/common/sock_daemon.c @@ -529,7 +529,7 @@ int sock_daemon_add_unix(struct sock_daemon_context *sockd, * Run socket daemon */ -struct sock_daemon_start_state { +struct sock_daemon_run_state { struct tevent_context *ev; struct sock_daemon_context *sockd; pid_t pid_watch; @@ -542,10 +542,10 @@ static void sock_daemon_signal_handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data); +static void sock_daemon_reconfigure(struct sock_daemon_run_state *state); +static void sock_daemon_shutdown(struct sock_daemon_run_state *state); static void sock_daemon_socket_fail(struct tevent_req *subreq); static void sock_daemon_watch_pid(struct tevent_req *subreq); -static void sock_daemon_reconfigure(struct sock_daemon_start_state *state); -static void sock_daemon_shutdown(struct sock_daemon_start_state *state); struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -553,12 +553,12 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, pid_t pid_watch) { struct tevent_req *req, *subreq; - struct sock_daemon_start_state *state; + struct sock_daemon_run_state *state; struct tevent_signal *se; struct sock_socket *sock; req = tevent_req_create(mem_ctx, &state, - struct sock_daemon_start_state); + struct sock_daemon_run_state); if (req == NULL) { return NULL; } @@ -627,8 +627,8 @@ static void sock_daemon_started(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); - struct sock_daemon_start_state *state = tevent_req_data( - req, struct sock_daemon_start_state); + struct sock_daemon_run_state *state = tevent_req_data( + req, struct sock_daemon_run_state); struct sock_daemon_context *sockd = state->sockd; D_NOTICE("daemon started, pid=%u\n", getpid()); @@ -645,8 +645,8 @@ static void sock_daemon_signal_handler(struct tevent_context *ev, { struct tevent_req *req = talloc_get_type_abort( private_data, struct tevent_req); - struct sock_daemon_start_state *state = tevent_req_data( - req, struct sock_daemon_start_state); + struct sock_daemon_run_state *state = tevent_req_data( + req, struct sock_daemon_run_state); D_NOTICE("Received signal %d\n", signum); @@ -661,7 +661,7 @@ static void sock_daemon_signal_handler(struct tevent_context *ev, } } -static void sock_daemon_reconfigure(struct sock_daemon_start_state *state) +static void sock_daemon_reconfigure(struct sock_daemon_run_state *state) { struct sock_daemon_context *sockd = state->sockd; @@ -670,7 +670,7 @@ static void sock_daemon_reconfigure(struct sock_daemon_start_state *state) } } -static void sock_daemon_shutdown(struct sock_daemon_start_state *state) +static void sock_daemon_shutdown(struct sock_daemon_run_state *state) { struct sock_daemon_context *sockd = state->sockd; struct sock_socket *sock; @@ -694,8 +694,8 @@ static void sock_daemon_socket_fail(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); - struct sock_daemon_start_state *state = tevent_req_data( - req, struct sock_daemon_start_state); + struct sock_daemon_run_state *state = tevent_req_data( + req, struct sock_daemon_run_state); int ret = 0; bool status; @@ -714,8 +714,8 @@ static void sock_daemon_watch_pid(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); - struct sock_daemon_start_state *state = tevent_req_data( - req, struct sock_daemon_start_state); + struct sock_daemon_run_state *state = tevent_req_data( + req, struct sock_daemon_run_state); int ret; bool status; -- 2.9.3 From bb882450cb2df21e326c44ed669405a4dd81a7e2 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Fri, 13 Jan 2017 10:40:43 +1100 Subject: [PATCH 2/5] ctdb-common: Use consistent naming for sock_daemon_run computation functions BUG: https://bugzilla.samba.org/show_bug.cgi?id=12510 Signed-off-by: Amitay Isaacs Reviewed-by: Stefan Metzmacher (cherry picked from commit 31274cf7aec1bb26e8dac0dbd1b9a3fa799b2b85) --- ctdb/common/sock_daemon.c | 62 ++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c index 87935fd..3bccf46 100644 --- a/ctdb/common/sock_daemon.c +++ b/ctdb/common/sock_daemon.c @@ -537,15 +537,15 @@ struct sock_daemon_run_state { int fd; }; -static void sock_daemon_started(struct tevent_req *subreq); -static void sock_daemon_signal_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, int count, void *siginfo, - void *private_data); -static void sock_daemon_reconfigure(struct sock_daemon_run_state *state); -static void sock_daemon_shutdown(struct sock_daemon_run_state *state); -static void sock_daemon_socket_fail(struct tevent_req *subreq); -static void sock_daemon_watch_pid(struct tevent_req *subreq); +static void sock_daemon_run_started(struct tevent_req *subreq); +static void sock_daemon_run_signal_handler(struct tevent_context *ev, + struct tevent_signal *se, + int signum, int count, void *siginfo, + void *private_data); +static void sock_daemon_run_reconfigure(struct sock_daemon_run_state *state); +static void sock_daemon_run_shutdown(struct sock_daemon_run_state *state); +static void sock_daemon_run_socket_fail(struct tevent_req *subreq); +static void sock_daemon_run_watch_pid(struct tevent_req *subreq); struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -573,28 +573,28 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, sock_daemon_started, req); + tevent_req_set_callback(subreq, sock_daemon_run_started, req); se = tevent_add_signal(ev, state, SIGHUP, 0, - sock_daemon_signal_handler, req); + sock_daemon_run_signal_handler, req); if (tevent_req_nomem(se, req)) { return tevent_req_post(req, ev); } se = tevent_add_signal(ev, state, SIGUSR1, 0, - sock_daemon_signal_handler, req); + sock_daemon_run_signal_handler, req); if (tevent_req_nomem(se, req)) { return tevent_req_post(req, ev); } se = tevent_add_signal(ev, state, SIGINT, 0, - sock_daemon_signal_handler, req); + sock_daemon_run_signal_handler, req); if (tevent_req_nomem(se, req)) { return tevent_req_post(req, ev); } se = tevent_add_signal(ev, state, SIGTERM, 0, - sock_daemon_signal_handler, req); + sock_daemon_run_signal_handler, req); if (tevent_req_nomem(se, req)) { return tevent_req_post(req, ev); } @@ -604,7 +604,8 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, sock_daemon_socket_fail, req); + tevent_req_set_callback(subreq, sock_daemon_run_socket_fail, + req); sock->req = subreq; } @@ -615,7 +616,8 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, sock_daemon_watch_pid, req); + tevent_req_set_callback(subreq, sock_daemon_run_watch_pid, + req); } sockd->req = req; @@ -623,7 +625,7 @@ struct tevent_req *sock_daemon_run_send(TALLOC_CTX *mem_ctx, return req; } -static void sock_daemon_started(struct tevent_req *subreq) +static void sock_daemon_run_started(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); @@ -638,10 +640,10 @@ static void sock_daemon_started(struct tevent_req *subreq) } } -static void sock_daemon_signal_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, int count, void *siginfo, - void *private_data) +static void sock_daemon_run_signal_handler(struct tevent_context *ev, + struct tevent_signal *se, + int signum, int count, void *siginfo, + void *private_data) { struct tevent_req *req = talloc_get_type_abort( private_data, struct tevent_req); @@ -651,17 +653,17 @@ static void sock_daemon_signal_handler(struct tevent_context *ev, D_NOTICE("Received signal %d\n", signum); if (signum == SIGHUP || signum == SIGUSR1) { - sock_daemon_reconfigure(state); + sock_daemon_run_reconfigure(state); return; } if (signum == SIGINT || signum == SIGTERM) { - sock_daemon_shutdown(state); + sock_daemon_run_shutdown(state); tevent_req_error(req, EINTR); } } -static void sock_daemon_reconfigure(struct sock_daemon_run_state *state) +static void sock_daemon_run_reconfigure(struct sock_daemon_run_state *state) { struct sock_daemon_context *sockd = state->sockd; @@ -670,7 +672,7 @@ static void sock_daemon_reconfigure(struct sock_daemon_run_state *state) } } -static void sock_daemon_shutdown(struct sock_daemon_run_state *state) +static void sock_daemon_run_shutdown(struct sock_daemon_run_state *state) { struct sock_daemon_context *sockd = state->sockd; struct sock_socket *sock; @@ -690,7 +692,7 @@ static void sock_daemon_shutdown(struct sock_daemon_run_state *state) TALLOC_FREE(sockd->pid_ctx); } -static void sock_daemon_socket_fail(struct tevent_req *subreq) +static void sock_daemon_run_socket_fail(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); @@ -707,10 +709,10 @@ static void sock_daemon_socket_fail(struct tevent_req *subreq) tevent_req_done(req); } - sock_daemon_shutdown(state); + sock_daemon_run_shutdown(state); } -static void sock_daemon_watch_pid(struct tevent_req *subreq) +static void sock_daemon_run_watch_pid(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); @@ -730,7 +732,7 @@ static void sock_daemon_watch_pid(struct tevent_req *subreq) if (ret == -1) { if (errno == ESRCH) { D_ERR("PID %d gone away, exiting\n", state->pid_watch); - sock_daemon_shutdown(state); + sock_daemon_run_shutdown(state); tevent_req_error(req, ESRCH); return; } else { @@ -744,7 +746,7 @@ static void sock_daemon_watch_pid(struct tevent_req *subreq) if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, sock_daemon_watch_pid, req); + tevent_req_set_callback(subreq, sock_daemon_run_watch_pid, req); } bool sock_daemon_run_recv(struct tevent_req *req, int *perr) -- 2.9.3 From 7a4a4736a3fed80af5973b3ffe53dd114735bbde Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Fri, 13 Jan 2017 10:43:44 +1100 Subject: [PATCH 3/5] ctdb-common: Pass tevent_req to the computation sub-functions BUG: https://bugzilla.samba.org/show_bug.cgi?id=12510 Signed-off-by: Amitay Isaacs Reviewed-by: Stefan Metzmacher (cherry picked from commit d5be55725000eb34611dc76a2e8e7188eea2503f) --- ctdb/common/sock_daemon.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c index 3bccf46..08102c3 100644 --- a/ctdb/common/sock_daemon.c +++ b/ctdb/common/sock_daemon.c @@ -542,8 +542,8 @@ static void sock_daemon_run_signal_handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data); -static void sock_daemon_run_reconfigure(struct sock_daemon_run_state *state); -static void sock_daemon_run_shutdown(struct sock_daemon_run_state *state); +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); @@ -647,24 +647,24 @@ 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); if (signum == SIGHUP || signum == SIGUSR1) { - sock_daemon_run_reconfigure(state); + sock_daemon_run_reconfigure(req); return; } if (signum == SIGINT || signum == SIGTERM) { - sock_daemon_run_shutdown(state); + sock_daemon_run_shutdown(req); tevent_req_error(req, EINTR); } } -static void sock_daemon_run_reconfigure(struct sock_daemon_run_state *state) +static void sock_daemon_run_reconfigure(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; if (sockd->funcs != NULL && sockd->funcs->reconfigure != NULL) { @@ -672,8 +672,10 @@ static void sock_daemon_run_reconfigure(struct sock_daemon_run_state *state) } } -static void sock_daemon_run_shutdown(struct sock_daemon_run_state *state) +static void sock_daemon_run_shutdown(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; struct sock_socket *sock; @@ -696,8 +698,6 @@ static void sock_daemon_run_socket_fail(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); int ret = 0; bool status; @@ -709,7 +709,7 @@ static void sock_daemon_run_socket_fail(struct tevent_req *subreq) tevent_req_done(req); } - sock_daemon_run_shutdown(state); + sock_daemon_run_shutdown(req); } static void sock_daemon_run_watch_pid(struct tevent_req *subreq) @@ -732,7 +732,7 @@ 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); - sock_daemon_run_shutdown(state); + sock_daemon_run_shutdown(req); tevent_req_error(req, ESRCH); return; } else { -- 2.9.3 From 455520f1af86e14e86ccaca08256dda0e4df24cc Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 11 Jan 2017 19:54:36 +1100 Subject: [PATCH 4/5] ctdb-common: Avoid any processing after finishing tevent_req BUG: https://bugzilla.samba.org/show_bug.cgi?id=12510 Signed-off-by: Amitay Isaacs Reviewed-by: Stefan Metzmacher (cherry picked from commit d09469e575233242eab2a8c1c0767f52e7cad1e5) --- ctdb/common/sock_daemon.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c index 08102c3..3b679ab1 100644 --- a/ctdb/common/sock_daemon.c +++ b/ctdb/common/sock_daemon.c @@ -703,13 +703,12 @@ static void sock_daemon_run_socket_fail(struct tevent_req *subreq) status = sock_socket_start_recv(subreq, &ret); TALLOC_FREE(subreq); + sock_daemon_run_shutdown(req); if (! status) { tevent_req_error(req, ret); } else { tevent_req_done(req); } - - sock_daemon_run_shutdown(req); } static void sock_daemon_run_watch_pid(struct tevent_req *subreq) -- 2.9.3 From 8a83ac7020cdea05ffbd423b293606088aa5efb4 Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Wed, 11 Jan 2017 20:37:00 +1100 Subject: [PATCH 5/5] 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 Reviewed-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Mon Jan 16 21:16:51 CET 2017 on sn-devel-144 (cherry picked from commit ed722c3aa9690873af495cb467dd440c1a714d82) --- ctdb/common/sock_daemon.c | 47 ++++++--- ctdb/common/sock_daemon.h | 14 ++- ctdb/tests/cunit/sock_daemon_test_001.sh | 2 + ctdb/tests/src/sock_daemon_test.c | 175 ++++++++++++++++++++++++------- 4 files changed, 183 insertions(+), 55 deletions(-) diff --git a/ctdb/common/sock_daemon.c b/ctdb/common/sock_daemon.c index 3b679ab1..b53b4d8 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 6c474ac..81853f6 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); }; /** diff --git a/ctdb/tests/cunit/sock_daemon_test_001.sh b/ctdb/tests/cunit/sock_daemon_test_001.sh index 036b6ac..72e5532 100755 --- a/ctdb/tests/cunit/sock_daemon_test_001.sh +++ b/ctdb/tests/cunit/sock_daemon_test_001.sh @@ -47,6 +47,7 @@ unit_test sock_daemon_test "$pidfile" "$sockpath" 3 ok <fd, &ret, sizeof(ret)); assert(nwritten == sizeof(ret)); - close(fd); + close(server_state->fd); + server_state->fd = -1; } -static struct sock_daemon_funcs test6_funcs = { - .startup = test6_startup, +struct test6_wait_state { + struct test6_server_state *server_state; }; -static void test6_handler(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval curtime, - void *private_data) +static void test6_wait_done(struct tevent_req *subreq); + +static struct tevent_req *test6_wait_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + void *private_data) { - struct test6_server_state *state = - (struct test6_server_state *)private_data; + struct tevent_req *req, *subreq; + struct test6_wait_state *state; + + req = tevent_req_create(mem_ctx, &state, struct test6_wait_state); + if (req == NULL) { + return NULL; + } + + state->server_state = (struct test6_server_state *)private_data; - if (state->done == 0) { - kill(0, SIGTERM); + subreq = tevent_wakeup_send(state, ev, + tevent_timeval_current_ofs(10,0)); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, test6_wait_done, req); + + return req; +} + +static void test6_wait_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct test6_wait_state *state = tevent_req_data( + req, struct test6_wait_state); + bool status; + + status = tevent_wakeup_recv(subreq); + TALLOC_FREE(subreq); + if (! status) { + tevent_req_error(req, EIO); return; } - talloc_free(state->sockd); + if (state->server_state->done == 0) { + tevent_req_error(req, EIO); + return; + } + + tevent_req_done(req); } +static bool test6_wait_recv(struct tevent_req *req, int *perr) +{ + int ret; + + if (tevent_req_is_unix_error(req, &ret)) { + if (perr != NULL) { + *perr = ret; + } + return false; + } + + return true; +} + +static struct sock_daemon_funcs test6_funcs = { + .startup = test6_startup, + .wait_send = test6_wait_send, + .wait_recv = test6_wait_recv, +}; + static void test6(TALLOC_CTX *mem_ctx, const char *pidfile, const char *sockpath) { @@ -799,29 +900,27 @@ static void test6(TALLOC_CTX *mem_ctx, const char *pidfile, if (pid_server == 0) { struct tevent_context *ev; struct sock_daemon_context *sockd; - struct test6_server_state state; - struct tevent_timer *te; + struct test6_server_state server_state = { 0 }; close(fd[0]); ev = tevent_context_init(mem_ctx); assert(ev != NULL); + server_state.fd = fd[1]; + ret = sock_daemon_setup(mem_ctx, "test6", "file:", "NOTICE", - pidfile, &test6_funcs, &fd[1], &sockd); + pidfile, &test6_funcs, &server_state, + &sockd); assert(ret == 0); - state.sockd = sockd; - state.done = 0; + server_state.sockd = sockd; + server_state.done = 0; ret = sock_daemon_add_unix(sockd, sockpath, - &test6_client_funcs, &state); + &test6_client_funcs, &server_state); assert(ret == 0); - te = tevent_add_timer(ev, ev, tevent_timeval_current_ofs(10,0), - test6_handler, &state); - assert(te != NULL); - ret = sock_daemon_run(ev, sockd, pid); assert(ret == 0); -- 2.9.3