summaryrefslogtreecommitdiffstats
path: root/llvm/lib/LTO
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/LTO')
-rw-r--r--llvm/lib/LTO/Caching.cpp27
1 files changed, 21 insertions, 6 deletions
diff --git a/llvm/lib/LTO/Caching.cpp b/llvm/lib/LTO/Caching.cpp
index e32e46c4c3c..3f10c154683 100644
--- a/llvm/lib/LTO/Caching.cpp
+++ b/llvm/lib/LTO/Caching.cpp
@@ -36,7 +36,7 @@ Expected<NativeObjectCache> lto::localCache(StringRef CacheDirectoryPath,
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
MemoryBuffer::getFile(EntryPath);
if (MBOrErr) {
- AddBuffer(Task, std::move(*MBOrErr));
+ AddBuffer(Task, std::move(*MBOrErr), EntryPath);
return AddStreamFn();
}
@@ -60,22 +60,37 @@ Expected<NativeObjectCache> lto::localCache(StringRef CacheDirectoryPath,
EntryPath(std::move(EntryPath)), Task(Task) {}
~CacheStream() {
- // FIXME: This code could race with the cache pruner, but it is unlikely
- // that the cache pruner will choose to remove a newly created file.
-
// Make sure the file is closed before committing it.
OS.reset();
- // This is atomic on POSIX systems.
+
+#ifdef _WIN32
+ // Rename the file first on Windows because we cannot rename an open
+ // file on that platform using the sys::fs::rename function.
+ // FIXME: This code could race with the cache pruner, but it is unlikely
+ // that the cache pruner will choose to remove a newly created file.
+ // We should look at using the SetFileInformationByHandle function to
+ // rename the file while it is open.
if (auto EC = sys::fs::rename(TempFilename, EntryPath))
report_fatal_error(Twine("Failed to rename temporary file ") +
TempFilename + ": " + EC.message() + "\n");
ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
MemoryBuffer::getFile(EntryPath);
+#else
+ // Open the file first to avoid racing with a cache pruner.
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
+ MemoryBuffer::getFile(TempFilename);
+
+ // This is atomic on POSIX systems.
+ if (auto EC = sys::fs::rename(TempFilename, EntryPath))
+ report_fatal_error(Twine("Failed to rename temporary file ") +
+ TempFilename + ": " + EC.message() + "\n");
+#endif
+
if (!MBOrErr)
report_fatal_error(Twine("Failed to open cache file ") + EntryPath +
": " + MBOrErr.getError().message() + "\n");
- AddBuffer(Task, std::move(*MBOrErr));
+ AddBuffer(Task, std::move(*MBOrErr), EntryPath);
}
};
OpenPOWER on IntegriCloud