From d73d5d9fb0c2b963bd58ed0ab679dd71498f118e Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Tue, 27 Oct 2020 03:09:26 -0400 Subject: [PATCH] cmd/go/internal/imports: make Tags and AnyTags safe for concurrent use AnyTags turned up as a data race while running 'go test -race cmd/go'. I'm not sure how long the race has been present. ================== WARNING: DATA RACE Read at 0x000001141ec0 by goroutine 8: cmd/go/internal/imports.AnyTags() /usr/local/google/home/bcmills/go/src/cmd/go/internal/imports/tags.go:45 +0x10e cmd/go/internal/modload.QueryPattern.func2() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:539 +0x11d cmd/go/internal/modload.QueryPattern.func4.1() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:607 +0x3db cmd/go/internal/modload.queryPrefixModules.func1() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:677 +0xa7 Previous write at 0x000001141ec0 by goroutine 7: cmd/go/internal/imports.AnyTags() /usr/local/google/home/bcmills/go/src/cmd/go/internal/imports/tags.go:46 +0x26b cmd/go/internal/modload.QueryPattern.func2() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:539 +0x11d cmd/go/internal/modload.QueryPattern.func4.1() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:607 +0x3db cmd/go/internal/modload.queryPrefixModules.func1() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:677 +0xa7 Goroutine 8 (running) created at: cmd/go/internal/modload.queryPrefixModules() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:676 +0x284 cmd/go/internal/modload.QueryPattern.func4() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:624 +0x2e4 cmd/go/internal/modfetch.TryProxies() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modfetch/proxy.go:220 +0x107 cmd/go/internal/modload.QueryPattern() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:590 +0x69e cmd/go/internal/work.installOutsideModule() /usr/local/google/home/bcmills/go/src/cmd/go/internal/work/build.go:744 +0x4b0 cmd/go/internal/work.runInstall() /usr/local/google/home/bcmills/go/src/cmd/go/internal/work/build.go:556 +0x217 main.main() /usr/local/google/home/bcmills/go/src/cmd/go/main.go:194 +0xb94 Goroutine 7 (finished) created at: cmd/go/internal/modload.queryPrefixModules() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:676 +0x284 cmd/go/internal/modload.QueryPattern.func4() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:624 +0x2e4 cmd/go/internal/modfetch.TryProxies() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modfetch/proxy.go:220 +0x107 cmd/go/internal/modload.QueryPattern() /usr/local/google/home/bcmills/go/src/cmd/go/internal/modload/query.go:590 +0x69e cmd/go/internal/work.installOutsideModule() /usr/local/google/home/bcmills/go/src/cmd/go/internal/work/build.go:744 +0x4b0 cmd/go/internal/work.runInstall() /usr/local/google/home/bcmills/go/src/cmd/go/internal/work/build.go:556 +0x217 main.main() /usr/local/google/home/bcmills/go/src/cmd/go/main.go:194 +0xb94 ================== Change-Id: Id394978fd6ea0c30614caf8f90ee4f8e2d272843 Reviewed-on: https://go-review.googlesource.com/c/go/+/265278 Trust: Bryan C. Mills Run-TryBot: Bryan C. Mills TryBot-Result: Go Bot Reviewed-by: Jay Conrod --- src/cmd/go/internal/imports/tags.go | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/cmd/go/internal/imports/tags.go b/src/cmd/go/internal/imports/tags.go index 14b4e21a02..01b448b914 100644 --- a/src/cmd/go/internal/imports/tags.go +++ b/src/cmd/go/internal/imports/tags.go @@ -4,17 +4,23 @@ package imports -import "cmd/go/internal/cfg" +import ( + "cmd/go/internal/cfg" + "sync" +) -var tags map[string]bool +var ( + tags map[string]bool + tagsOnce sync.Once +) // Tags returns a set of build tags that are true for the target platform. // It includes GOOS, GOARCH, the compiler, possibly "cgo", // release tags like "go1.13", and user-specified build tags. func Tags() map[string]bool { - if tags == nil { + tagsOnce.Do(func() { tags = loadTags() - } + }) return tags } @@ -36,14 +42,17 @@ func loadTags() map[string]bool { return tags } -var anyTags map[string]bool +var ( + anyTags map[string]bool + anyTagsOnce sync.Once +) // AnyTags returns a special set of build tags that satisfy nearly all // build tag expressions. Only "ignore" and malformed build tag requirements // are considered false. func AnyTags() map[string]bool { - if anyTags == nil { + anyTagsOnce.Do(func() { anyTags = map[string]bool{"*": true} - } + }) return anyTags } -- 2.48.1