Fixes #31247
Change-Id: I85a760a5d36ae835c97a13f980804d06b658857e
Reviewed-on: https://go-review.googlesource.com/c/go/+/172418
Run-TryBot: Bryan C. Mills <bcmills@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
"io/ioutil"
"os"
"path/filepath"
+ "runtime"
+ "strings"
+ "time"
)
const patternSuffix = "*.tmp"
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)
+ }
}