Line data Source code
1 : //===--- LockFileManager.h - File-level locking utility ---------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : #ifndef LLVM_SUPPORT_LOCKFILEMANAGER_H
10 : #define LLVM_SUPPORT_LOCKFILEMANAGER_H
11 :
12 : #include "llvm/ADT/Optional.h"
13 : #include "llvm/ADT/SmallString.h"
14 : #include <system_error>
15 : #include <utility> // for std::pair
16 :
17 : namespace llvm {
18 : class StringRef;
19 :
20 : /// Class that manages the creation of a lock file to aid
21 : /// implicit coordination between different processes.
22 : ///
23 : /// The implicit coordination works by creating a ".lock" file alongside
24 : /// the file that we're coordinating for, using the atomicity of the file
25 : /// system to ensure that only a single process can create that ".lock" file.
26 : /// When the lock file is removed, the owning process has finished the
27 : /// operation.
28 : class LockFileManager {
29 : public:
30 : /// Describes the state of a lock file.
31 : enum LockFileState {
32 : /// The lock file has been created and is owned by this instance
33 : /// of the object.
34 : LFS_Owned,
35 : /// The lock file already exists and is owned by some other
36 : /// instance.
37 : LFS_Shared,
38 : /// An error occurred while trying to create or find the lock
39 : /// file.
40 : LFS_Error
41 : };
42 :
43 : /// Describes the result of waiting for the owner to release the lock.
44 : enum WaitForUnlockResult {
45 : /// The lock was released successfully.
46 : Res_Success,
47 : /// Owner died while holding the lock.
48 : Res_OwnerDied,
49 : /// Reached timeout while waiting for the owner to release the lock.
50 : Res_Timeout
51 : };
52 :
53 : private:
54 : SmallString<128> FileName;
55 : SmallString<128> LockFileName;
56 : SmallString<128> UniqueLockFileName;
57 :
58 : Optional<std::pair<std::string, int> > Owner;
59 : std::error_code ErrorCode;
60 : std::string ErrorDiagMsg;
61 :
62 : LockFileManager(const LockFileManager &) = delete;
63 : LockFileManager &operator=(const LockFileManager &) = delete;
64 :
65 : static Optional<std::pair<std::string, int> >
66 : readLockFile(StringRef LockFileName);
67 :
68 : static bool processStillExecuting(StringRef Hostname, int PID);
69 :
70 : public:
71 :
72 : LockFileManager(StringRef FileName);
73 : ~LockFileManager();
74 :
75 : /// Determine the state of the lock file.
76 : LockFileState getState() const;
77 :
78 1762 : operator LockFileState() const { return getState(); }
79 :
80 : /// For a shared lock, wait until the owner releases the lock.
81 : WaitForUnlockResult waitForUnlock();
82 :
83 : /// Remove the lock file. This may delete a different lock file than
84 : /// the one previously read if there is a race.
85 : std::error_code unsafeRemoveLockFile();
86 :
87 : /// Get error message, or "" if there is no error.
88 : std::string getErrorMessage() const;
89 :
90 : /// Set error and error message
91 0 : void setError(const std::error_code &EC, StringRef ErrorMsg = "") {
92 0 : ErrorCode = EC;
93 0 : ErrorDiagMsg = ErrorMsg.str();
94 0 : }
95 : };
96 :
97 : } // end namespace llvm
98 :
99 : #endif // LLVM_SUPPORT_LOCKFILEMANAGER_H
|