aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2019-04-29 21:29:16 -0400
committerRuss Cox <rsc@golang.org>2019-04-30 13:12:48 +0000
commit8e28cd19acc43437e7ccec25dd0572afd6b77f8a (patch)
tree220de68fb2e082d32d5551c93183bab979b5b48e /src
parent203e18883726409205df4af11935d6393ed9ad52 (diff)
downloadgo-8e28cd19acc43437e7ccec25dd0572afd6b77f8a.tar.xz
cmd/go/internal/modfetch: fix concurrent read/write race in modfetch
On Windows systems, the failure rate for cmd/go's TestScript/mod_concurrent is somewhere around 3-10% without this change. With the change, I have yet to see a failure. Fixes #31744. Change-Id: Ib321ebb9556dd8438086cf329dfa083a9e051732 Reviewed-on: https://go-review.googlesource.com/c/go/+/174439 Run-TryBot: Russ Cox <rsc@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/go/internal/modfetch/sumdb.go10
1 files changed, 9 insertions, 1 deletions
diff --git a/src/cmd/go/internal/modfetch/sumdb.go b/src/cmd/go/internal/modfetch/sumdb.go
index b01aad8333..ebfb95b716 100644
--- a/src/cmd/go/internal/modfetch/sumdb.go
+++ b/src/cmd/go/internal/modfetch/sumdb.go
@@ -233,7 +233,15 @@ func (*dbClient) WriteConfig(file string, old, new []byte) error {
// which will be deleted by "go clean -modcache".
func (*dbClient) ReadCache(file string) ([]byte, error) {
targ := filepath.Join(PkgMod, "download/cache/sumdb", file)
- return lockedfile.Read(targ)
+ data, err := lockedfile.Read(targ)
+ // lockedfile.Write does not atomically create the file with contents.
+ // There is a moment between file creation and locking the file for writing,
+ // during which the empty file can be locked for reading.
+ // Treat observing an empty file as file not found.
+ if err == nil && len(data) == 0 {
+ err = &os.PathError{Op: "read", Path: targ, Err: os.ErrNotExist}
+ }
+ return data, err
}
// WriteCache updates cached lookups or tiles.