summaryrefslogtreecommitdiff
path: root/lib/Support/LockFileManager.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2014-03-06 17:37:10 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2014-03-06 17:37:10 +0000
commitd25733bebcccb671e5b33283eabdf6d0a66ee5db (patch)
tree34d85fe2c0290c70527171250e2dd857143b5636 /lib/Support/LockFileManager.cpp
parent7b95c0d529c9160b6678a14e2f8885d1cf08cd4f (diff)
downloadllvm-d25733bebcccb671e5b33283eabdf6d0a66ee5db.tar.gz
llvm-d25733bebcccb671e5b33283eabdf6d0a66ee5db.tar.bz2
llvm-d25733bebcccb671e5b33283eabdf6d0a66ee5db.tar.xz
[Support/LockFileManager] Make the LockFileManager more robust against races.
There was a race where: - The LockFileManager tries to own the lock file and fails. - The other owner then releases and removes the lock file. - The LockFileManager tries to read the owner info from the lock file but fails now. In such a case have LockFileManager try to get ownership again, instead of error'ing out. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203138 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/LockFileManager.cpp')
-rw-r--r--lib/Support/LockFileManager.cpp51
1 files changed, 34 insertions, 17 deletions
diff --git a/lib/Support/LockFileManager.cpp b/lib/Support/LockFileManager.cpp
index acb310efee..957f2fdd7a 100644
--- a/lib/Support/LockFileManager.cpp
+++ b/lib/Support/LockFileManager.cpp
@@ -115,25 +115,42 @@ LockFileManager::LockFileManager(StringRef FileName)
}
}
- // 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
- = sys::fs::create_symbolic_link(UniqueLockFileName.str(),
- LockFileName.str());
- if (EC == errc::success)
- return;
+ while (1) {
+ // 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
+ = sys::fs::create_symbolic_link(UniqueLockFileName.str(),
+ LockFileName.str());
+ if (EC == errc::success)
+ 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 (EC != errc::file_exists) {
+ Error = EC;
+ return;
+ }
- // There is a lock file that nobody owns; try to clean it up and report
- // an error.
- sys::fs::remove(LockFileName.str());
- Error = EC;
+ // 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;
+ }
+
+ 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 {