mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
timeout: make all timers one-shot.
It's closer to what we want, and simpler. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
4beaedfa49
commit
82c2325467
@ -12,8 +12,6 @@
|
||||
#include <ccan/asort/asort.h>
|
||||
#include <ccan/structeq/structeq.h>
|
||||
|
||||
static struct timeout topology_timeout;
|
||||
|
||||
struct block {
|
||||
int height;
|
||||
|
||||
@ -65,6 +63,14 @@ struct topology {
|
||||
struct block_map block_map;
|
||||
};
|
||||
|
||||
static void start_poll_chaintips(struct lightningd_state *dstate);
|
||||
|
||||
static void next_topology_timer(struct lightningd_state *dstate)
|
||||
{
|
||||
new_reltimer(dstate, dstate, time_from_sec(dstate->config.poll_seconds),
|
||||
start_poll_chaintips, dstate);
|
||||
}
|
||||
|
||||
static int cmp_times(const u32 *a, const u32 *b, void *unused)
|
||||
{
|
||||
if (*a > *b)
|
||||
@ -371,7 +377,7 @@ static void gather_blocks(struct lightningd_state *dstate,
|
||||
|
||||
/* All done. */
|
||||
topology_changed(dstate, prev, b);
|
||||
refresh_timeout(dstate, &topology_timeout);
|
||||
next_topology_timer(dstate);
|
||||
}
|
||||
|
||||
static void check_chaintips(struct lightningd_state *dstate,
|
||||
@ -385,7 +391,8 @@ static void check_chaintips(struct lightningd_state *dstate,
|
||||
bitcoind_getrawblock(dstate, &blockids[0], gather_blocks,
|
||||
(struct block *)NULL);
|
||||
else
|
||||
refresh_timeout(dstate, &topology_timeout);
|
||||
/* Next! */
|
||||
next_topology_timer(dstate);
|
||||
}
|
||||
|
||||
static void start_poll_chaintips(struct lightningd_state *dstate)
|
||||
@ -393,10 +400,10 @@ static void start_poll_chaintips(struct lightningd_state *dstate)
|
||||
if (!list_empty(&dstate->bitcoin_req)) {
|
||||
log_unusual(dstate->base_log,
|
||||
"Delaying start poll: commands in progress");
|
||||
refresh_timeout(dstate, &topology_timeout);
|
||||
next_topology_timer(dstate);
|
||||
} else
|
||||
bitcoind_get_chaintips(dstate, check_chaintips, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void init_topo(struct lightningd_state *dstate,
|
||||
struct bitcoin_block *blk,
|
||||
@ -457,7 +464,5 @@ void setup_topology(struct lightningd_state *dstate)
|
||||
dstate->topology->tip = NULL;
|
||||
block_map_init(&dstate->topology->block_map);
|
||||
|
||||
init_timeout(&topology_timeout, dstate->config.poll_seconds,
|
||||
start_poll_chaintips, dstate);
|
||||
bitcoind_getblockcount(dstate, get_init_blockhash, NULL);
|
||||
}
|
||||
|
@ -307,11 +307,8 @@ int main(int argc, char *argv[])
|
||||
* 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);
|
||||
}
|
||||
if (expired)
|
||||
timer_expired(dstate, expired);
|
||||
}
|
||||
|
||||
tal_free(dstate);
|
||||
|
@ -1559,9 +1559,10 @@ void peer_watch_anchor(struct peer *peer,
|
||||
* So, our formula of 12 + N*2 holds for N <= 20 at least.
|
||||
*/
|
||||
if (w->timeout != INPUT_NONE) {
|
||||
w->timer = oneshot_timeout(peer->dstate, w,
|
||||
7200 + 20*peer->us.mindepth,
|
||||
anchor_timeout, w);
|
||||
w->timer = new_reltimer(peer->dstate, w,
|
||||
time_from_sec(7200
|
||||
+ 20*peer->us.mindepth),
|
||||
anchor_timeout, w);
|
||||
} else
|
||||
w->timer = NULL;
|
||||
}
|
||||
@ -2063,13 +2064,13 @@ static void htlc_expiry_timeout(struct peer *peer)
|
||||
void peer_add_htlc_expiry(struct peer *peer,
|
||||
const struct abs_locktime *expiry)
|
||||
{
|
||||
time_t when;
|
||||
struct timeabs absexpiry;
|
||||
|
||||
/* Add 30 seconds to be sure peers agree on timeout. */
|
||||
when = abs_locktime_to_seconds(expiry) - controlled_time().ts.tv_sec;
|
||||
when += 30;
|
||||
absexpiry.ts.tv_sec = abs_locktime_to_seconds(expiry) + 30;
|
||||
absexpiry.ts.tv_nsec = 0;
|
||||
|
||||
oneshot_timeout(peer->dstate, peer, when, htlc_expiry_timeout, peer);
|
||||
new_abstimer(peer->dstate, peer, absexpiry, htlc_expiry_timeout, peer);
|
||||
}
|
||||
|
||||
struct newhtlc {
|
||||
|
@ -2,54 +2,51 @@
|
||||
#include "lightningd.h"
|
||||
#include "timeout.h"
|
||||
|
||||
void init_timeout_(struct timeout *t, unsigned int interval,
|
||||
void (*cb)(void *), void *arg)
|
||||
{
|
||||
timer_init(&t->timer);
|
||||
t->interval = time_from_sec(interval);
|
||||
t->cb = cb;
|
||||
t->arg = arg;
|
||||
}
|
||||
|
||||
void refresh_timeout(struct lightningd_state *dstate, struct timeout *t)
|
||||
{
|
||||
timer_del(&dstate->timers, &t->timer);
|
||||
timer_add(&dstate->timers, &t->timer,
|
||||
timeabs_add(controlled_time(), t->interval));
|
||||
}
|
||||
|
||||
/* FIXME: Make all timers one-shot! */
|
||||
struct oneshot {
|
||||
struct timeout timeout;
|
||||
struct lightningd_state *dstate;
|
||||
struct timer timer;
|
||||
void (*cb)(void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static void remove_timer(struct oneshot *o)
|
||||
static void remove_timer(struct oneshot *t)
|
||||
{
|
||||
timer_del(&o->dstate->timers, &o->timeout.timer);
|
||||
timer_del(&t->dstate->timers, &t->timer);
|
||||
}
|
||||
|
||||
static void oneshot_done(struct oneshot *o)
|
||||
struct oneshot *new_abstimer_(struct lightningd_state *dstate,
|
||||
const tal_t *ctx,
|
||||
struct timeabs expiry,
|
||||
void (*cb)(void *), void *arg)
|
||||
{
|
||||
o->cb(o->arg);
|
||||
tal_free(o);
|
||||
struct oneshot *t = tal(ctx, struct oneshot);
|
||||
|
||||
t->cb = cb;
|
||||
t->arg = arg;
|
||||
t->dstate = dstate;
|
||||
timer_init(&t->timer);
|
||||
timer_add(&dstate->timers, &t->timer, expiry);
|
||||
tal_add_destructor(t, remove_timer);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
struct oneshot *oneshot_timeout_(struct lightningd_state *dstate,
|
||||
const tal_t *ctx, unsigned int seconds,
|
||||
void (*cb)(void *), void *arg)
|
||||
struct oneshot *new_reltimer_(struct lightningd_state *dstate,
|
||||
const tal_t *ctx,
|
||||
struct timerel relexpiry,
|
||||
void (*cb)(void *), void *arg)
|
||||
{
|
||||
struct oneshot *o = tal(ctx, struct oneshot);
|
||||
|
||||
o->dstate = dstate;
|
||||
o->cb = cb;
|
||||
o->arg = arg;
|
||||
|
||||
init_timeout(&o->timeout, seconds, oneshot_done, o);
|
||||
refresh_timeout(dstate, &o->timeout);
|
||||
tal_add_destructor(o, remove_timer);
|
||||
|
||||
return o;
|
||||
return new_abstimer_(dstate, ctx,
|
||||
timeabs_add(controlled_time(), relexpiry),
|
||||
cb, arg);
|
||||
}
|
||||
|
||||
void timer_expired(struct lightningd_state *dstate, struct timer *timer)
|
||||
{
|
||||
struct oneshot *t = container_of(timer, struct oneshot, timer);
|
||||
tal_t *tmpctx = tal(dstate, char);
|
||||
|
||||
/* If it doesn't free itself, freeing tmpctx will do it */
|
||||
tal_steal(tmpctx, t);
|
||||
t->cb(t->arg);
|
||||
}
|
||||
|
@ -7,31 +7,25 @@
|
||||
#include <ccan/timer/timer.h>
|
||||
#include <ccan/typesafe_cb/typesafe_cb.h>
|
||||
|
||||
struct timeout {
|
||||
struct timer timer;
|
||||
struct timerel interval;
|
||||
void (*cb)(void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
struct lightningd_state;
|
||||
|
||||
void init_timeout_(struct timeout *t, unsigned int interval,
|
||||
void (*cb)(void *), void *arg);
|
||||
|
||||
void refresh_timeout(struct lightningd_state *dstate, struct timeout *t);
|
||||
|
||||
#define init_timeout(t, interval, func, arg) \
|
||||
init_timeout_((t), (interval), \
|
||||
typesafe_cb(void, void *, (func), (arg)), (arg))
|
||||
|
||||
/* tal_free this to disable timer. */
|
||||
struct oneshot *oneshot_timeout_(struct lightningd_state *dstate,
|
||||
const tal_t *ctx, unsigned int seconds,
|
||||
void (*cb)(void *), void *arg);
|
||||
struct oneshot *new_reltimer_(struct lightningd_state *dstate,
|
||||
const tal_t *ctx,
|
||||
struct timerel expire,
|
||||
void (*cb)(void *), void *arg);
|
||||
|
||||
#define oneshot_timeout(dstate, ctx, interval, func, arg) \
|
||||
oneshot_timeout_((dstate), (ctx), (interval), \
|
||||
typesafe_cb(void, void *, (func), (arg)), (arg))
|
||||
#define new_reltimer(dstate, ctx, relexpire, func, arg) \
|
||||
new_reltimer_((dstate), (ctx), (relexpire), \
|
||||
typesafe_cb(void, void *, (func), (arg)), (arg))
|
||||
|
||||
struct oneshot *new_abstimer_(struct lightningd_state *dstate,
|
||||
const tal_t *ctx,
|
||||
struct timeabs expire,
|
||||
void (*cb)(void *), void *arg);
|
||||
|
||||
#define new_abstimer(dstate, ctx, absexpire, func, arg) \
|
||||
new_abstimer_((dstate), (ctx), (absexpire), \
|
||||
typesafe_cb(void, void *, (func), (arg)), (arg))
|
||||
|
||||
void timer_expired(struct lightningd_state *dstate, struct timer *timer);
|
||||
|
||||
#endif /* LIGHTNING_DAEMON_TIMEOUT_H */
|
||||
|
Loading…
Reference in New Issue
Block a user