aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-07-27 23:34:35 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-10-23 18:26:01 +0000
commit0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583 (patch)
tree6cf5ab1f05330c6773b1f3f64799d56a9c7a1faa /contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp
parent6b9f7133aba44189d9625c352bc2c2a59baf18ef (diff)
parentac9a064cb179f3425b310fa2847f8764ac970a4d (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp48
1 files changed, 13 insertions, 35 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp b/contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp
index a2b0fe8ca8f2..ea040ccf22b9 100644
--- a/contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp
+++ b/contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp
@@ -11,6 +11,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/ExponentialBackoff.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Process.h"
@@ -20,7 +21,6 @@
#include <chrono>
#include <ctime>
#include <memory>
-#include <random>
#include <sys/stat.h>
#include <sys/types.h>
#include <system_error>
@@ -66,7 +66,7 @@ LockFileManager::readLockFile(StringRef LockFileName) {
StringRef Hostname;
StringRef PIDStr;
std::tie(Hostname, PIDStr) = getToken(MB.getBuffer(), " ");
- PIDStr = PIDStr.substr(PIDStr.find_first_not_of(" "));
+ PIDStr = PIDStr.substr(PIDStr.find_first_not_of(' '));
int PID;
if (!PIDStr.getAsInteger(10, PID)) {
auto Owner = std::make_pair(std::string(Hostname), PID);
@@ -87,7 +87,7 @@ static std::error_code getHostID(SmallVectorImpl<char> &HostID) {
struct timespec wait = {1, 0}; // 1 second.
uuid_t uuid;
if (gethostuuid(uuid, &wait) != 0)
- return std::error_code(errno, std::system_category());
+ return errnoAsErrorCode();
uuid_string_t UUIDStr;
uuid_unparse(uuid, UUIDStr);
@@ -205,6 +205,8 @@ LockFileManager::LockFileManager(StringRef FileName)
S.append(std::string(UniqueLockFileName));
setError(Out.error(), S);
sys::fs::remove(UniqueLockFileName);
+ // Don't call report_fatal_error.
+ Out.clear_error();
return;
}
}
@@ -226,7 +228,7 @@ LockFileManager::LockFileManager(StringRef FileName)
std::string S("failed to create link ");
raw_string_ostream OSS(S);
OSS << LockFileName.str() << " to " << UniqueLockFileName.str();
- setError(EC, OSS.str());
+ setError(EC, S);
return;
}
@@ -272,7 +274,7 @@ std::string LockFileManager::getErrorMessage() const {
raw_string_ostream OSS(Str);
if (!ErrCodeMsg.empty())
OSS << ": " << ErrCodeMsg;
- return OSS.str();
+ return Str;
}
return "";
}
@@ -295,29 +297,15 @@ LockFileManager::waitForUnlock(const unsigned MaxSeconds) {
return Res_Success;
// Since we don't yet have an event-based method to wait for the lock file,
- // implement randomized exponential backoff, similar to Ethernet collision
+ // use randomized exponential backoff, similar to Ethernet collision
// algorithm. This improves performance on machines with high core counts
// when the file lock is heavily contended by multiple clang processes
- const unsigned long MinWaitDurationMS = 10;
- const unsigned long MaxWaitMultiplier = 50; // 500ms max wait
- unsigned long WaitMultiplier = 1;
- unsigned long ElapsedTimeSeconds = 0;
-
- std::random_device Device;
- std::default_random_engine Engine(Device());
-
- auto StartTime = std::chrono::steady_clock::now();
+ using namespace std::chrono_literals;
+ ExponentialBackoff Backoff(std::chrono::seconds(MaxSeconds), 10ms, 500ms);
- do {
+ // Wait first as this is only called when the lock is known to be held.
+ while (Backoff.waitForNextAttempt()) {
// FIXME: implement event-based waiting
-
- // Sleep for the designated interval, to allow the owning process time to
- // finish up and remove the lock file.
- std::uniform_int_distribution<unsigned long> Distribution(1,
- WaitMultiplier);
- unsigned long WaitDurationMS = MinWaitDurationMS * Distribution(Engine);
- std::this_thread::sleep_for(std::chrono::milliseconds(WaitDurationMS));
-
if (sys::fs::access(LockFileName.c_str(), sys::fs::AccessMode::Exist) ==
errc::no_such_file_or_directory) {
// If the original file wasn't created, somone thought the lock was dead.
@@ -329,17 +317,7 @@ LockFileManager::waitForUnlock(const unsigned MaxSeconds) {
// If the process owning the lock died without cleaning up, just bail out.
if (!processStillExecuting((*Owner).first, (*Owner).second))
return Res_OwnerDied;
-
- WaitMultiplier *= 2;
- if (WaitMultiplier > MaxWaitMultiplier) {
- WaitMultiplier = MaxWaitMultiplier;
- }
-
- ElapsedTimeSeconds = std::chrono::duration_cast<std::chrono::seconds>(
- std::chrono::steady_clock::now() - StartTime)
- .count();
-
- } while (ElapsedTimeSeconds < MaxSeconds);
+ }
// Give up.
return Res_Timeout;