summaryrefslogtreecommitdiff
path: root/src/pkg/net/http/transport.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2012-02-14 12:48:56 +1100
committerBrad Fitzpatrick <bradfitz@golang.org>2012-02-14 12:48:56 +1100
commitb3b43752b70fcb5e97361a810315469c65becfd6 (patch)
treef14174d874516abcce051251e2219792cc97ac38 /src/pkg/net/http/transport.go
parent6dd31594b8bd0b82a65ec7e2ef5095ab897c7ae8 (diff)
downloadgo-b3b43752b70fcb5e97361a810315469c65becfd6.tar.gz
net/http: fix client goroutine leak with persistent connections
Thanks to Sascha Matzke & Florian Weimer for diagnosing. R=golang-dev, adg, bradfitz, kevlar CC=golang-dev http://codereview.appspot.com/5656046
Diffstat (limited to 'src/pkg/net/http/transport.go')
-rw-r--r--src/pkg/net/http/transport.go21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/pkg/net/http/transport.go b/src/pkg/net/http/transport.go
index 510e55b05..3e48abafb 100644
--- a/src/pkg/net/http/transport.go
+++ b/src/pkg/net/http/transport.go
@@ -235,15 +235,19 @@ func (cm *connectMethod) proxyAuth() string {
return ""
}
-func (t *Transport) putIdleConn(pconn *persistConn) {
+// putIdleConn adds pconn to the list of idle persistent connections awaiting
+// a new request.
+// If pconn is no longer needed or not in a good state, putIdleConn
+// returns false.
+func (t *Transport) putIdleConn(pconn *persistConn) bool {
t.lk.Lock()
defer t.lk.Unlock()
if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 {
pconn.close()
- return
+ return false
}
if pconn.isBroken() {
- return
+ return false
}
key := pconn.cacheKey
max := t.MaxIdleConnsPerHost
@@ -252,9 +256,10 @@ func (t *Transport) putIdleConn(pconn *persistConn) {
}
if len(t.idleConn[key]) >= max {
pconn.close()
- return
+ return false
}
t.idleConn[key] = append(t.idleConn[key], pconn)
+ return true
}
func (t *Transport) getIdleConn(cm *connectMethod) (pconn *persistConn) {
@@ -565,7 +570,9 @@ func (pc *persistConn) readLoop() {
lastbody = resp.Body
waitForBodyRead = make(chan bool)
resp.Body.(*bodyEOFSignal).fn = func() {
- pc.t.putIdleConn(pc)
+ if !pc.t.putIdleConn(pc) {
+ alive = false
+ }
waitForBodyRead <- true
}
} else {
@@ -578,7 +585,9 @@ func (pc *persistConn) readLoop() {
// read it (even though it'll just be 0, EOF).
lastbody = nil
- pc.t.putIdleConn(pc)
+ if !pc.t.putIdleConn(pc) {
+ alive = false
+ }
}
}