Index: lld/trunk/ELF/CMakeLists.txt =================================================================== --- lld/trunk/ELF/CMakeLists.txt +++ lld/trunk/ELF/CMakeLists.txt @@ -40,6 +40,7 @@ Symbols.cpp SyntheticSections.cpp Target.cpp + Threads.cpp Thunks.cpp Writer.cpp Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -89,6 +89,7 @@ Config->Argv = {Args.begin(), Args.end()}; Driver->main(Args, CanExitEarly); + waitForBackgroundThreads(); // Exit immediately if we don't need to return to the caller. // This saves time because the overhead of calling destructors Index: lld/trunk/ELF/Error.cpp =================================================================== --- lld/trunk/ELF/Error.cpp +++ lld/trunk/ELF/Error.cpp @@ -9,6 +9,7 @@ #include "Error.h" #include "Config.h" +#include "Threads.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Error.h" @@ -100,6 +101,8 @@ } void elf::exitLld(int Val) { + waitForBackgroundThreads(); + // Dealloc/destroy ManagedStatic variables before calling // _exit(). In a non-LTO build, this is a nop. In an LTO // build allows us to get the output of -time-passes. Index: lld/trunk/ELF/Filesystem.cpp =================================================================== --- lld/trunk/ELF/Filesystem.cpp +++ lld/trunk/ELF/Filesystem.cpp @@ -13,9 +13,9 @@ #include "Filesystem.h" #include "Config.h" -#include "llvm/Support/FileSystem.h" +#include "Threads.h" #include "llvm/Support/FileOutputBuffer.h" -#include +#include "llvm/Support/FileSystem.h" using namespace llvm; @@ -55,7 +55,7 @@ } // Remove TempPath in background. - std::thread([=] { ::remove(TempPath.str().str().c_str()); }).detach(); + runBackground([=] { ::remove(TempPath.str().str().c_str()); }); } // Simulate file creation to see if Path is writable. Index: lld/trunk/ELF/Threads.h =================================================================== --- lld/trunk/ELF/Threads.h +++ lld/trunk/ELF/Threads.h @@ -81,6 +81,10 @@ else for_each_n(llvm::parallel::seq, Begin, End, Fn); } + +void runBackground(std::function Fn); +void waitForBackgroundThreads(); + } // namespace elf } // namespace lld Index: lld/trunk/ELF/Threads.cpp =================================================================== --- lld/trunk/ELF/Threads.cpp +++ lld/trunk/ELF/Threads.cpp @@ -0,0 +1,29 @@ +//===- Threads.cpp --------------------------------------------------------===// +// +// The LLVM Linker +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Threads.h" +#include + +static std::vector Threads; + +// Runs a given function in a new thread. +void lld::elf::runBackground(std::function Fn) { + Threads.emplace_back(Fn); +} + +// Wait for all threads spawned for runBackground() to finish. +// +// You need to call this function from the main thread before exiting +// because it is not defined what will happen to non-main threads when +// the main thread exits. +void lld::elf::waitForBackgroundThreads() { + for (std::thread &T : Threads) + if (T.joinable()) + T.join(); +}