/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/Support/LockFileManager.h
Line | Count | Source |
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 | | /// \brief 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 | | /// \brief Describes the state of a lock file. |
31 | | enum LockFileState { |
32 | | /// \brief The lock file has been created and is owned by this instance |
33 | | /// of the object. |
34 | | LFS_Owned, |
35 | | /// \brief The lock file already exists and is owned by some other |
36 | | /// instance. |
37 | | LFS_Shared, |
38 | | /// \brief An error occurred while trying to create or find the lock |
39 | | /// file. |
40 | | LFS_Error |
41 | | }; |
42 | | |
43 | | /// \brief Describes the result of waiting for the owner to release the lock. |
44 | | enum WaitForUnlockResult { |
45 | | /// \brief The lock was released successfully. |
46 | | Res_Success, |
47 | | /// \brief Owner died while holding the lock. |
48 | | Res_OwnerDied, |
49 | | /// \brief 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 | | Optional<std::error_code> Error; |
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 | | /// \brief Determine the state of the lock file. |
76 | | LockFileState getState() const; |
77 | | |
78 | 1.64k | operator LockFileState() const { return getState(); } |
79 | | |
80 | | /// \brief For a shared lock, wait until the owner releases the lock. |
81 | | WaitForUnlockResult waitForUnlock(); |
82 | | |
83 | | /// \brief 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 | | /// \brief Get error message, or "" if there is no error. |
88 | | std::string getErrorMessage() const; |
89 | | |
90 | | /// \brief Set error and error message |
91 | 10 | void setError(std::error_code &EC, StringRef ErrorMsg = "") { |
92 | 10 | Error = EC; |
93 | 10 | ErrorDiagMsg = ErrorMsg.str(); |
94 | 10 | } |
95 | | }; |
96 | | |
97 | | } // end namespace llvm |
98 | | |
99 | | #endif // LLVM_SUPPORT_LOCKFILEMANAGER_H |