Index: ELF/Filesystem.cpp =================================================================== --- ELF/Filesystem.cpp +++ ELF/Filesystem.cpp @@ -14,8 +14,12 @@ #include "Filesystem.h" #include "Config.h" #include "lld/Common/Threads.h" +#include "llvm/Config/config.h" #include "llvm/Support/FileOutputBuffer.h" #include "llvm/Support/FileSystem.h" +#if defined(HAVE_UNISTD_H) +#include +#endif using namespace llvm; @@ -35,27 +39,30 @@ // Since LLD can link a 1 GB binary in about 5 seconds, that waste // actually counts. // -// This function spawns a background thread to call unlink. +// This function spawns a background thread to remove the file. // The calling thread returns almost immediately. void elf::unlinkAsync(StringRef Path) { +// Removing a file is async on windows. +#if defined(LLVM_ON_WIN32) + sys::fs::remove(Path); +#else if (!ThreadsEnabled || !sys::fs::exists(Path) || !sys::fs::is_regular_file(Path)) return; - // First, rename Path to avoid race condition. We cannot remove - // Path from a different thread because we are now going to create - // Path as a new file. If we do that in a different thread, the new - // thread can remove the new file. - SmallString<128> TempPath; - if (sys::fs::createUniqueFile(Path + "tmp%%%%%%%%", TempPath)) + // We cannot just remove path from a different thread because we are now going + // to create path as a new file. + // Instead we open the file and unlink it on this thread. The unlink is fast + // since the open fd guarantees that it is not removing the last reference. + int FD; + if (std::error_code EC = sys::fs::openFileForRead(Path, FD)) return; - if (sys::fs::rename(Path, TempPath)) { - sys::fs::remove(TempPath); - return; - } - // Remove TempPath in background. - runBackground([=] { ::remove(TempPath.str().str().c_str()); }); + sys::fs::remove(Path); + + // close and therefore remove TempPath in background. + runBackground([=] { ::close(FD); }); +#endif } // Simulate file creation to see if Path is writable.