Skip to content

Commit

Permalink
[Support/LockFileManager] Make the LockFileManager more robust agains…
Browse files Browse the repository at this point in the history
…t 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
  • Loading branch information
akyrtzi committed Mar 6, 2014
1 parent 7b95c0d commit d25733b
Showing 1 changed file with 34 additions and 17 deletions.
51 changes: 34 additions & 17 deletions lib/Support/LockFileManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit d25733b

Please sign in to comment.