[Support/LockFileManager] Re-apply r203137 and r203138 but use symbolic links only on unix.

Reid Kleckner pointed out that we can't use symbolic links on Windows.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203162 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Argyrios Kyrtzidis 2014-03-06 20:53:58 +00:00
parent 4eb048a6f1
commit 046c8e1a3a

View File

@ -67,6 +67,22 @@ bool LockFileManager::processStillExecuting(StringRef Hostname, int PID) {
return true; return true;
} }
#if LLVM_ON_UNIX
static error_code unix_create_symbolic_link(const Twine &to,
const Twine &from) {
// Get arguments.
SmallString<128> from_storage;
SmallString<128> to_storage;
StringRef f = from.toNullTerminatedStringRef(from_storage);
StringRef t = to.toNullTerminatedStringRef(to_storage);
if (::symlink(t.begin(), f.begin()) == -1)
return error_code(errno, system_category());
return error_code::success();
}
#endif
LockFileManager::LockFileManager(StringRef FileName) LockFileManager::LockFileManager(StringRef FileName)
{ {
this->FileName = FileName; this->FileName = FileName;
@ -115,34 +131,50 @@ LockFileManager::LockFileManager(StringRef FileName)
} }
} }
// Create a hard link from the lock file name. If this succeeds, we're done. while (1) {
error_code EC #if LLVM_ON_UNIX
= sys::fs::create_hard_link(UniqueLockFileName.str(), // Create a symbolic link from the lock file name. If this succeeds, we're
LockFileName.str()); // done. Note that we are using symbolic link because hard links are not
if (EC == errc::success) // supported by all filesystems.
return; error_code EC
= unix_create_symbolic_link(UniqueLockFileName.str(),
// Creating the hard link failed. LockFileName.str());
#else
#ifdef LLVM_ON_UNIX // We can't use symbolic links for windows.
// The creation of the hard link may appear to fail, but if stat'ing the // Create a hard link from the lock file name. If this succeeds, we're done.
// unique file returns a link count of 2, then we can still declare success. error_code EC
struct stat StatBuf; = sys::fs::create_hard_link(UniqueLockFileName.str(),
if (stat(UniqueLockFileName.c_str(), &StatBuf) == 0 && LockFileName.str());
StatBuf.st_nlink == 2)
return;
#endif #endif
if (EC == errc::success)
return;
// Someone else managed to create the lock file first. Wipe out our unique if (EC != errc::file_exists) {
// lock file (it's useless now) and read the process ID from the lock file. Error = EC;
sys::fs::remove(UniqueLockFileName.str()); return;
if ((Owner = readLockFile(LockFileName))) }
return;
// There is a lock file that nobody owns; try to clean it up and report // Someone else managed to create the lock file first. Read the process ID
// an error. // from the lock file.
sys::fs::remove(LockFileName.str()); if ((Owner = readLockFile(LockFileName))) {
Error = EC; // Wipe out our unique lock file (it's useless now)
sys::fs::remove(UniqueLockFileName.str());
return;
}
if (!sys::fs::exists(LockFileName.str())) {
// The previous owner released the lock file before we could read it.
// Try to get ownership again.
continue;
}
// There is a lock file that nobody owns; try to clean it up and get
// ownership.
if ((EC = sys::fs::remove(LockFileName.str()))) {
Error = EC;
return;
}
}
} }
LockFileManager::LockFileState LockFileManager::getState() const { LockFileManager::LockFileState LockFileManager::getState() const {