From 48df6c856610d0e96cd3e098a740741fae38658d Mon Sep 17 00:00:00 2001 From: ZmnSCPxj Date: Thu, 30 May 2019 02:30:10 +0000 Subject: [PATCH] lightningd/io_loop_with_timers.c: Move mainloop to its own source file, have chaintopology use it. Fixes: #2687 --- lightningd/Makefile | 1 + lightningd/chaintopology.c | 3 ++- lightningd/io_loop_with_timers.c | 36 +++++++++++++++++++++++++++ lightningd/io_loop_with_timers.h | 10 ++++++++ lightningd/lightningd.c | 31 ++++++----------------- lightningd/test/run-find_my_abspath.c | 1 + tests/test_misc.py | 1 - 7 files changed, 57 insertions(+), 26 deletions(-) create mode 100644 lightningd/io_loop_with_timers.c create mode 100644 lightningd/io_loop_with_timers.h diff --git a/lightningd/Makefile b/lightningd/Makefile index 1a054346c..932d8a46c 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -69,6 +69,7 @@ LIGHTNINGD_SRC := \ lightningd/hsm_control.c \ lightningd/htlc_end.c \ lightningd/invoice.c \ + lightningd/io_loop_with_timers.c \ lightningd/json.c \ lightningd/json_stream.c \ lightningd/jsonrpc.c \ diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 633405681..4bf302546 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -22,6 +22,7 @@ #include #include #include +#include /* Mutual recursion via timer. */ static void try_extend_tip(struct chain_topology *topo); @@ -894,7 +895,7 @@ void setup_topology(struct chain_topology *topo, start_fee_estimate(topo); /* Once it gets initial block, it calls io_break() and we return. */ - io_loop(NULL, NULL); + io_loop_with_timers(topo->ld); } void begin_topology(struct chain_topology *topo) diff --git a/lightningd/io_loop_with_timers.c b/lightningd/io_loop_with_timers.c new file mode 100644 index 000000000..be781d355 --- /dev/null +++ b/lightningd/io_loop_with_timers.c @@ -0,0 +1,36 @@ +#include "lightningd/io_loop_with_timers.h" + +#include +#include +#include +#include +#include +#include + +void *io_loop_with_timers(struct lightningd *ld) +{ + void *retval = NULL; + struct timer *expired; + + while (!retval) { + /* ~ccan/io's io_loop() continuously calls + * io_poll_lightningd() for all file descriptors registered + * with it, then calls their callbacks or closes them if they + * fail, as appropriate. + * + * It will only exit if there's an expired timer, *or* someone + * calls io_break, or if there are no more file descriptors + * (which never happens in our code). */ + retval = io_loop(&ld->timers, &expired); + + /*~ Notice that timers are called here in the event loop like + * anything else, so there are no weird concurrency issues. */ + if (expired) { + db_begin_transaction(ld->wallet->db); + timer_expired(ld, expired); + db_commit_transaction(ld->wallet->db); + } + } + + return retval; +} diff --git a/lightningd/io_loop_with_timers.h b/lightningd/io_loop_with_timers.h new file mode 100644 index 000000000..cc8e85bd4 --- /dev/null +++ b/lightningd/io_loop_with_timers.h @@ -0,0 +1,10 @@ +#ifndef LIGHTNING_LIGHTNINGD_IO_LOOP_WITH_TIMERS_H +#define LIGHTNING_LIGHTNINGD_IO_LOOP_WITH_TIMERS_H + +#include "config.h" + +struct lightningd; + +void *io_loop_with_timers(struct lightningd *ld); + +#endif /* LIGHTNING_LIGHTNINGD_IO_LOOP_WITH_TIMERS_H */ diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 36996e200..2fffa15ce 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -810,30 +811,12 @@ int main(int argc, char *argv[]) /*~ The root of every backtrace (almost). This is our main event * loop. */ - for (;;) { - /* ~ccan/io's io_loop() continuously calls - * io_poll_lightningd() for all file descriptors registered - * with it, then calls their callbacks or closes them if they - * fail, as appropriate. - * - * It will only exit if there's an expired timer, *or* someone - * calls io_break, or if there are no more file descriptors - * (which never happens in our code). */ - struct timer *expired; - void *v = io_loop(&ld->timers, &expired); - - /*~ We use io_break(ld) to shut down. */ - if (v == ld) - break; - - /*~ Notice that timers are called here in the event loop like - * anything else, so there are no weird concurrency issues. */ - if (expired) { - db_begin_transaction(ld->wallet->db); - timer_expired(ld, expired); - db_commit_transaction(ld->wallet->db); - } - } + void *io_loop_ret = io_loop_with_timers(ld); + /*~ io_loop_with_timers will only exit if we call io_break. + * At this point in code, we should use io_break(ld) to + * shut down. + */ + assert(io_loop_ret == ld); shutdown_subdaemons(ld); diff --git a/lightningd/test/run-find_my_abspath.c b/lightningd/test/run-find_my_abspath.c index f05707e25..113a19538 100644 --- a/lightningd/test/run-find_my_abspath.c +++ b/lightningd/test/run-find_my_abspath.c @@ -2,6 +2,7 @@ int unused_main(int argc, char *argv[]); #include "../../common/base32.c" #include "../../common/wireaddr.c" +#include "../io_loop_with_timers.c" #include "../lightningd.c" #include "../subd.c" #include diff --git a/tests/test_misc.py b/tests/test_misc.py index d0fa2e34a..0c7a5a9af 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -1401,7 +1401,6 @@ def test_newaddr(node_factory): assert both['bech32'].startswith('bcrt1') -@pytest.mark.xfail(strict=True) def test_bitcoind_fail_first(node_factory, bitcoind, executor): """Make sure we handle spurious bitcoin-cli failures during startup