Files
llvm/lld/ELF/Threads.cpp
Rui Ueyama 945cd64471 Wait for all threads to terminate before exitting.
I think it is not defined what would happen to detached threads
when the main thread tries to exit. That means it was not guaranteed
that unlinkAsync correctly removes a temporary file. It was also
reported that this unlinkAsync caused a crash on Windows.

This patch adds a few new functions so that the main thread always
waits for non-main threads before exitting.

I don't actually like the new two functions, runBackground and
waitForBackgroundThreads, because it looks like it is a bit
overdesigned. After all, what we are doing with these functions
is to just remove a file.

An alternative would be to do fork(2) and make the child process
remove a file asynchronously. However, it has its own problems.
Correctly forking and reclaiming a resource using waitpid(2) is not
doable unless we know our process-wide settings (such as signal mask),
but we can't make any assumption on it when lld is embedded to other
process. So I chose to stick with threads instead of multi-processes.

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

llvm-svn: 315033
2017-10-05 23:01:11 +00:00

30 lines
895 B
C++

//===- 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 <thread>
static std::vector<std::thread> Threads;
// Runs a given function in a new thread.
void lld::elf::runBackground(std::function<void()> 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();
}