From 313cf39d4ac368181bce6960ac9be9e7cee67e68 Mon Sep 17 00:00:00 2001 From: Mikio Hara Date: Wed, 8 Jun 2016 05:04:34 +0900 Subject: [PATCH] http2: fix data race on pipe Fixes golang/go#15999. Change-Id: I20793ce717c768557c4942ff6be4e77c23ab201c Reviewed-on: https://go-review.googlesource.com/23880 Run-TryBot: Mikio Hara TryBot-Result: Gobot Gobot Reviewed-by: Andrew Gerrand --- http2/pipe.go | 6 ++++++ http2/transport.go | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/http2/pipe.go b/http2/pipe.go index 69446e7a..53b7a1da 100644 --- a/http2/pipe.go +++ b/http2/pipe.go @@ -29,6 +29,12 @@ type pipeBuffer interface { io.Reader } +func (p *pipe) Len() int { + p.mu.Lock() + defer p.mu.Unlock() + return p.b.Len() +} + // Read waits until data is available and copies bytes // from the buffer into p. func (p *pipe) Read(d []byte) (n int, err error) { diff --git a/http2/transport.go b/http2/transport.go index 2a4abfa5..060471ed 100644 --- a/http2/transport.go +++ b/http2/transport.go @@ -1462,7 +1462,7 @@ func (b transportResponseBody) Read(p []byte) (n int, err error) { // Consider any buffered body data (read from the conn but not // consumed by the client) when computing flow control for this // stream. - v := int(cs.inflow.available()) + cs.bufPipe.b.Len() + v := int(cs.inflow.available()) + cs.bufPipe.Len() if v < transportDefaultStreamFlow-transportDefaultStreamMinRefresh { streamAdd = int32(transportDefaultStreamFlow - v) cs.inflow.add(streamAdd)