From: Bryan C. Mills Date: Tue, 16 Apr 2019 17:07:29 +0000 (-0400) Subject: cmd/go: retry RemoveAll(workdir) for up to 500ms X-Git-Tag: go1.13beta1~671 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=56b8ee23986c48ec63a0411f12b3fcaad61d6c06;p=gostls13.git cmd/go: retry RemoveAll(workdir) for up to 500ms On some configurations of Windows, directories containing executable files may be locked for a while after the executable exits (perhaps due to antivirus scans?). It's probably worth a little extra latency on exit to avoid filling up the user's temporary directory with leaked files. Updates #30789 Change-Id: Iae7fcdd07fb9ecfb05967cfe0c8833db646d2f85 Reviewed-on: https://go-review.googlesource.com/c/go/+/172337 Run-TryBot: Bryan C. Mills TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- diff --git a/src/cmd/go/internal/work/action.go b/src/cmd/go/internal/work/action.go index 0232c45ebe..1134b1f35b 100644 --- a/src/cmd/go/internal/work/action.go +++ b/src/cmd/go/internal/work/action.go @@ -16,8 +16,10 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "strings" "sync" + "time" "cmd/go/internal/base" "cmd/go/internal/cache" @@ -243,8 +245,23 @@ func (b *Builder) Init() { if !cfg.BuildWork { workdir := b.WorkDir base.AtExit(func() { - if err := os.RemoveAll(workdir); err != nil { - fmt.Fprintf(os.Stderr, "go: failed to remove work dir: %s\n", err) + start := time.Now() + for { + err := os.RemoveAll(workdir) + if err == nil { + return + } + + // On some configurations of Windows, directories containing executable + // files may be locked for a while after the executable exits (perhaps + // due to antivirus scans?). It's probably worth a little extra latency + // on exit to avoid filling up the user's temporary directory with leaked + // files. (See golang.org/issue/30789.) + if runtime.GOOS != "windows" || time.Since(start) >= 500*time.Millisecond { + fmt.Fprintf(os.Stderr, "go: failed to remove work dir: %s\n", err) + return + } + time.Sleep(5 * time.Millisecond) } }) }