Go to the documentation of this file.
26 #include <sys/types.h>
27 #include <system_error>
38 #if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1050)
39 #define USE_OSX_GETHOSTUUID 1
41 #define USE_OSX_GETHOSTUUID 0
44 #if USE_OSX_GETHOSTUUID
45 #include <uuid/uuid.h>
56 LockFileManager::readLockFile(
StringRef LockFileName) {
69 std::tie(Hostname, PIDStr) = getToken(MB.
getBuffer(),
" ");
73 auto Owner = std::make_pair(std::string(Hostname), PID);
74 if (processStillExecuting(Owner.first, Owner.second))
86 #if USE_OSX_GETHOSTUUID
88 struct timespec wait = {1, 0};
90 if (gethostuuid(uuid, &wait) != 0)
91 return std::error_code(errno, std::system_category());
93 uuid_string_t UUIDStr;
94 uuid_unparse(uuid, UUIDStr);
102 gethostname(HostName, 255);
111 return std::error_code();
114 bool LockFileManager::processStillExecuting(
StringRef HostID,
int PID) {
115 #if LLVM_ON_UNIX && !defined(__ANDROID__)
121 if (StoredHostID == HostID && getsid(PID) == -1 && errno == ESRCH)
137 class RemoveUniqueLockFileOnSignal {
139 bool RemoveImmediately;
142 : Filename(
Name), RemoveImmediately(
true) {
146 ~RemoveUniqueLockFileOnSignal() {
147 if (!RemoveImmediately) {
156 void lockAcquired() { RemoveImmediately =
false; }
163 this->FileName = FileName;
165 std::string
S(
"failed to obtain absolute path for ");
166 S.append(std::string(this->FileName.
str()));
170 LockFileName = this->FileName;
171 LockFileName +=
".lock";
175 if ((Owner = readLockFile(LockFileName)))
179 UniqueLockFileName = LockFileName;
180 UniqueLockFileName +=
"-%%%%%%%%";
181 int UniqueLockFileID;
183 UniqueLockFileName, UniqueLockFileID, UniqueLockFileName)) {
184 std::string
S(
"failed to create unique file ");
185 S.append(std::string(UniqueLockFileName.
str()));
194 setError(EC,
"failed to get host id");
205 std::string
S(
"failed to write to ");
206 S.append(std::string(UniqueLockFileName.
str()));
215 RemoveUniqueLockFileOnSignal RemoveUniqueFile(UniqueLockFileName);
222 RemoveUniqueFile.lockAcquired();
227 std::string
S(
"failed to create link ");
229 OSS << LockFileName.
str() <<
" to " << UniqueLockFileName.
str();
236 if ((Owner = readLockFile(LockFileName))) {
251 std::string
S(
"failed to remove lockfile ");
252 S.append(std::string(UniqueLockFileName.
str()));
271 std::string Str(ErrorDiagMsg);
272 std::string ErrCodeMsg = ErrorCode.message();
274 if (!ErrCodeMsg.empty())
275 OSS <<
": " << ErrCodeMsg;
302 const unsigned long MinWaitDurationMS = 10;
303 const unsigned long MaxWaitMultiplier = 50;
304 unsigned long WaitMultiplier = 1;
305 unsigned long ElapsedTimeSeconds = 0;
307 std::random_device Device;
308 std::default_random_engine Engine(Device());
317 std::uniform_int_distribution<unsigned long> Distribution(1,
319 unsigned long WaitDurationMS = MinWaitDurationMS * Distribution(Engine);
320 std::this_thread::sleep_for(std::chrono::milliseconds(WaitDurationMS));
331 if (!processStillExecuting((*Owner).first, (*Owner).second))
335 if (WaitMultiplier > MaxWaitMultiplier) {
336 WaitMultiplier = MaxWaitMultiplier;
339 ElapsedTimeSeconds = std::chrono::duration_cast<std::chrono::seconds>(
343 }
while (ElapsedTimeSeconds < MaxSeconds);
std::error_code unsafeRemoveLockFile()
Remove the lock file.
@ LFS_Owned
The lock file has been created and is owned by this instance of the object.
This is an optimization pass for GlobalISel generic memory operations.
void close()
Manually flush the stream and close the file.
WaitForUnlockResult
Describes the result of waiting for the owner to release the lock.
A raw_ostream that writes to an std::string.
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.
@ LFS_Shared
The lock file already exists and is owned by some other instance.
@ no_such_file_or_directory
std::error_code access(const Twine &Path, AccessMode Mode)
Can the file be accessed?
This interface provides simple read-only access to a block of memory, and provides simple methods for...
raw_ostream::uuid_t uuid_t
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
LockFileState getState() const
Determine the state of the lock file.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
std::error_code create_link(const Twine &to, const Twine &from)
Create a link from from to to.
bool has_error() const
Return the value of the flag in this raw_fd_ostream indicating whether an output error has been encou...
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
@ Res_Timeout
Reached timeout while waiting for the owner to release the lock.
void setError(const std::error_code &EC, StringRef ErrorMsg="")
Set error and error message.
StringRef getBuffer() const
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
static sys::TimePoint< std::chrono::seconds > now(bool Deterministic)
LockFileState
Describes the state of a lock file.
bool exists(const basic_file_status &status)
Does file exist?
@ Res_OwnerDied
Owner died while holding the lock.
@ LFS_Error
An error occurred while trying to create or find the lock file.
LLVM_NODISCARD 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.
void make_absolute(const Twine ¤t_directory, SmallVectorImpl< char > &path)
Make path an absolute path.
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
std::error_code error() const
StringRef - Represent a constant reference to a string, i.e.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
static std::error_code getHostID(SmallVectorImpl< char > &HostID)
WaitForUnlockResult waitForUnlock(const unsigned MaxSeconds=90)
For a shared lock, wait until the owner releases the lock.
A raw_ostream that writes to a file descriptor.
StringRef str() const
Explicit conversion to StringRef.
void DontRemoveFileOnSignal(StringRef Filename)
This function removes a file from the list of files to be removed on signal delivery.
static Pid getProcessId()
Get the process's identifier.
Represents either an error or a value T.
@ Res_Success
The lock was released successfully.
std::string & str()
Returns the string's reference.
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...
std::string getErrorMessage() const
Get error message, or "" if there is no error.