Browse Source

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 <rusty@rustcorp.com.au>
pull/2938/head
Rusty Russell 6 years ago
parent
commit
0954feddc7
  1. 29
      lightningd/subd.c

29
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); 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 subd *subd_shutdown(struct subd *sd, unsigned int seconds)
{ {
struct sigaction sa, old;
log_debug(sd->log, "Shutting down"); log_debug(sd->log, "Shutting down");
tal_del_destructor(sd, destroy_subd); 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); tal_steal(sd->ld, sd);
sd->conn = tal_free(sd->conn); sd->conn = tal_free(sd->conn);
/* Wait for a while. */ /* Set up alarm to wake us up if child doesn't exit. */
while (seconds) { sa.sa_handler = discard_alarm;
if (waitpid(sd->pid, NULL, WNOHANG) > 0) { sigemptyset(&sa.sa_mask);
return (struct subd*) tal_free(sd); sa.sa_flags = 0;
} sigaction(SIGALRM, &sa, &old);
sleep(1); alarm(seconds);
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 */ /* Didn't die? This will kill it harder */
sd->must_not_exit = false; sd->must_not_exit = false;
destroy_subd(sd); destroy_subd(sd);
return (struct subd*) tal_free(sd); return tal_free(sd);
} }
void subd_release_channel(struct subd *owner, void *channel) void subd_release_channel(struct subd *owner, void *channel)

Loading…
Cancel
Save