From 34b1f210462409f8c05d927a80d973b5692c1d26 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Tue, 16 Apr 2019 16:14:31 -0400 Subject: [PATCH] cmd/go/internal/renameio: mask spurious "Access is denied" errors on Windows Fixes #31247 Change-Id: I85a760a5d36ae835c97a13f980804d06b658857e Reviewed-on: https://go-review.googlesource.com/c/go/+/172418 Run-TryBot: Bryan C. Mills Reviewed-by: Brad Fitzpatrick TryBot-Result: Gobot Gobot --- src/cmd/go/internal/renameio/renameio.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/cmd/go/internal/renameio/renameio.go b/src/cmd/go/internal/renameio/renameio.go index 8f59e1a577..3f3f1708fa 100644 --- a/src/cmd/go/internal/renameio/renameio.go +++ b/src/cmd/go/internal/renameio/renameio.go @@ -11,6 +11,9 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" + "strings" + "time" ) const patternSuffix = "*.tmp" @@ -59,5 +62,22 @@ func WriteToFile(filename string, data io.Reader) (err error) { if err := f.Close(); err != nil { return err } - return os.Rename(f.Name(), filename) + + var start time.Time + for { + err := os.Rename(f.Name(), filename) + if err == nil || runtime.GOOS != "windows" || !strings.HasSuffix(err.Error(), "Access is denied.") { + return err + } + + // Windows seems to occasionally trigger spurious "Access is denied" errors + // here (see golang.org/issue/31247). We're not sure why. It's probably + // worth a little extra latency to avoid propagating the spurious errors. + if start.IsZero() { + start = time.Now() + } else if time.Since(start) >= 500*time.Millisecond { + return err + } + time.Sleep(5 * time.Millisecond) + } } -- 2.48.1