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 "llvm/ADT/StringRef.h"
15#include <system_error>
16#include <utility> // for std::pair
17
18namespace llvm {
19/// \brief Class that manages the creation of a lock file to aid
20/// implicit coordination between different processes.
21///
22/// The implicit coordination works by creating a ".lock" file alongside
23/// the file that we're coordinating for, using the atomicity of the file
24/// system to ensure that only a single process can create that ".lock" file.
25/// When the lock file is removed, the owning process has finished the
26/// operation.
27class LockFileManager {
28public:
29  /// \brief Describes the state of a lock file.
30  enum LockFileState {
31    /// \brief The lock file has been created and is owned by this instance
32    /// of the object.
33    LFS_Owned,
34    /// \brief The lock file already exists and is owned by some other
35    /// instance.
36    LFS_Shared,
37    /// \brief An error occurred while trying to create or find the lock
38    /// file.
39    LFS_Error
40  };
41
42  /// \brief Describes the result of waiting for the owner to release the lock.
43  enum WaitForUnlockResult {
44    /// \brief The lock was released successfully.
45    Res_Success,
46    /// \brief Owner died while holding the lock.
47    Res_OwnerDied,
48    /// \brief Reached timeout while waiting for the owner to release the lock.
49    Res_Timeout
50  };
51
52private:
53  SmallString<128> FileName;
54  SmallString<128> LockFileName;
55  SmallString<128> UniqueLockFileName;
56
57  Optional<std::pair<std::string, int> > Owner;
58  Optional<std::error_code> Error;
59
60  LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION;
61  LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION;
62
63  static Optional<std::pair<std::string, int> >
64  readLockFile(StringRef LockFileName);
65
66  static bool processStillExecuting(StringRef Hostname, int PID);
67
68public:
69
70  LockFileManager(StringRef FileName);
71  ~LockFileManager();
72
73  /// \brief Determine the state of the lock file.
74  LockFileState getState() const;
75
76  operator LockFileState() const { return getState(); }
77
78  /// \brief For a shared lock, wait until the owner releases the lock.
79  WaitForUnlockResult waitForUnlock();
80};
81
82} // end namespace llvm
83
84#endif // LLVM_SUPPORT_LOCKFILEMANAGER_H
85