Description
(*http.Transport).getConn
currently starts a dialConn
call in a background goroutine:
Lines 942 to 945 in 0b0cc41
That records traces to the provided Context
and eventually invokes t.DialContext
with it:
Line 1029 in 0b0cc41
Line 1060 in 0b0cc41
This is pretty much a textbook illustration of the problem described in #19643 (Context API for continuing work). If (*Transport).getConn
returns early (due to cancellation or to availability of an idle connection), the caller may have already written out the corresponding traces, and dialConn
(and/or the user-provided DialContext
callback) will unexpectedly access a Context
that the caller believes to be unreachable.
httptrace.ClientTrace
says, "Functions may be called concurrently from different goroutines and some may be called after the request has completed or failed." However, that is not true of Context
instances in general: if the http
package wants to save a trace after a call has returned, it should call Value
ahead of time and save only the ClientTrace
pointer. If dialConn
calls a user-provided DialContext
function, then getConn
should cancel the Context
passed to it and wait for DialContext
to return before itself returning.
See also #20617 (Context race in http.Transport
).