lightningd/lightningd: shutdown subdaemons on exit.

Especially under valgrind, we should give them some time to exit.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-04-11 23:52:32 -07:00
parent 3c5a70910a
commit d27a5d3212
3 changed files with 52 additions and 1 deletions

View File

@ -197,6 +197,20 @@ void derive_peer_seed(struct lightningd *ld, struct privkey *peer_seed,
ld->peer_counter++;
}
static void shutdown_subdaemons(struct lightningd *ld)
{
struct peer *p;
/* Let everyone shutdown cleanly. */
subd_shutdown(ld->hsm, 10);
subd_shutdown(ld->gossip, 10);
/* Duplicates are OK: no need to check here. */
list_for_each(&ld->peers, p, list)
if (p->owner)
subd_shutdown(p->owner, 0);
}
int main(int argc, char *argv[])
{
struct lightningd *ld = new_lightningd(NULL);
@ -250,7 +264,6 @@ int main(int argc, char *argv[])
#if 0
/* Load peers from database. */
db_load_peers(dstate);
#endif
for (;;) {
@ -265,6 +278,8 @@ int main(int argc, char *argv[])
timer_expired(&ld->dstate, expired);
}
shutdown_subdaemons(ld);
tal_free(ld);
opt_free_table();
return 0;

View File

@ -431,6 +431,32 @@ void subd_req_(const tal_t *ctx,
add_req(ctx, sd, type, num_fds_in, replycb, replycb_data);
}
void subd_shutdown(struct subd *sd, unsigned int seconds)
{
/* Idempotent. */
if (!sd->conn)
return;
log_debug(sd->log, "Shutting down");
/* No finished callback any more. */
sd->finished = NULL;
/* Don't free sd when we close connection manually. */
tal_steal(sd->ld, sd);
/* Close connection: should begin shutdown now. */
sd->conn = tal_free(sd->conn);
/* Do we actually want to wait? */
while (seconds) {
if (waitpid(sd->pid, NULL, WNOHANG) > 0) {
tal_del_destructor(sd, destroy_subd);
return;
}
sleep(1);
seconds--;
}
}
char *opt_subd_debug(const char *optarg, struct lightningd *ld)
{
ld->dev_debug_subdaemon = optarg;

View File

@ -113,6 +113,16 @@ void subd_req_(const tal_t *ctx,
bool (*replycb)(struct subd *, const u8 *, const int *, void *),
void *replycb_data);
/**
* subd_shutdown - try to politely shut down a subdaemon.
* @subd: subd to shutdown.
* @seconds: maximum seconds to wait for it to exit.
*
* This closes the fd to the subdaemon, and gives it a little while to exit.
* The @finished callback will never be called.
*/
void subd_shutdown(struct subd *subd, unsigned int seconds);
char *opt_subd_debug(const char *optarg, struct lightningd *ld);
#endif /* LIGHTNING_LIGHTNINGD_SUBD_H */