mirror of https://github.com/golang/go.git
cmd/go/internal/vcweb: fix a data race in the overview handler
I forgot to lock the scriptResult in the overview handler, and apparently a cmd/go test is incidentally fetching the overview page at some point during test execution, triggering the race. This race was caught almost immediately by the new linux-amd64-longtest-race builder (see https://build.golang.org/log/85ab78169a6382a73b1a26c89e64138b387da217). Updates #27494. Change-Id: I06ee8d54dba400800284401428ba4a59809983b2 Reviewed-on: https://go-review.googlesource.com/c/go/+/449517 Run-TryBot: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Bryan Mills <bcmills@google.com> Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
parent
fffda6b3ad
commit
fcd14bdcbd
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -87,6 +88,24 @@ func TestScripts(t *testing.T) {
|
||||||
}
|
}
|
||||||
srv := httptest.NewServer(s)
|
srv := httptest.NewServer(s)
|
||||||
|
|
||||||
|
// To check for data races in the handler, run the root handler to produce an
|
||||||
|
// overview of the script status at an arbitrary point during the test.
|
||||||
|
// (We ignore the output because the expected failure mode is a friendly stack
|
||||||
|
// dump from the race detector.)
|
||||||
|
t.Run("overview", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Millisecond) // Give the other handlers time to race.
|
||||||
|
|
||||||
|
resp, err := http.Get(srv.URL)
|
||||||
|
if err == nil {
|
||||||
|
io.Copy(io.Discard, resp.Body)
|
||||||
|
resp.Body.Close()
|
||||||
|
} else {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
// The subtests spawned by WalkDir run in parallel. When they complete, this
|
// The subtests spawned by WalkDir run in parallel. When they complete, this
|
||||||
// Cleanup callback will run. At that point we fetch the root URL (which
|
// Cleanup callback will run. At that point we fetch the root URL (which
|
||||||
|
|
|
||||||
|
|
@ -383,6 +383,9 @@ func (s *Server) overview(w http.ResponseWriter, r *http.Request) {
|
||||||
status := ""
|
status := ""
|
||||||
if ri, ok := s.scriptCache.Load(rel); ok {
|
if ri, ok := s.scriptCache.Load(rel); ok {
|
||||||
r := ri.(*scriptResult)
|
r := ri.(*scriptResult)
|
||||||
|
r.mu.RLock()
|
||||||
|
defer r.mu.RUnlock()
|
||||||
|
|
||||||
if !r.hashTime.IsZero() {
|
if !r.hashTime.IsZero() {
|
||||||
hashTime = r.hashTime.Format(time.RFC3339)
|
hashTime = r.hashTime.Format(time.RFC3339)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue