[llvm] r203162 - [Support/LockFileManager] Re-apply r203137 and r203138 but use symbolic links only on unix.
Argyrios Kyrtzidis
akyrtzi at gmail.com
Thu Mar 6 12:53:58 PST 2014
Author: akirtzidis
Date: Thu Mar 6 14:53:58 2014
New Revision: 203162
URL: http://llvm.org/viewvc/llvm-project?rev=203162&view=rev
Log:
[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.
Modified:
llvm/trunk/lib/Support/LockFileManager.cpp
Modified: llvm/trunk/lib/Support/LockFileManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/LockFileManager.cpp?rev=203162&r1=203161&r2=203162&view=diff
==============================================================================
--- llvm/trunk/lib/Support/LockFileManager.cpp (original)
+++ llvm/trunk/lib/Support/LockFileManager.cpp Thu Mar 6 14:53:58 2014
@@ -67,6 +67,22 @@ bool LockFileManager::processStillExecut
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)
{
this->FileName = FileName;
@@ -115,34 +131,50 @@ LockFileManager::LockFileManager(StringR
}
}
- // Create a hard link from the lock file name. If this succeeds, we're done.
- error_code EC
- = sys::fs::create_hard_link(UniqueLockFileName.str(),
- LockFileName.str());
- if (EC == errc::success)
- return;
+ while (1) {
+#if LLVM_ON_UNIX
+ // Create a symbolic link from the lock file name. If this succeeds, we're
+ // done. Note that we are using symbolic link because hard links are not
+ // supported by all filesystems.
+ error_code EC
+ = unix_create_symbolic_link(UniqueLockFileName.str(),
+ LockFileName.str());
+#else
+ // We can't use symbolic links for windows.
+ // Create a hard link from the lock file name. If this succeeds, we're done.
+ error_code EC
+ = sys::fs::create_hard_link(UniqueLockFileName.str(),
+ LockFileName.str());
+#endif
+ if (EC == errc::success)
+ return;
- // Creating the hard link failed.
+ if (EC != errc::file_exists) {
+ Error = EC;
+ return;
+ }
-#ifdef LLVM_ON_UNIX
- // The creation of the hard link may appear to fail, but if stat'ing the
- // unique file returns a link count of 2, then we can still declare success.
- struct stat StatBuf;
- if (stat(UniqueLockFileName.c_str(), &StatBuf) == 0 &&
- StatBuf.st_nlink == 2)
- return;
-#endif
+ // Someone else managed to create the lock file first. Read the process ID
+ // from the lock file.
+ if ((Owner = readLockFile(LockFileName))) {
+ // Wipe out our unique lock file (it's useless now)
+ sys::fs::remove(UniqueLockFileName.str());
+ return;
+ }
- // Someone else managed to create the lock file first. Wipe out our unique
- // lock file (it's useless now) and read the process ID from the lock file.
- sys::fs::remove(UniqueLockFileName.str());
- if ((Owner = readLockFile(LockFileName)))
- 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 report
- // an error.
- sys::fs::remove(LockFileName.str());
- Error = EC;
+ // 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 {
More information about the llvm-commits
mailing list