mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
libplugin: simple timer support.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
c83066f8ed
commit
9b61c19a20
@ -4,6 +4,7 @@
|
||||
#include <ccan/read_write_all/read_write_all.h>
|
||||
#include <ccan/strmap/strmap.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <ccan/timer/timer.h>
|
||||
#include <common/daemon.h>
|
||||
#include <common/utils.h>
|
||||
#include <errno.h>
|
||||
@ -26,8 +27,17 @@ static u64 next_outreq_id;
|
||||
* struct json_command as it's good practice to have those const. */
|
||||
static STRMAP(const char *) usagemap;
|
||||
|
||||
/* Timers */
|
||||
static struct timers timers;
|
||||
static bool in_timer;
|
||||
|
||||
bool deprecated_apis;
|
||||
|
||||
struct plugin_timer {
|
||||
struct timer timer;
|
||||
struct command_result *(*cb)(void);
|
||||
};
|
||||
|
||||
struct plugin_conn {
|
||||
int fd;
|
||||
MEMBUF(char) mb;
|
||||
@ -232,6 +242,13 @@ command_done_raw(struct command *cmd,
|
||||
return end_cmd(cmd);
|
||||
}
|
||||
|
||||
struct command_result *timer_complete(void)
|
||||
{
|
||||
assert(in_timer);
|
||||
in_timer = false;
|
||||
return &complete;
|
||||
}
|
||||
|
||||
struct command_result *command_success(struct command *cmd, const char *result)
|
||||
{
|
||||
return command_done_raw(cmd, "result", result, strlen(result));
|
||||
@ -582,6 +599,31 @@ static void setup_command_usage(const struct plugin_command *commands,
|
||||
}
|
||||
}
|
||||
|
||||
static void call_plugin_timer(struct plugin_conn *rpc, struct timer *timer)
|
||||
{
|
||||
struct plugin_timer *t = container_of(timer, struct plugin_timer, timer);
|
||||
|
||||
in_timer = true;
|
||||
t->cb();
|
||||
tal_free(t);
|
||||
}
|
||||
|
||||
static void destroy_plugin_timer(struct plugin_timer *timer)
|
||||
{
|
||||
timer_del(&timers, &timer->timer);
|
||||
}
|
||||
|
||||
struct plugin_timer *plugin_timer(struct plugin_conn *rpc, struct timerel t,
|
||||
struct command_result *(*cb)(void))
|
||||
{
|
||||
struct plugin_timer *timer = tal(NULL, struct plugin_timer);
|
||||
timer->cb = cb;
|
||||
timer_init(&timer->timer);
|
||||
timer_addrel(&timers, &timer->timer, t);
|
||||
tal_add_destructor(timer, destroy_plugin_timer);
|
||||
return timer;
|
||||
}
|
||||
|
||||
void plugin_main(char *argv[],
|
||||
void (*init)(struct plugin_conn *rpc),
|
||||
const struct plugin_command *commands,
|
||||
@ -606,6 +648,7 @@ void plugin_main(char *argv[],
|
||||
|
||||
setup_command_usage(commands, num_commands);
|
||||
|
||||
timers_init(&timers, time_mono());
|
||||
membuf_init(&rpc_conn.mb,
|
||||
tal_arr(ctx, char, READ_CHUNKSIZE), READ_CHUNKSIZE,
|
||||
membuf_tal_realloc);
|
||||
@ -650,6 +693,10 @@ void plugin_main(char *argv[],
|
||||
fds[1].events = POLLIN;
|
||||
|
||||
for (;;) {
|
||||
struct timer *expired;
|
||||
struct timemono now, first;
|
||||
int t;
|
||||
|
||||
clean_tmpctx();
|
||||
|
||||
/* If we already have some input, process now. */
|
||||
@ -663,8 +710,22 @@ void plugin_main(char *argv[],
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle any timeouts */
|
||||
now = time_mono();
|
||||
expired = timers_expire(&timers, now);
|
||||
if (expired) {
|
||||
call_plugin_timer(&rpc_conn, expired);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If we have a pending timer, timeout then */
|
||||
if (timer_earliest(&timers, &first))
|
||||
t = time_to_msec(timemono_between(first, now));
|
||||
else
|
||||
t = -1;
|
||||
|
||||
/* Otherwise, we poll. */
|
||||
poll(fds, 2, -1);
|
||||
poll(fds, 2, t);
|
||||
|
||||
if (fds[0].revents & POLLIN)
|
||||
handle_new_command(ctx, &request_conn, &rpc_conn,
|
||||
|
@ -55,7 +55,9 @@ const char *rpc_delve(const tal_t *ctx,
|
||||
const char *method, const char *params,
|
||||
struct plugin_conn *rpc, const char *guide);
|
||||
|
||||
/* Async rpc request. For convenience, and single ' are turned into ". */
|
||||
/* Async rpc request. For convenience, and single ' are turned into ".
|
||||
* @cmd can be NULL if we're coming from a timer callback.
|
||||
*/
|
||||
PRINTF_FMT(6,7) struct command_result *
|
||||
send_outreq_(struct command *cmd,
|
||||
const char *method,
|
||||
@ -96,6 +98,17 @@ struct command_result *forward_result(struct command *cmd,
|
||||
const jsmntok_t *result,
|
||||
void *arg);
|
||||
|
||||
/* Callback for timer where we expect a 'command_result'. */
|
||||
struct command_result *timer_complete(void);
|
||||
|
||||
/* Access timer infrastructure to add a timer.
|
||||
*
|
||||
* Freeing this releases the timer (don't free it in timer cb though)
|
||||
*/
|
||||
struct plugin_timer *plugin_timer(struct plugin_conn *rpc,
|
||||
struct timerel t,
|
||||
struct command_result *(*cb)(void));
|
||||
|
||||
/* Macro to define arguments */
|
||||
#define plugin_option(name, description, set, arg) \
|
||||
(name), \
|
||||
|
Loading…
Reference in New Issue
Block a user