daemon: fix bug when we close two peers simulatneously.

If a block triggers two peers to close, we ran io_break() on both of them; the
second overrode the first and we didn't end up freeing that one.

Rather than chase such bugs in future, simply iterate to see if any
peers need freeing.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2016-06-30 09:08:11 +09:30
parent 31a5de644a
commit 21a29d9b4d
3 changed files with 15 additions and 4 deletions

View File

@ -345,12 +345,10 @@ int main(int argc, char *argv[])
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)
timer_expired(dstate, expired);
else
cleanup_peers(dstate);
}
tal_free(dstate);

View File

@ -2678,6 +2678,18 @@ const struct json_command getpeers_command = {
"Returns a 'peers' array"
};
/* To avoid freeing underneath ourselves, we free outside event loop. */
void cleanup_peers(struct lightningd_state *dstate)
{
struct peer *peer, *next;
list_for_each_safe(&dstate->peers, peer, next, list) {
/* Deletes itself from list. */
if (!peer->conn && peer->state == STATE_CLOSED)
tal_free(peer);
}
}
/* A zero-fee single route to this peer. */
static const u8 *dummy_single_route(const tal_t *ctx,
const struct peer *peer,

View File

@ -272,4 +272,5 @@ uint64_t commit_tx_fee(const struct bitcoin_tx *commit,
void our_htlc_fulfilled(struct peer *peer, struct htlc *htlc,
const struct rval *preimage);
void cleanup_peers(struct lightningd_state *dstate);
#endif /* LIGHTNING_DAEMON_PEER_H */