// 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.
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)
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)