1 //===--- LockFileManager.h - File-level locking utility ---------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 #ifndef LLVM_SUPPORT_LOCKFILEMANAGER_H 9 #define LLVM_SUPPORT_LOCKFILEMANAGER_H 10 11 #include "llvm/ADT/SmallString.h" 12 #include "llvm/ADT/StringRef.h" 13 #include "llvm/Support/AdvisoryLock.h" 14 #include "llvm/Support/Compiler.h" 15 #include <optional> 16 #include <string> 17 #include <variant> 18 19 namespace llvm { 20 /// Class that manages the creation of a lock file to aid implicit coordination 21 /// between different processes. 22 /// 23 /// The implicit coordination works by creating a ".lock" file, using the 24 /// atomicity of the file system to ensure that only a single process can create 25 /// that ".lock" file. When the lock file is removed, the owning process has 26 /// finished the operation. 27 class LLVM_ABI LockFileManager : public AdvisoryLock { 28 SmallString<128> FileName; 29 SmallString<128> LockFileName; 30 SmallString<128> UniqueLockFileName; 31 32 struct OwnerUnknown {}; 33 struct OwnedByUs {}; 34 struct OwnedByAnother { 35 std::string OwnerHostName; 36 int OwnerPID; 37 }; 38 std::variant<OwnerUnknown, OwnedByUs, OwnedByAnother> Owner; 39 40 LockFileManager(const LockFileManager &) = delete; 41 LockFileManager &operator=(const LockFileManager &) = delete; 42 43 static std::optional<OwnedByAnother> readLockFile(StringRef LockFileName); 44 45 static bool processStillExecuting(StringRef Hostname, int PID); 46 47 public: 48 /// Does not try to acquire the lock. 49 LockFileManager(StringRef FileName); 50 51 /// Tries to acquire the lock without blocking. 52 /// \returns true if the lock was successfully acquired, false if the lock is 53 /// already held by someone else, or \c Error in case of unexpected failure. 54 Expected<bool> tryLock() override; 55 56 /// For a shared lock, wait until the owner releases the lock. 57 /// 58 /// \param MaxSeconds the maximum total wait time in seconds. 59 WaitForUnlockResult 60 waitForUnlockFor(std::chrono::seconds MaxSeconds) override; 61 62 /// Remove the lock file. This may delete a different lock file than 63 /// the one previously read if there is a race. 64 std::error_code unsafeMaybeUnlock() override; 65 66 /// Unlocks the lock if previously acquired by \c tryLock(). 67 ~LockFileManager() override; 68 }; 69 } // end namespace llvm 70 71 #endif // LLVM_SUPPORT_LOCKFILEMANAGER_H 72