瀏覽代碼

Fixed a race condition in PrecompiledPreamble.

Summary:
Two PrecompiledPreambles, used in parallel on separate threads,
could be writing preamble to the same temporary file.

Reviewers: bkramer, krasimir, klimek

Reviewed By: klimek

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D36529

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@310618 91177308-0d34-0410-b5e6-96231b3b80d8
Ilya Biryukov 8 年之前
父節點
當前提交
ed88e83b5d
共有 1 個文件被更改,包括 9 次插入1 次删除
  1. 9 1
      lib/Frontend/PrecompiledPreamble.cpp

+ 9 - 1
lib/Frontend/PrecompiledPreamble.cpp

@@ -28,6 +28,7 @@
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Mutex.h"
 #include "llvm/Support/MutexGuard.h"
+#include "llvm/Support/Process.h"
 
 using namespace clang;
 
@@ -462,9 +463,16 @@ llvm::ErrorOr<PrecompiledPreamble::TempPCHFile>
 PrecompiledPreamble::TempPCHFile::createInSystemTempDir(const Twine &Prefix,
                                                         StringRef Suffix) {
   llvm::SmallString<64> File;
-  auto EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, /*ref*/ File);
+  // Using a version of createTemporaryFile with a file descriptor guarantees
+  // that we would never get a race condition in a multi-threaded setting (i.e.,
+  // multiple threads getting the same temporary path).
+  int FD;
+  auto EC = llvm::sys::fs::createTemporaryFile(Prefix, Suffix, /*ref*/ FD,
+                                               /*ref*/ File);
   if (EC)
     return EC;
+  // We only needed to make sure the file exists, close the file right away.
+  llvm::sys::Process::SafelyCloseFileDescriptor(FD);
   return TempPCHFile(std::move(File).str());
 }