12#include "llvm/Config/llvm-config.h"
27#include <system_error>
39#if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1050)
40#define USE_OSX_GETHOSTUUID 1
42#define USE_OSX_GETHOSTUUID 0
45#if USE_OSX_GETHOSTUUID
56std::optional<LockFileManager::OwnedByAnother>
57LockFileManager::readLockFile(
StringRef LockFileName) {
75 Owner.OwnerHostName = Hostname;
77 if (processStillExecuting(
Owner.OwnerHostName,
Owner.OwnerPID))
93#if USE_OSX_GETHOSTUUID
95 struct timespec wait = {1, 0};
97 if (gethostuuid(uuid, &wait) != 0)
100 uuid_string_t UUIDStr;
101 uuid_unparse(uuid, UUIDStr);
109 gethostname(HostName, 255);
114 wchar_t HostName[256];
115 DWORD
Size =
static_cast<DWORD
>(std::size(HostName));
116 if (!::GetComputerNameExW(ComputerNamePhysicalDnsHostname, HostName, &
Size))
118 std::string HostNameUTF8;
120 return std::make_error_code(std::errc::illegal_byte_sequence);
121 HostID.
append(HostNameUTF8.begin(), HostNameUTF8.end());
128 return std::error_code();
131bool LockFileManager::processStillExecuting(
StringRef HostID,
int PID) {
132#if LLVM_ON_UNIX && !defined(__ANDROID__)
133 SmallString<256> StoredHostID;
138 if (StoredHostID == HostID && getsid(PID) == -1 && errno == ESRCH)
141 SmallString<256> StoredHostID;
144 if (StoredHostID != HostID)
151 ::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION,
152 FALSE,
static_cast<DWORD>(PID));
156 return ::GetLastError() != ERROR_INVALID_PARAMETER;
162 ::GetExitCodeProcess(Process, &ExitCode) && ExitCode != STILL_ACTIVE;
163 ::CloseHandle(Process);
179class RemoveUniqueLockFileOnSignal {
181 bool RemoveImmediately;
183 RemoveUniqueLockFileOnSignal(StringRef Name)
188 ~RemoveUniqueLockFileOnSignal() {
189 if (!RemoveImmediately) {
198 void lockAcquired() { RemoveImmediately =
false; }
204 : FileName(FileName), Owner(OwnerUnknown{}) {}
209 assert(std::holds_alternative<OwnerUnknown>(Owner) &&
210 "lock has already been attempted");
216 LockFileName = AbsoluteFileName;
217 LockFileName +=
".lock";
221 if (
auto LockFileOwner = readLockFile(LockFileName)) {
222 Owner = std::move(*LockFileOwner);
227 int UniqueLockFileID;
230 UniqueLockFilePattern +=
"-%%%%%%%%";
233 UniqueLockFilePattern, UniqueLockFileID, UniquePath);
239 "failed to create lock directory " + Dir);
249 "failed to create unique file " + UniquePath);
251 UniqueLockFileName = UniquePath;
255 RemoveUniqueLockFileOnSignal RemoveUniqueFile(UniqueLockFileName);
267 if (Out.has_error()) {
270 "failed to write to " + UniqueLockFileName);
273 return std::move(Err);
282 RemoveUniqueFile.lockAcquired();
289 " to " + UniqueLockFileName);
293 if (
auto LockFileOwner = readLockFile(LockFileName)) {
294 Owner = std::move(*LockFileOwner);
315 if (!std::holds_alternative<OwnedByUs>(Owner))
330 auto *LockFileOwner = std::get_if<OwnedByAnother>(&Owner);
332 "waiting for lock to be unlocked without knowing the owner");
338 using namespace std::chrono_literals;
349 if (!processStillExecuting(LockFileOwner->OwnerHostName,
350 LockFileOwner->OwnerPID))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static ManagedStatic< DebugCounterOwner > Owner
Provides ErrorOr<T> smart pointer.
static std::error_code getHostID(SmallVectorImpl< char > &HostID)
Get an identifier for this machine.
static constexpr StringLiteral Filename
Provides a library for accessing information about this process and other processes on the operating ...
This file defines the SmallVector class.
Represents either an error or a value T.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
A class to help implement exponential backoff.
LLVM_ABI bool waitForNextAttempt()
Blocks while waiting for the next attempt.
std::error_code unsafeUnlock() override
Remove the lock file.
WaitForUnlockResult waitForUnlockFor(std::chrono::seconds MaxSeconds) override
For a shared lock, wait until the owner releases the lock.
Expected< bool > tryLock() override
Tries to acquire the lock without blocking.
~LockFileManager() override
Unlocks the lock if previously acquired by tryLock().
This interface provides simple read-only access to a block of memory, and provides simple methods for...
StringRef getBuffer() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
LLVM_ABI size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
A raw_ostream that writes to a file descriptor.
static LLVM_ABI Pid getProcessId()
Get the process's identifier.
LLVM_ABI std::error_code access(const Twine &Path, AccessMode Mode)
Can the file be accessed?
LLVM_ABI bool exists(const basic_file_status &status)
Does file exist?
LLVM_ABI std::error_code create_link(const Twine &to, const Twine &from)
Create a link from from to to.
LLVM_ABI std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None, unsigned Mode=all_read|all_write)
Create a uniquely named file.
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
LLVM_ABI std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
LLVM_ABI std::error_code make_absolute(SmallVectorImpl< char > &path)
Make path an absolute path.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
ScopedSetting scopedDisable()
LLVM_ABI void DontRemoveFileOnSignal(StringRef Filename)
This function removes a file from the list of files to be removed on signal delivery.
LLVM_ABI bool RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg=nullptr)
This function registers signal handlers to ensure that if a signal gets delivered that the named file...
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
LLVM_ABI bool convertWideToUTF8(std::wstring_view Source, std::string &Result)
Converts a wide string view to a UTF-8 encoded std::string.
@ no_such_file_or_directory
WaitForUnlockResult
Describes the result of waiting for the owner to release the lock.
@ Success
The lock was released successfully.
@ OwnerDied
Owner died while holding the lock.
@ Timeout
Reached timeout while waiting for the owner to release the lock.
LLVM_ABI std::error_code mapWindowsError(unsigned EV)
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.