aboutsummaryrefslogtreecommitdiff
path: root/deps/lld/ELF/Filesystem.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-03-08 10:59:54 -0500
committerAndrew Kelley <superjoe30@gmail.com>2018-03-08 10:59:54 -0500
commit3200ebc2ea5f6bb51130cbc69d6533144a9f4ddc (patch)
treee234c061c28a95c35afbb35b80b89e3114ecdeb9 /deps/lld/ELF/Filesystem.cpp
parent2e010c60ae006944ae20ab8b3445598471c9f1e8 (diff)
parentb57cb04afc1898c3b21ef3486709f0c0aa285433 (diff)
downloadzig-3200ebc2ea5f6bb51130cbc69d6533144a9f4ddc.tar.gz
zig-3200ebc2ea5f6bb51130cbc69d6533144a9f4ddc.zip
Merge branch 'llvm6'
Zig now depends on LLVM 6.0.0. The latest commit that depends on LLVM 5.0.1 is 2e010c60ae006944ae20ab8b3445598471c9f1e8.
Diffstat (limited to 'deps/lld/ELF/Filesystem.cpp')
-rw-r--r--deps/lld/ELF/Filesystem.cpp45
1 files changed, 27 insertions, 18 deletions
diff --git a/deps/lld/ELF/Filesystem.cpp b/deps/lld/ELF/Filesystem.cpp
index d468ae0c61..8d0b5d8a2f 100644
--- a/deps/lld/ELF/Filesystem.cpp
+++ b/deps/lld/ELF/Filesystem.cpp
@@ -13,8 +13,13 @@
#include "Filesystem.h"
#include "Config.h"
-#include "llvm/Support/FileSystem.h"
+#include "lld/Common/Threads.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/FileSystem.h"
+#if LLVM_ON_UNIX
+#include <unistd.h>
+#endif
#include <thread>
using namespace llvm;
@@ -35,27 +40,29 @@ using namespace lld::elf;
// 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) {
- if (!Config->Threads || !sys::fs::exists(Config->OutputFile) ||
- !sys::fs::is_regular_file(Config->OutputFile))
+// 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))
- return;
- if (sys::fs::rename(Path, TempPath)) {
- sys::fs::remove(TempPath);
- return;
- }
+ // 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;
+ std::error_code EC = sys::fs::openFileForRead(Path, FD);
+ sys::fs::remove(Path);
- // Remove TempPath in background.
- std::thread([=] { ::remove(TempPath.str().str().c_str()); }).detach();
+ // close and therefore remove TempPath in background.
+ if (!EC)
+ std::thread([=] { ::close(FD); }).detach();
+#endif
}
// Simulate file creation to see if Path is writable.
@@ -73,5 +80,7 @@ void elf::unlinkAsync(StringRef Path) {
std::error_code elf::tryCreateFile(StringRef Path) {
if (Path.empty())
return std::error_code();
- return FileOutputBuffer::create(Path, 1).getError();
+ if (Path == "-")
+ return std::error_code();
+ return errorToErrorCode(FileOutputBuffer::create(Path, 1).takeError());
}