libplugin: add aux_command.

Sometimes we want to clean up *after* a command has completed, but
we're moving to a model where all libplugin operations require a
`struct command`.  This adds `aux_command` to create an
independent-lifetime command with the same id.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2024-11-06 21:19:36 +10:30
parent c85dd95c12
commit 606aab6f55
2 changed files with 57 additions and 9 deletions

View File

@ -190,6 +190,31 @@ static void complain_deprecated_nocmd(const char *feature,
}
}
/* New command, without a filter */
static struct command *new_command(const tal_t *ctx,
struct plugin *plugin,
const char *id TAKES,
const char *methodname TAKES,
bool usage_only,
bool check)
{
struct command *cmd = tal(ctx, struct command);
cmd->plugin = plugin;
cmd->usage_only = usage_only;
cmd->check = check;
cmd->filter = NULL;
cmd->methodname = tal_strdup(cmd, methodname);
if (id) {
cmd->id = tal_strdup(cmd, id);
} else {
/* Might be taken, even if NULL */
taken(id);
cmd->id = NULL;
}
return cmd;
}
bool command_deprecated_in_nocmd_ok(struct plugin *plugin,
const char *name,
const char *depr_start,
@ -1630,11 +1655,11 @@ bool flag_jsonfmt(struct plugin *plugin, struct json_stream *js, const char *fie
static void setup_command_usage(struct plugin *p)
{
struct command *usage_cmd = tal(tmpctx, struct command);
struct command *usage_cmd = new_command(tmpctx, p, "usage",
"check-usage",
true, false);
/* This is how common/param can tell it's just a usage request */
usage_cmd->usage_only = true;
usage_cmd->plugin = p;
for (size_t i = 0; i < p->num_commands; i++) {
struct command_result *res;
@ -1881,6 +1906,7 @@ static void ld_command_handle(struct plugin *plugin,
const jsmntok_t *toks)
{
const jsmntok_t *methtok, *paramstok, *filtertok;
const char *methodname;
struct command *cmd;
methtok = json_get_member(plugin->buffer, toks, "method");
@ -1893,12 +1919,11 @@ static void ld_command_handle(struct plugin *plugin,
json_tok_full_len(toks),
json_tok_full(plugin->buffer, toks));
cmd = tal(plugin, struct command);
cmd->plugin = plugin;
cmd->usage_only = false;
cmd->filter = NULL;
cmd->methodname = json_strdup(cmd, plugin->buffer, methtok);
cmd->id = json_get_id(cmd, plugin->buffer, toks);
methodname = json_strdup(NULL, plugin->buffer, methtok);
cmd = new_command(plugin, plugin,
take(json_get_id(NULL, plugin->buffer, toks)),
take(methodname),
false, streq(methodname, "check"));
if (!plugin->manifested) {
if (streq(cmd->methodname, "getmanifest")) {
@ -2507,6 +2532,20 @@ command_hook_success(struct command *cmd)
return command_finished(cmd, response);
}
struct command *aux_command(const struct command *cmd)
{
assert(!cmd->check);
return new_command(cmd->plugin, cmd->plugin, cmd->id,
cmd->methodname, false, false);
}
struct command_result *WARN_UNUSED_RESULT
aux_command_done(struct command *cmd)
{
tal_free(cmd);
return &complete;
}
struct command_result *WARN_UNUSED_RESULT
notification_handled(struct command *cmd)
{

View File

@ -190,6 +190,11 @@ struct out_req *add_to_batch(struct command *cmd,
struct request_batch *batch,
const char *cmdname);
/* We want some commands to live after this command (possibly)
* completes. This creates a new command with the same id but its own
* lifetime: use aux_command_done() or tal_free() when you're done. */
struct command *aux_command(const struct command *cmd);
/* Runs finalcb immediately if batch is empty. */
struct command_result *batch_done(struct command *cmd,
struct request_batch *batch);
@ -355,6 +360,10 @@ command_hook_success(struct command *cmd);
struct command_result *WARN_UNUSED_RESULT
notification_handled(struct command *cmd);
/* End a command created with aux_command. */
struct command_result *WARN_UNUSED_RESULT
aux_command_done(struct command *cmd);
/**
* What's the deprecation_ok state for this cmd?
* @cmd: the command.