libplugin: don't wait for clean_tmpctx() to free requests as we process them.

xpay is relying on the destructor to send another request.  This means
that it doesn't actually submit the request until *next time* we wake.

This has been in xpay from the start, but it is not noticeable until
xpay stops subscribing to every command on the rpc_command hook.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2025-11-20 12:07:13 +10:30
parent ebe5f2e68f
commit 1d4a1cdd8a

View File

@@ -1018,7 +1018,8 @@ static void destroy_cmd_mark_freed(struct command *cmd, bool *cmd_freed)
*cmd_freed = true;
}
static void handle_rpc_reply(struct plugin *plugin, const char *buf, const jsmntok_t *toks)
static void handle_rpc_reply(const tal_t *working_ctx,
struct plugin *plugin, const char *buf, const jsmntok_t *toks)
{
const jsmntok_t *idtok, *contenttok;
struct out_req *out;
@@ -1042,7 +1043,7 @@ static void handle_rpc_reply(struct plugin *plugin, const char *buf, const jsmnt
}
/* We want to free this if callback doesn't. */
tal_steal(tmpctx, out);
tal_steal(working_ctx, out);
/* If they return complete, cmd should have been freed! */
cmd_freed = false;
@@ -1356,6 +1357,8 @@ static void rpc_conn_finished(struct io_conn *conn,
static struct io_plan *rpc_conn_read_response(struct io_conn *conn,
struct plugin *plugin)
{
const tal_t *working_ctx = tal(NULL, char);
/* Gather an parse any new bytes */
for (;;) {
const jsmntok_t *toks;
@@ -1371,10 +1374,14 @@ static struct io_plan *rpc_conn_read_response(struct io_conn *conn,
if (!toks)
break;
handle_rpc_reply(plugin, buf, toks);
handle_rpc_reply(working_ctx, plugin, buf, toks);
jsonrpc_io_parse_done(plugin->jsonrpc_in);
}
/* Explicitly free any expired requests now; xpay uses this to
* fire more commands! */
tal_free(working_ctx);
/* Read more */
return jsonrpc_io_read(conn, plugin->jsonrpc_in,
rpc_conn_read_response,