mirror of
https://github.com/golang/go
synced 2024-11-17 18:54:42 -07:00
net/http: clear reference to the request context after transport getConn
Clears wannConn ctx and prevents pending dialConnFor after connection delivered or canceled.
Updates #50798
Change-Id: I9a681ac0f222be56571fa768700220f6b5ee0888
GitHub-Last-Rev: fd6c83ab07
GitHub-Pull-Request: golang/go#61524
Reviewed-on: https://go-review.googlesource.com/c/go/+/512196
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
c738344171
commit
38a0c5bdb4
@ -1205,7 +1205,6 @@ func (t *Transport) dial(ctx context.Context, network, addr string) (net.Conn, e
|
||||
type wantConn struct {
|
||||
cm connectMethod
|
||||
key connectMethodKey // cm.key()
|
||||
ctx context.Context // context for dial
|
||||
ready chan struct{} // closed when pc, err pair is delivered
|
||||
|
||||
// hooks for testing to know when dials are done
|
||||
@ -1214,7 +1213,8 @@ type wantConn struct {
|
||||
beforeDial func()
|
||||
afterDial func()
|
||||
|
||||
mu sync.Mutex // protects pc, err, close(ready)
|
||||
mu sync.Mutex // protects ctx, pc, err, close(ready)
|
||||
ctx context.Context // context for dial, cleared after delivered or canceled
|
||||
pc *persistConn
|
||||
err error
|
||||
}
|
||||
@ -1229,6 +1229,13 @@ func (w *wantConn) waiting() bool {
|
||||
}
|
||||
}
|
||||
|
||||
// getCtxForDial returns context for dial or nil if connection was delivered or canceled.
|
||||
func (w *wantConn) getCtxForDial() context.Context {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
return w.ctx
|
||||
}
|
||||
|
||||
// tryDeliver attempts to deliver pc, err to w and reports whether it succeeded.
|
||||
func (w *wantConn) tryDeliver(pc *persistConn, err error) bool {
|
||||
w.mu.Lock()
|
||||
@ -1238,6 +1245,7 @@ func (w *wantConn) tryDeliver(pc *persistConn, err error) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
w.ctx = nil
|
||||
w.pc = pc
|
||||
w.err = err
|
||||
if w.pc == nil && w.err == nil {
|
||||
@ -1255,6 +1263,7 @@ func (w *wantConn) cancel(t *Transport, err error) {
|
||||
close(w.ready) // catch misbehavior in future delivery
|
||||
}
|
||||
pc := w.pc
|
||||
w.ctx = nil
|
||||
w.pc = nil
|
||||
w.err = err
|
||||
w.mu.Unlock()
|
||||
@ -1463,8 +1472,12 @@ func (t *Transport) queueForDial(w *wantConn) {
|
||||
// If the dial is canceled or unsuccessful, dialConnFor decrements t.connCount[w.cm.key()].
|
||||
func (t *Transport) dialConnFor(w *wantConn) {
|
||||
defer w.afterDial()
|
||||
ctx := w.getCtxForDial()
|
||||
if ctx == nil {
|
||||
return
|
||||
}
|
||||
|
||||
pc, err := t.dialConn(w.ctx, w.cm)
|
||||
pc, err := t.dialConn(ctx, w.cm)
|
||||
delivered := w.tryDeliver(pc, err)
|
||||
if err == nil && (!delivered || pc.alt != nil) {
|
||||
// pconn was not passed to w,
|
||||
|
Loading…
Reference in New Issue
Block a user