From 0954feddc7d9de45448b9516a2737623d478fa84 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 14 Aug 2019 13:55:23 +0930 Subject: [PATCH] json: speed up shutdown. We currently end up sleeping for 1 second for channeld and gossipd: better to use a normal blocking waitpid and an alarm to wake us in case they don't exit. This speeds up `lightning-cli stop` on my machine from 2.008s to 0.008s: a 286 times speedup! Signed-off-by: Rusty Russell --- lightningd/subd.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/lightningd/subd.c b/lightningd/subd.c index 339c47b16..319598487 100644 --- a/lightningd/subd.c +++ b/lightningd/subd.c @@ -749,8 +749,16 @@ void subd_req_(const tal_t *ctx, add_req(ctx, sd, type, num_fds_in, replycb, replycb_data); } +/* SIGALRM terminates by default: we just want it to interrupt waitpid(), + * which is implied by "handling" it. */ +static void discard_alarm(int sig UNNEEDED) +{ +} + struct subd *subd_shutdown(struct subd *sd, unsigned int seconds) { + struct sigaction sa, old; + log_debug(sd->log, "Shutting down"); tal_del_destructor(sd, destroy_subd); @@ -759,19 +767,24 @@ struct subd *subd_shutdown(struct subd *sd, unsigned int seconds) tal_steal(sd->ld, sd); sd->conn = tal_free(sd->conn); - /* Wait for a while. */ - while (seconds) { - if (waitpid(sd->pid, NULL, WNOHANG) > 0) { - return (struct subd*) tal_free(sd); - } - sleep(1); - seconds--; + /* Set up alarm to wake us up if child doesn't exit. */ + sa.sa_handler = discard_alarm; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sigaction(SIGALRM, &sa, &old); + alarm(seconds); + + if (waitpid(sd->pid, NULL, 0) > 0) { + alarm(0); + sigaction(SIGALRM, &old, NULL); + return tal_free(sd); } + sigaction(SIGALRM, &old, NULL); /* Didn't die? This will kill it harder */ sd->must_not_exit = false; destroy_subd(sd); - return (struct subd*) tal_free(sd); + return tal_free(sd); } void subd_release_channel(struct subd *owner, void *channel)