diff options
author | Felix Lange <fjl@twurst.com> | 2019-06-20 14:36:27 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2019-06-20 14:36:27 +0800 |
commit | 8d815e365cd2cda2e865dd2e272ebb5a3d4b8772 (patch) | |
tree | c23f4a67ec8446beb326346f899820b98621437e | |
parent | 3271a5afa0b3a8d65357347db65b45ddb91c5bcd (diff) | |
download | go-tangerine-8d815e365cd2cda2e865dd2e272ebb5a3d4b8772.tar go-tangerine-8d815e365cd2cda2e865dd2e272ebb5a3d4b8772.tar.gz go-tangerine-8d815e365cd2cda2e865dd2e272ebb5a3d4b8772.tar.bz2 go-tangerine-8d815e365cd2cda2e865dd2e272ebb5a3d4b8772.tar.lz go-tangerine-8d815e365cd2cda2e865dd2e272ebb5a3d4b8772.tar.xz go-tangerine-8d815e365cd2cda2e865dd2e272ebb5a3d4b8772.tar.zst go-tangerine-8d815e365cd2cda2e865dd2e272ebb5a3d4b8772.zip |
rpc: fix rare deadlock when canceling HTTP call context (#19715)
When cancelling the context for a call on a HTTP-based client while the
call is running, the select in requestOp.wait may hit the <-context.Done()
case instead of the <-op.resp case. This doesn't happen often -- our
cancel test hasn't caught this even though it ran thousands of times
on CI since the RPC client was added.
Fixes #19714
-rw-r--r-- | rpc/client.go | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/rpc/client.go b/rpc/client.go index 02029dc8f..16511747f 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -137,9 +137,11 @@ func (op *requestOp) wait(ctx context.Context, c *Client) (*jsonrpcMessage, erro select { case <-ctx.Done(): // Send the timeout to dispatch so it can remove the request IDs. - select { - case c.reqTimeout <- op: - case <-c.closing: + if !c.isHTTP { + select { + case c.reqTimeout <- op: + case <-c.closing: + } } return nil, ctx.Err() case resp := <-op.resp: |