From: Michael Matloob Date: Mon, 6 Jan 2025 16:10:02 +0000 (-0500) Subject: cmd/go/internal/modindex: don't write index entry if file open X-Git-Tag: go1.24rc2~6^2~4 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=b50ccef67a5cd4a2919131cfeb6f3a21d6742385;p=gostls13.git cmd/go/internal/modindex: don't write index entry if file open On Windows, we can't open a file that's already been opened. Before this change, we'd try to write an index entry if mmapping the entry failed. But that could happen either if the file doesn't exist or if there was a problem mmapping an already opened file. Pass through information about whether the file was actually opened so that we don't try to write to an already opened file. For #71059 Change-Id: I6adabe1093fed9ec37e7fafb13384c102786cbce Reviewed-on: https://go-review.googlesource.com/c/go/+/640577 Reviewed-by: Sam Thanawalla LUCI-TryBot-Result: Go LUCI --- diff --git a/src/cmd/go/internal/cache/cache.go b/src/cmd/go/internal/cache/cache.go index c9acd8782d..1bef1db08c 100644 --- a/src/cmd/go/internal/cache/cache.go +++ b/src/cmd/go/internal/cache/cache.go @@ -296,19 +296,19 @@ func GetBytes(c Cache, id ActionID) ([]byte, Entry, error) { // GetMmap looks up the action ID in the cache and returns // the corresponding output bytes. // GetMmap should only be used for data that can be expected to fit in memory. -func GetMmap(c Cache, id ActionID) ([]byte, Entry, error) { +func GetMmap(c Cache, id ActionID) ([]byte, Entry, bool, error) { entry, err := c.Get(id) if err != nil { - return nil, entry, err + return nil, entry, false, err } - md, err := mmap.Mmap(c.OutputFile(entry.OutputID)) + md, opened, err := mmap.Mmap(c.OutputFile(entry.OutputID)) if err != nil { - return nil, Entry{}, err + return nil, Entry{}, opened, err } if int64(len(md.Data)) != entry.Size { - return nil, Entry{}, &entryNotFoundError{Err: errors.New("file incomplete")} + return nil, Entry{}, true, &entryNotFoundError{Err: errors.New("file incomplete")} } - return md.Data, entry, nil + return md.Data, entry, true, nil } // OutputFile returns the name of the cache file storing output with the given OutputID. diff --git a/src/cmd/go/internal/mmap/mmap.go b/src/cmd/go/internal/mmap/mmap.go index fcbd3e08c1..fd374df82e 100644 --- a/src/cmd/go/internal/mmap/mmap.go +++ b/src/cmd/go/internal/mmap/mmap.go @@ -22,10 +22,11 @@ type Data struct { } // Mmap maps the given file into memory. -func Mmap(file string) (Data, error) { +func Mmap(file string) (Data, bool, error) { f, err := os.Open(file) if err != nil { - return Data{}, err + return Data{}, false, err } - return mmapFile(f) + data, err := mmapFile(f) + return data, true, err } diff --git a/src/cmd/go/internal/modindex/read.go b/src/cmd/go/internal/modindex/read.go index c4102409b4..4c1fbd8359 100644 --- a/src/cmd/go/internal/modindex/read.go +++ b/src/cmd/go/internal/modindex/read.go @@ -183,16 +183,21 @@ func openIndexModule(modroot string, ismodcache bool) (*Module, error) { if err != nil { return nil, err } - data, _, err := cache.GetMmap(cache.Default(), id) + data, _, opened, err := cache.GetMmap(cache.Default(), id) if err != nil { // Couldn't read from modindex. Assume we couldn't read from // the index because the module hasn't been indexed yet. + // But double check on Windows that we haven't opened the file yet, + // because once mmap opens the file, we can't close it, and + // Windows won't let us open an already opened file. data, err = indexModule(modroot) if err != nil { return nil, err } - if err = cache.PutBytes(cache.Default(), id, data); err != nil { - return nil, err + if runtime.GOOS != "windows" || !opened { + if err = cache.PutBytes(cache.Default(), id, data); err != nil { + return nil, err + } } } mi, err := fromBytes(modroot, data) @@ -212,13 +217,18 @@ func openIndexPackage(modroot, pkgdir string) (*IndexPackage, error) { if err != nil { return nil, err } - data, _, err := cache.GetMmap(cache.Default(), id) + data, _, opened, err := cache.GetMmap(cache.Default(), id) if err != nil { // Couldn't read from index. Assume we couldn't read from // the index because the package hasn't been indexed yet. + // But double check on Windows that we haven't opened the file yet, + // because once mmap opens the file, we can't close it, and + // Windows won't let us open an already opened file. data = indexPackage(modroot, pkgdir) - if err = cache.PutBytes(cache.Default(), id, data); err != nil { - return nil, err + if runtime.GOOS != "windows" || !opened { + if err = cache.PutBytes(cache.Default(), id, data); err != nil { + return nil, err + } } } pkg, err := packageFromBytes(modroot, data)