Closed
Description
The documentation for httptrace says
// Functions may be
// called concurrently from different goroutines, starting after the
// call to Transport.RoundTrip and ending either when RoundTrip
// returns an error, or when the Response.Body is closed.
However, if RoundTrip is canceled or times out before t.dialConn completes, ConnectStart can be called concurrently with code that runs after RoundTrip returns an error.
https://golang.org/src/net/http/transport.go#L880
Here is a sample race found by TSAN:
WARNING: DATA RACE
Read at 0x00c420204418 by goroutine 98:
[in my code that reads the final trace struct after RoundTrip has returned an error]
Previous write at 0x00c420204418 by goroutine 100:
[in my implementation of ConnectStart]
net.dialSingle()
go/gc/src/net/dial.go:511 +0xde5
net.dialSerial()
go/gc/src/net/dial.go:489 +0x245
net.(*Dialer).DialContext()
go/gc/src/net/dial.go:371 +0x977
[some frames redacted]
net/http.(*Transport).dial()
go/gc/src/net/http/transport.go:821 +0xe3
net/http.(*Transport).dialConn()
go/gc/src/net/http/transport.go:962 +0x242a
net/http.(*Transport).getConn.func4()
go/gc/src/net/http/transport.go:880 +0xa2
I'm not sure if this is a documentation bug or a code bug. The only way to implement the documentation faithfully is to either (a) prevent calling hooks after the conditions specified in the doc have been reached, or (b) wait for the background t.dialConn to complete before returning from RoundTrip with an error. The second solution doesn't seem practical. The first solution is doable, but do we really need a strict guarantee in the first place?