mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-21 08:04:26 +01:00
subd: wrap all message callbacks in a transaction.
Including destructors. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
bbe7a03300
commit
3a596d6dda
@@ -20,6 +20,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <wallet/db.h>
|
||||||
#include <wire/wire.h>
|
#include <wire/wire.h>
|
||||||
#include <wire/wire_io.h>
|
#include <wire/wire_io.h>
|
||||||
|
|
||||||
@@ -411,20 +412,26 @@ static struct io_plan *sd_msg_read(struct io_conn *conn, struct subd *sd)
|
|||||||
int type = fromwire_peektype(sd->msg_in);
|
int type = fromwire_peektype(sd->msg_in);
|
||||||
const tal_t *tmpctx;
|
const tal_t *tmpctx;
|
||||||
struct subd_req *sr;
|
struct subd_req *sr;
|
||||||
|
struct db *db = sd->ld->wallet->db;
|
||||||
|
struct io_plan *plan;
|
||||||
|
|
||||||
if (type == -1) {
|
/* Everything we do, we wrap in a database transaction */
|
||||||
subdaemon_malformed_msg(sd, sd->msg_in);
|
db_begin_transaction(db);
|
||||||
return io_close(conn);
|
|
||||||
}
|
if (type == -1)
|
||||||
|
goto malformed;
|
||||||
|
|
||||||
/* First, check for replies. */
|
/* First, check for replies. */
|
||||||
sr = get_req(sd, type);
|
sr = get_req(sd, type);
|
||||||
if (sr) {
|
if (sr) {
|
||||||
if (sr->num_reply_fds && sd->fds_in == NULL)
|
if (sr->num_reply_fds && sd->fds_in == NULL) {
|
||||||
return sd_collect_fds(conn, sd, sr->num_reply_fds);
|
plan = sd_collect_fds(conn, sd, sr->num_reply_fds);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
assert(sr->num_reply_fds == tal_count(sd->fds_in));
|
assert(sr->num_reply_fds == tal_count(sd->fds_in));
|
||||||
return sd_msg_reply(conn, sd, sr);
|
plan = sd_msg_reply(conn, sd, sr);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If not stolen, we'll free this below. */
|
/* If not stolen, we'll free this below. */
|
||||||
@@ -434,24 +441,18 @@ static struct io_plan *sd_msg_read(struct io_conn *conn, struct subd *sd)
|
|||||||
if (type == STATUS_TRACE) {
|
if (type == STATUS_TRACE) {
|
||||||
int str_len;
|
int str_len;
|
||||||
const char *str = string_from_msg(sd->msg_in, &str_len);
|
const char *str = string_from_msg(sd->msg_in, &str_len);
|
||||||
if (!str) {
|
if (!str)
|
||||||
subdaemon_malformed_msg(sd, sd->msg_in);
|
goto malformed;
|
||||||
return io_close(conn);
|
|
||||||
}
|
|
||||||
log_debug(sd->log, "TRACE: %.*s", str_len, str);
|
log_debug(sd->log, "TRACE: %.*s", str_len, str);
|
||||||
goto next;
|
goto next;
|
||||||
} else if (type & STATUS_FAIL) {
|
} else if (type & STATUS_FAIL) {
|
||||||
int str_len;
|
int str_len;
|
||||||
const char *str = string_from_msg(sd->msg_in, &str_len);
|
const char *str = string_from_msg(sd->msg_in, &str_len);
|
||||||
if (!str) {
|
if (!str)
|
||||||
subdaemon_malformed_msg(sd, sd->msg_in);
|
goto malformed;
|
||||||
return io_close(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!log_status_fail(sd, type, str, str_len)) {
|
if (!log_status_fail(sd, type, str, str_len))
|
||||||
subdaemon_malformed_msg(sd, sd->msg_in);
|
goto malformed;
|
||||||
return io_close(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If they care, tell them about invalid peer behavior */
|
/* If they care, tell them about invalid peer behavior */
|
||||||
if (sd->peer && type == STATUS_FAIL_PEER_BAD) {
|
if (sd->peer && type == STATUS_FAIL_PEER_BAD) {
|
||||||
@@ -464,7 +465,7 @@ static struct io_plan *sd_msg_read(struct io_conn *conn, struct subd *sd)
|
|||||||
(u8 *)str, str_len,
|
(u8 *)str, str_len,
|
||||||
0)));
|
0)));
|
||||||
}
|
}
|
||||||
return io_close(conn);
|
goto close;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info(sd->log, "UPDATE %s", sd->msgname(type));
|
log_info(sd->log, "UPDATE %s", sd->msgname(type));
|
||||||
@@ -478,7 +479,7 @@ static struct io_plan *sd_msg_read(struct io_conn *conn, struct subd *sd)
|
|||||||
|
|
||||||
i = sd->msgcb(sd, sd->msg_in, sd->fds_in);
|
i = sd->msgcb(sd, sd->msg_in, sd->fds_in);
|
||||||
if (freed)
|
if (freed)
|
||||||
return io_close(conn);
|
goto close;
|
||||||
tal_del_destructor2(sd, mark_freed, &freed);
|
tal_del_destructor2(sd, mark_freed, &freed);
|
||||||
|
|
||||||
sd->conn = conn;
|
sd->conn = conn;
|
||||||
@@ -489,7 +490,8 @@ static struct io_plan *sd_msg_read(struct io_conn *conn, struct subd *sd)
|
|||||||
/* Don't free msg_in: we go around again. */
|
/* Don't free msg_in: we go around again. */
|
||||||
tal_steal(sd, sd->msg_in);
|
tal_steal(sd, sd->msg_in);
|
||||||
tal_free(tmpctx);
|
tal_free(tmpctx);
|
||||||
return sd_collect_fds(conn, sd, i);
|
plan = sd_collect_fds(conn, sd, i);
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,9 +499,20 @@ next:
|
|||||||
sd->msg_in = NULL;
|
sd->msg_in = NULL;
|
||||||
sd->fds_in = tal_free(sd->fds_in);
|
sd->fds_in = tal_free(sd->fds_in);
|
||||||
tal_free(tmpctx);
|
tal_free(tmpctx);
|
||||||
return io_read_wire(conn, sd, &sd->msg_in, sd_msg_read, sd);
|
|
||||||
|
plan = io_read_wire(conn, sd, &sd->msg_in, sd_msg_read, sd);
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
malformed:
|
||||||
|
subdaemon_malformed_msg(sd, sd->msg_in);
|
||||||
|
close:
|
||||||
|
plan = io_close(conn);
|
||||||
|
out:
|
||||||
|
db_commit_transaction(db);
|
||||||
|
return plan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void destroy_subd(struct subd *sd)
|
static void destroy_subd(struct subd *sd)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ struct subd {
|
|||||||
/* For logging */
|
/* For logging */
|
||||||
struct log *log;
|
struct log *log;
|
||||||
|
|
||||||
/* Callback when non-reply message comes in. */
|
/* Callback when non-reply message comes in (inside db transaction) */
|
||||||
unsigned (*msgcb)(struct subd *, const u8 *, const int *);
|
unsigned (*msgcb)(struct subd *, const u8 *, const int *);
|
||||||
const char *(*msgname)(int msgtype);
|
const char *(*msgname)(int msgtype);
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ struct subd {
|
|||||||
* @ld: global state
|
* @ld: global state
|
||||||
* @name: basename of daemon
|
* @name: basename of daemon
|
||||||
* @msgname: function to get name from messages
|
* @msgname: function to get name from messages
|
||||||
* @msgcb: function to call when non-fatal message received (or NULL)
|
* @msgcb: function to call (inside db transaction) when non-fatal message received (or NULL)
|
||||||
* @...: NULL-terminated list of pointers to fds to hand as fd 3, 4...
|
* @...: NULL-terminated list of pointers to fds to hand as fd 3, 4...
|
||||||
* (can be take, if so, set to -1)
|
* (can be take, if so, set to -1)
|
||||||
*
|
*
|
||||||
@@ -78,7 +78,7 @@ struct subd *new_global_subd(struct lightningd *ld,
|
|||||||
* @name: basename of daemon
|
* @name: basename of daemon
|
||||||
* @peer: peer to associate.
|
* @peer: peer to associate.
|
||||||
* @msgname: function to get name from messages
|
* @msgname: function to get name from messages
|
||||||
* @msgcb: function to call when non-fatal message received (or NULL)
|
* @msgcb: function to call (inside db transaction) when non-fatal message received (or NULL)
|
||||||
* @...: NULL-terminated list of pointers to fds to hand as fd 3, 4...
|
* @...: NULL-terminated list of pointers to fds to hand as fd 3, 4...
|
||||||
* (can be take, if so, set to -1)
|
* (can be take, if so, set to -1)
|
||||||
*
|
*
|
||||||
@@ -122,7 +122,7 @@ void subd_send_fd(struct subd *sd, int fd);
|
|||||||
* @msg_out: request message (can be take)
|
* @msg_out: request message (can be take)
|
||||||
* @fd_out: if >=0 fd to pass at the end of the message (closed after)
|
* @fd_out: if >=0 fd to pass at the end of the message (closed after)
|
||||||
* @num_fds_in: how many fds to read in to hand to @replycb if it's a reply.
|
* @num_fds_in: how many fds to read in to hand to @replycb if it's a reply.
|
||||||
* @replycb: callback when reply comes in (can free subd)
|
* @replycb: callback (inside db transaction) when reply comes in (can free subd)
|
||||||
* @replycb_data: final arg to hand to @replycb
|
* @replycb_data: final arg to hand to @replycb
|
||||||
*
|
*
|
||||||
* @replycb cannot free @sd, so it returns false to remove it.
|
* @replycb cannot free @sd, so it returns false to remove it.
|
||||||
|
|||||||
Reference in New Issue
Block a user