浏览代码

[Tooling] Avoid working-dir races in AllTUsToolExecutor

Reviewers: ioeric

Reviewed By: ioeric

Subscribers: jdoerfert, cfe-commits

Tags: #clang

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@356743 91177308-0d34-0410-b5e6-96231b3b80d8
Ilya Biryukov 6 年之前
父节点
当前提交
e3172cb65f
共有 1 个文件被更改,包括 7 次插入14 次删除
  1. 7 14
      lib/Tooling/AllTUsExecution.cpp

+ 7 - 14
lib/Tooling/AllTUsExecution.cpp

@@ -9,6 +9,7 @@
 #include "clang/Tooling/AllTUsExecution.h"
 #include "clang/Tooling/AllTUsExecution.h"
 #include "clang/Tooling/ToolExecutorPluginRegistry.h"
 #include "clang/Tooling/ToolExecutorPluginRegistry.h"
 #include "llvm/Support/ThreadPool.h"
 #include "llvm/Support/ThreadPool.h"
+#include "llvm/Support/VirtualFileSystem.h"
 
 
 namespace clang {
 namespace clang {
 namespace tooling {
 namespace tooling {
@@ -114,25 +115,22 @@ llvm::Error AllTUsToolExecutor::execute(
   {
   {
     llvm::ThreadPool Pool(ThreadCount == 0 ? llvm::hardware_concurrency()
     llvm::ThreadPool Pool(ThreadCount == 0 ? llvm::hardware_concurrency()
                                            : ThreadCount);
                                            : ThreadCount);
-    llvm::SmallString<128> InitialWorkingDir;
-    if (auto EC = llvm::sys::fs::current_path(InitialWorkingDir)) {
-      InitialWorkingDir = "";
-      llvm::errs() << "Error while getting current working directory: "
-                   << EC.message() << "\n";
-    }
     for (std::string File : Files) {
     for (std::string File : Files) {
       Pool.async(
       Pool.async(
           [&](std::string Path) {
           [&](std::string Path) {
             Log("[" + std::to_string(Count()) + "/" + TotalNumStr +
             Log("[" + std::to_string(Count()) + "/" + TotalNumStr +
                 "] Processing file " + Path);
                 "] Processing file " + Path);
-            ClangTool Tool(Compilations, {Path});
+            // Each thread gets an indepent copy of a VFS to allow different
+            // concurrent working directories.
+            IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
+                llvm::vfs::createPhysicalFileSystem().release();
+            ClangTool Tool(Compilations, {Path},
+                           std::make_shared<PCHContainerOperations>(), FS);
             Tool.appendArgumentsAdjuster(Action.second);
             Tool.appendArgumentsAdjuster(Action.second);
             Tool.appendArgumentsAdjuster(getDefaultArgumentsAdjusters());
             Tool.appendArgumentsAdjuster(getDefaultArgumentsAdjusters());
             for (const auto &FileAndContent : OverlayFiles)
             for (const auto &FileAndContent : OverlayFiles)
               Tool.mapVirtualFile(FileAndContent.first(),
               Tool.mapVirtualFile(FileAndContent.first(),
                                   FileAndContent.second);
                                   FileAndContent.second);
-            // Do not restore working dir from multiple threads to avoid races.
-            Tool.setRestoreWorkingDir(false);
             if (Tool.run(Action.first.get()))
             if (Tool.run(Action.first.get()))
               AppendError(llvm::Twine("Failed to run action on ") + Path +
               AppendError(llvm::Twine("Failed to run action on ") + Path +
                           "\n");
                           "\n");
@@ -141,11 +139,6 @@ llvm::Error AllTUsToolExecutor::execute(
     }
     }
     // Make sure all tasks have finished before resetting the working directory.
     // Make sure all tasks have finished before resetting the working directory.
     Pool.wait();
     Pool.wait();
-    if (!InitialWorkingDir.empty()) {
-      if (auto EC = llvm::sys::fs::set_current_path(InitialWorkingDir))
-        llvm::errs() << "Error while restoring working directory: "
-                     << EC.message() << "\n";
-    }
   }
   }
 
 
   if (!ErrorMsg.empty())
   if (!ErrorMsg.empty())