From 45c5c83d6f860968e36315af1dcd6e3ce079caf6 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 22 Jan 2016 06:45:28 +1030 Subject: [PATCH] daemon: exit main loop to free dead peers. When a peer is finally to be freed (ie. STATE_CLOSED), doing this inside the state logic is a bit fraught. We're better off exiting the io loop and freeing it there. Signed-off-by: Rusty Russell --- daemon/lightningd.c | 22 ++++++++++++++++------ daemon/peer.c | 4 ++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/daemon/lightningd.c b/daemon/lightningd.c index d38b5e5db..d4baa0def 100644 --- a/daemon/lightningd.c +++ b/daemon/lightningd.c @@ -196,7 +196,6 @@ static void tal_freefn(void *ptr) int main(int argc, char *argv[]) { struct lightningd_state *dstate = lightningd_state(); - struct timer *expired; unsigned int portnum = 0; err_set_progname(argv[0]); @@ -261,12 +260,23 @@ int main(int argc, char *argv[]) log_info(dstate->base_log, "Hello world!"); - /* If io_loop returns NULL, either a timer expired, or all fds closed */ - while (!io_loop(&dstate->timers, &expired) && expired) { - struct timeout *to; + for (;;) { + struct timer *expired; + void *v = io_loop(&dstate->timers, &expired); - to = container_of(expired, struct timeout, timer); - to->cb(to->arg); + /* We use io_break(dstate) to shut down. */ + if (v == dstate) + break; + + /* We use it on a peer when it needs freeing (may be + * NULL if we only broke out due to timer). */ + tal_free(v); + + if (expired) { + struct timeout *to; + to = container_of(expired, struct timeout, timer); + to->cb(to->arg); + } } tal_free(dstate); diff --git a/daemon/peer.c b/daemon/peer.c index f46bc98ea..cb94c6c1f 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -160,6 +160,10 @@ static void state_single(struct peer *peer, state_name(peer->state)); fatal("Peer entered error state"); } + + /* Break out and free this peer if it's completely done. */ + if (peer->state == STATE_CLOSED) + io_break(peer); } static void try_command(struct peer *peer)