From ffa170dc4aa6c659d11a6c06722c1e07af416dfc Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Mon, 28 Feb 2022 11:03:25 -0500 Subject: [PATCH] internal/jsonrpc2_v2: fix a racy map assignment in readIncoming If a call request comes it at the same time that a response becomes ready for another call (either via an explicit Respond call or the return from a Handle call), the map read and deletion for the response could race with the map assignment for the new (incoming) call. Change-Id: Ifd81dbc490486251e81c7eeae438806356f514af Reviewed-on: https://go-review.googlesource.com/c/tools/+/388595 Trust: Bryan Mills Run-TryBot: Bryan Mills Reviewed-by: Ian Cottrell gopls-CI: kokoro TryBot-Result: Gopher Robot --- internal/jsonrpc2_v2/conn.go | 2 +- internal/jsonrpc2_v2/jsonrpc2_test.go | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/jsonrpc2_v2/conn.go b/internal/jsonrpc2_v2/conn.go index 7d492c402d..d60b6c5521 100644 --- a/internal/jsonrpc2_v2/conn.go +++ b/internal/jsonrpc2_v2/conn.go @@ -322,8 +322,8 @@ func (c *Connection) readIncoming(ctx context.Context, reader Reader, toQueue ch // cancelled by id if msg.IsCall() { pending := <-c.incomingBox - c.incomingBox <- pending pending[msg.ID] = entry + c.incomingBox <- pending } // send the message to the incoming queue toQueue <- entry diff --git a/internal/jsonrpc2_v2/jsonrpc2_test.go b/internal/jsonrpc2_v2/jsonrpc2_test.go index 1157779f3b..4f4b7d9b9f 100644 --- a/internal/jsonrpc2_v2/jsonrpc2_test.go +++ b/internal/jsonrpc2_v2/jsonrpc2_test.go @@ -60,6 +60,14 @@ var callTests = []invoker{ notify{"unblock", "a"}, collect{"a", true, false}, }}, + sequence{"concurrent", []invoker{ + async{"a", "fork", "a"}, + notify{"unblock", "a"}, + async{"b", "fork", "b"}, + notify{"unblock", "b"}, + collect{"a", true, false}, + collect{"b", true, false}, + }}, } type binder struct {