xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Support/LockFileManager.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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