summaryrefslogtreecommitdiffstats
path: root/llvm/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
commit62a979cccff4b8d4b7c16bdbdc4a4fe0de2429ea (patch)
tree0888fd1bb0e20bbd072c91637922615b38a221e0 /llvm/lib/Support/LockFileManager.cpp
parent2eb8d02622d7be54fe593425485b2e6a9c4c7d46 (diff)
downloadbcm5719-llvm-62a979cccff4b8d4b7c16bdbdc4a4fe0de2429ea.tar.gz
bcm5719-llvm-62a979cccff4b8d4b7c16bdbdc4a4fe0de2429ea.zip
[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. llvm-svn: 203138
Diffstat (limited to 'llvm/lib/Support/LockFileManager.cpp')
-rw-r--r--llvm/lib/Support/LockFileManager.cpp51
1 files changed, 34 insertions, 17 deletions
diff --git a/llvm/lib/Support/LockFileManager.cpp b/llvm/lib/Support/LockFileManager.cpp
index acb310efeec..957f2fdd7a5 100644
--- a/llvm/lib/Support/LockFileManager.cpp
+++ b/llvm/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 {
OpenPOWER on IntegriCloud