// 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.
+// The boolean result indicates whether the file was opened.
+// If it is true, the caller should avoid attempting
+// to write to the file on Windows, because Windows locks
+// the open file, and writes to it will fail.
func GetMmap(c Cache, id ActionID) ([]byte, Entry, bool, error) {
entry, err := c.Get(id)
if err != nil {
}
// Mmap maps the given file into memory.
+// The boolean result indicates whether the file was opened.
+// If it is true, the caller should avoid attempting
+// to write to the file on Windows, because Windows locks
+// the open file, and writes to it will fail.
func Mmap(file string) (Data, bool, error) {
f, err := os.Open(file)
if err != nil {
return Data{}, false, err
}
data, err := mmapFile(f)
+
+ // Closing the file causes it not to count against this process's
+ // limit on open files; however, the mapping still counts against
+ // the system-wide limit, which is typically higher. Examples:
+ //
+ // macOS process (sysctl kern.maxfilesperproc): 61440
+ // macOS system (sysctl kern.maxfiles): 122880
+ // linux process (ulimit -n) 1048576
+ // linux system (/proc/sys/fs/file-max) 100000
+ if cerr := f.Close(); cerr != nil && err == nil {
+ return data, true, cerr
+ }
+
+ // The file is still considered to be in use on Windows after
+ // it's closed because of the mapping.
return data, true, err
}