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 <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2016-01-22 06:45:28 +10:30
parent f690be1e83
commit 45c5c83d6f
2 changed files with 20 additions and 6 deletions

View File

@ -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);

View File

@ -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)