diff --git a/lightningd/Makefile b/lightningd/Makefile index eb37128f4..ffee6cda7 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -32,6 +32,7 @@ LIGHTNINGD_COMMON_OBJS := \ common/htlc_state.o \ common/htlc_wire.o \ common/key_derive.o \ + common/io_lock.o \ common/json.o \ common/json_escaped.o \ common/memleak.o \ @@ -121,7 +122,7 @@ check-makefile: check-lightningd-makefile check-lightningd-makefile: @for f in lightningd/*.h lightningd/*/*.h; do if ! echo $(LIGHTNINGD_HEADERS_NOGEN) $(LIGHTNINGD_HEADERS_GEN) "" | grep -q "$$f "; then echo $$f not mentioned in LIGHTNINGD_HEADERS_NOGEN or LIGHTNINGD_HEADERS_GEN >&2; exit 1; fi; done -lightningd/lightningd: $(LIGHTNINGD_OBJS) $(LIGHTNINGD_COMMON_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(WIRE_ONION_OBJS) $(LIGHTNINGD_HANDSHAKE_CONTROL_OBJS) $(LIGHTNINGD_GOSSIP_CONTROL_OBJS) $(LIGHTNINGD_OPENING_CONTROL_OBJS) $(LIGHTNINGD_CHANNEL_CONTROL_OBJS) $(LIGHTNINGD_CLOSING_CONTROL_OBJS) $(LIGHTNINGD_ONCHAIN_CONTROL_OBJS) $(WALLET_LIB_OBJS) $(LIGHTNINGD_CONNECT_CONTROL_OBJS) +lightningd/lightningd: $(LIGHTNINGD_OBJS) $(LIGHTNINGD_COMMON_OBJS) $(BITCOIN_OBJS) $(WIRE_OBJS) $(WIRE_ONION_OBJS) $(LIGHTNINGD_HANDSHAKE_CONTROL_OBJS) $(LIGHTNINGD_GOSSIP_CONTROL_OBJS) $(LIGHTNINGD_OPENING_CONTROL_OBJS) $(LIGHTNINGD_CHANNEL_CONTROL_OBJS) $(LIGHTNINGD_CLOSING_CONTROL_OBJS) $(LIGHTNINGD_ONCHAIN_CONTROL_OBJS) $(WALLET_LIB_OBJS) $(LIGHTNINGD_CONNECT_CONTROL_OBJS) clean: lightningd-clean diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 66251f264..bbdcb3d42 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -510,6 +510,9 @@ static void parse_request(struct json_connection *jcon, const jsmntok_t tok[]) assert(c->pending); } +static struct io_plan *locked_write_json(struct io_conn *conn, + struct json_connection *jcon); + static struct io_plan *write_json(struct io_conn *conn, struct json_connection *jcon) { @@ -524,8 +527,9 @@ static struct io_plan *write_json(struct io_conn *conn, return io_close(conn); } + io_lock_release(jcon->lock); /* Wait for more output. */ - return io_out_wait(conn, jcon, write_json, jcon); + return io_out_wait(conn, jcon, locked_write_json, jcon); } jcon->outbuf = tal_steal(jcon, out->json); @@ -536,6 +540,12 @@ static struct io_plan *write_json(struct io_conn *conn, jcon->outbuf, strlen(jcon->outbuf), write_json, jcon); } +static struct io_plan *locked_write_json(struct io_conn *conn, + struct json_connection *jcon) +{ + return io_lock_acquire_out(conn, jcon->lock, write_json, jcon); +} + static struct io_plan *read_json(struct io_conn *conn, struct json_connection *jcon) { @@ -600,6 +610,7 @@ static struct io_plan *jcon_connected(struct io_conn *conn, jcon->used = 0; jcon->buffer = tal_arr(jcon, char, 64); jcon->stop = false; + jcon->lock = io_lock_new(jcon); list_head_init(&jcon->commands); /* We want to log on destruction, so we free this in destructor. */ @@ -613,7 +624,7 @@ static struct io_plan *jcon_connected(struct io_conn *conn, io_read_partial(conn, jcon->buffer, tal_count(jcon->buffer), &jcon->len_read, read_json, jcon), - write_json(conn, jcon)); + locked_write_json(conn, jcon)); } static struct io_plan *incoming_jcon_connected(struct io_conn *conn, diff --git a/lightningd/jsonrpc.h b/lightningd/jsonrpc.h index f94f243a9..b7ca5c028 100644 --- a/lightningd/jsonrpc.h +++ b/lightningd/jsonrpc.h @@ -4,6 +4,7 @@ #include #include #include +#include #include struct bitcoin_txid; @@ -64,6 +65,7 @@ struct json_connection { struct list_head output; const char *outbuf; + struct io_lock *lock; }; struct json_command {