diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2024-07-27 23:34:35 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2024-10-23 18:26:01 +0000 |
commit | 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583 (patch) | |
tree | 6cf5ab1f05330c6773b1f3f64799d56a9c7a1faa /contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp | |
parent | 6b9f7133aba44189d9625c352bc2c2a59baf18ef (diff) | |
parent | ac9a064cb179f3425b310fa2847f8764ac970a4d (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp | 48 |
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; |