]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: retry RemoveAll(workdir) for up to 500ms
authorBryan C. Mills <bcmills@google.com>
Tue, 16 Apr 2019 17:07:29 +0000 (13:07 -0400)
committerBryan C. Mills <bcmills@google.com>
Tue, 16 Apr 2019 17:44:16 +0000 (17:44 +0000)
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 <bcmills@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/go/internal/work/action.go

index 0232c45ebe0c1517b45bc1d448efdcc2f7c6065c..1134b1f35bfc304bbd8a1d99deefe153f21f54f5 100644 (file)
@@ -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)
                                }
                        })
                }