From 1af6262822e50532d96479b3ce43d10f46694f3d Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Sat, 11 Mar 2017 15:20:37 +0100 Subject: [PATCH] connection: Added callback when the queue is cleared This allows us to break out of the normal queue-based write loop and handle things ourself for a while. Currently this is used to trigger regular gossip dumps that do not proceed until the buffers have been cleared in order to avoid memory-explosions. --- lightningd/connection.c | 12 ++++++++---- lightningd/connection.h | 21 ++++++++++++++++++--- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lightningd/connection.c b/lightningd/connection.c index d527a0d0e..1e69e6bf9 100644 --- a/lightningd/connection.c +++ b/lightningd/connection.c @@ -17,8 +17,8 @@ static const u8 *daemon_conn_dequeue(struct daemon_conn *dc) if (n == 0) return NULL; msg = dc->msg_out[0]; - memmove(dc->msg_out, dc->msg_out + 1, sizeof(dc->msg_in[0]) * (n-1)); - tal_resize(&dc->msg_out, n-1); + memmove(dc->msg_out, dc->msg_out + 1, sizeof(dc->msg_in[0]) * (n - 1)); + tal_resize(&dc->msg_out, n - 1); return msg; } @@ -30,12 +30,15 @@ struct io_plan *daemon_conn_read_next(struct io_conn *conn, dc); } -static struct io_plan *daemon_conn_write_next(struct io_conn *conn, +struct io_plan *daemon_conn_write_next(struct io_conn *conn, struct daemon_conn *dc) { const u8 *msg = daemon_conn_dequeue(dc); if (msg) { - return io_write_wire(conn, take(msg), daemon_conn_write_next, dc); + return io_write_wire(conn, take(msg), daemon_conn_write_next, + dc); + } else if (dc->msg_queue_cleared_cb) { + return dc->msg_queue_cleared_cb(conn, dc); } else { return io_out_wait(conn, dc, daemon_conn_write_next, dc); } @@ -59,6 +62,7 @@ void daemon_conn_init(tal_t *ctx, struct daemon_conn *dc, int fd, dc->msg_in = NULL; dc->msg_out = tal_arr(ctx, u8 *, 0); dc->conn_fd = fd; + dc->msg_queue_cleared_cb = NULL; io_new_conn(ctx, fd, daemon_conn_start, dc); } diff --git a/lightningd/connection.h b/lightningd/connection.h index c79cea32e..dd69bcf1e 100644 --- a/lightningd/connection.h +++ b/lightningd/connection.h @@ -20,7 +20,13 @@ struct daemon_conn { struct io_conn *conn; /* Callback for incoming messages */ - struct io_plan *(*daemon_conn_recv)(struct io_conn *conn, struct daemon_conn *); + struct io_plan *(*daemon_conn_recv)(struct io_conn *conn, + struct daemon_conn *); + + /* Called whenever we've cleared the msg_out queue. Used to + * inject things into the write loop */ + struct io_plan *(*msg_queue_cleared_cb)(struct io_conn *conn, + struct daemon_conn *); }; /** @@ -32,13 +38,22 @@ struct daemon_conn { * @daemon_conn_recv: callback function to be called upon receiving a message */ void daemon_conn_init(tal_t *ctx, struct daemon_conn *dc, int fd, - struct io_plan *(*daemon_conn_recv)(struct io_conn *, - struct daemon_conn *)); + struct io_plan *(*daemon_conn_recv)( + struct io_conn *, struct daemon_conn *)); /** * daemon_conn_send - Enqueue an outgoing message to be sent */ void daemon_conn_send(struct daemon_conn *dc, u8 *msg); +/** + * daemon_conn_write_next - Continue writing from the msg-queue + * + * Exposed here so that, if `msg_queue_cleared_cb` is used to break + * out of the write-loop, we can get back in. + */ +struct io_plan *daemon_conn_write_next(struct io_conn *conn, + struct daemon_conn *dc); + /** * daemon_conn_read_next - Read the next message */