From: Dave Cheney Date: Tue, 21 Aug 2012 01:18:16 +0000 (+1000) Subject: net/http: fix send on close channel error X-Git-Tag: go1.1rc2~2616 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2bdc60f8e71aabafccb1c414a7732a265faac3dd;p=gostls13.git net/http: fix send on close channel error Fixes #3793. Tested using GOMAXPROCS=81 which was able to trigger a panic in TestStressSurpriseServerCloses continually on a Core i5. R=fullung, bradfitz CC=golang-dev https://golang.org/cl/6445069 --- diff --git a/src/pkg/net/http/transport.go b/src/pkg/net/http/transport.go index 00509acd44..fe6318824e 100644 --- a/src/pkg/net/http/transport.go +++ b/src/pkg/net/http/transport.go @@ -538,7 +538,6 @@ func remoteSideClosed(err error) bool { func (pc *persistConn) readLoop() { defer close(pc.closech) - defer close(pc.writech) alive := true var lastbody io.ReadCloser // last response body, if any, read on this connection @@ -640,19 +639,24 @@ func (pc *persistConn) readLoop() { } func (pc *persistConn) writeLoop() { - for wr := range pc.writech { - if pc.isBroken() { - wr.ch <- errors.New("http: can't write HTTP request on broken connection") - continue - } - err := wr.req.Request.write(pc.bw, pc.isProxy, wr.req.extra) - if err == nil { - err = pc.bw.Flush() - } - if err != nil { - pc.markBroken() + for { + select { + case wr := <-pc.writech: + if pc.isBroken() { + wr.ch <- errors.New("http: can't write HTTP request on broken connection") + continue + } + err := wr.req.Request.write(pc.bw, pc.isProxy, wr.req.extra) + if err == nil { + err = pc.bw.Flush() + } + if err != nil { + pc.markBroken() + } + wr.ch <- err + case <-pc.closech: + return } - wr.ch <- err } }