diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2014-03-06 17:37:10 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2014-03-06 17:37:10 +0000 |
commit | d25733bebcccb671e5b33283eabdf6d0a66ee5db (patch) | |
tree | 34d85fe2c0290c70527171250e2dd857143b5636 /lib/Support/LockFileManager.cpp | |
parent | 7b95c0d529c9160b6678a14e2f8885d1cf08cd4f (diff) | |
download | llvm-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.cpp | 51 |
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 { |