[PATCH] D39874: LTO: don't fatal when value for cache key already exists

Bob Haarman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 9 15:34:30 PST 2017


inglorion created this revision.
Herald added subscribers: hiraditya, mehdi_amini.

LTO/Caching.cpp uses file rename to atomically set the value for a
cache key. On Windows, this fails when the destination file already
exists. Previously, LLVM would report_fatal_error in such
cases. However, because the old and the new value for the cache key
are supposed to be equivalent, it actually doesn't matter which one we
keep. This change makes it so that failing the rename when an openable
file with the desired name already exists causes us to report success
instead of fataling.


https://reviews.llvm.org/D39874

Files:
  llvm/lib/LTO/Caching.cpp


Index: llvm/lib/LTO/Caching.cpp
===================================================================
--- llvm/lib/LTO/Caching.cpp
+++ llvm/lib/LTO/Caching.cpp
@@ -17,6 +17,7 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace llvm;
@@ -72,7 +73,20 @@
                              MBOrErr.getError().message() + "\n");
 
         // This is atomic on POSIX systems.
-        if (auto EC = sys::fs::rename(TempFilename, EntryPath))
+        // On Windows, it can fail with permission denied if the destination
+        // file already exists. Since the existing file should be semantically
+        // equivalent to the one we are trying to write, we count that as
+        // a success if we can open the destination file for reading.
+        auto EC = sys::fs::rename(TempFilename, EntryPath);
+        if (EC == errc::permission_denied) {
+          int FD;
+          EC = sys::fs::openFileForRead(EntryPath, FD);
+          if (!EC) {
+            sys::Process::SafelyCloseFileDescriptor(FD);
+            sys::fs::remove(TempFilename);
+          }
+        }
+        if (EC)
           report_fatal_error(Twine("Failed to rename temporary file ") +
                              TempFilename + " to " + EntryPath + ": " +
                              EC.message() + "\n");


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D39874.122346.patch
Type: text/x-patch
Size: 1435 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171109/45b10d7e/attachment-0001.bin>


More information about the llvm-commits mailing list