LockFileManager.h revision 276479
1234285Sdim//===--- LockFileManager.h - File-level locking utility ---------*- C++ -*-===//
2234285Sdim//
3234285Sdim//                     The LLVM Compiler Infrastructure
4234285Sdim//
5234285Sdim// This file is distributed under the University of Illinois Open Source
6234285Sdim// License. See LICENSE.TXT for details.
7234285Sdim//
8234285Sdim//===----------------------------------------------------------------------===//
9234285Sdim#ifndef LLVM_SUPPORT_LOCKFILEMANAGER_H
10234285Sdim#define LLVM_SUPPORT_LOCKFILEMANAGER_H
11234285Sdim
12234285Sdim#include "llvm/ADT/Optional.h"
13234285Sdim#include "llvm/ADT/SmallString.h"
14234285Sdim#include "llvm/ADT/StringRef.h"
15276479Sdim#include <system_error>
16234285Sdim#include <utility> // for std::pair
17234285Sdim
18234285Sdimnamespace llvm {
19234285Sdim/// \brief Class that manages the creation of a lock file to aid
20234285Sdim/// implicit coordination between different processes.
21234285Sdim///
22234285Sdim/// The implicit coordination works by creating a ".lock" file alongside
23234285Sdim/// the file that we're coordinating for, using the atomicity of the file
24234285Sdim/// system to ensure that only a single process can create that ".lock" file.
25234285Sdim/// When the lock file is removed, the owning process has finished the
26234285Sdim/// operation.
27234285Sdimclass LockFileManager {
28234285Sdimpublic:
29234285Sdim  /// \brief Describes the state of a lock file.
30234285Sdim  enum LockFileState {
31234285Sdim    /// \brief The lock file has been created and is owned by this instance
32234285Sdim    /// of the object.
33234285Sdim    LFS_Owned,
34234285Sdim    /// \brief The lock file already exists and is owned by some other
35234285Sdim    /// instance.
36234285Sdim    LFS_Shared,
37234285Sdim    /// \brief An error occurred while trying to create or find the lock
38234285Sdim    /// file.
39234285Sdim    LFS_Error
40234285Sdim  };
41234285Sdim
42276479Sdim  /// \brief Describes the result of waiting for the owner to release the lock.
43276479Sdim  enum WaitForUnlockResult {
44276479Sdim    /// \brief The lock was released successfully.
45276479Sdim    Res_Success,
46276479Sdim    /// \brief Owner died while holding the lock.
47276479Sdim    Res_OwnerDied,
48276479Sdim    /// \brief Reached timeout while waiting for the owner to release the lock.
49276479Sdim    Res_Timeout
50276479Sdim  };
51276479Sdim
52234285Sdimprivate:
53249423Sdim  SmallString<128> FileName;
54234285Sdim  SmallString<128> LockFileName;
55234285Sdim  SmallString<128> UniqueLockFileName;
56234285Sdim
57234285Sdim  Optional<std::pair<std::string, int> > Owner;
58276479Sdim  Optional<std::error_code> Error;
59234285Sdim
60243830Sdim  LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION;
61243830Sdim  LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION;
62234285Sdim
63234285Sdim  static Optional<std::pair<std::string, int> >
64234285Sdim  readLockFile(StringRef LockFileName);
65234285Sdim
66234285Sdim  static bool processStillExecuting(StringRef Hostname, int PID);
67234285Sdim
68234285Sdimpublic:
69234285Sdim
70234285Sdim  LockFileManager(StringRef FileName);
71234285Sdim  ~LockFileManager();
72234285Sdim
73234285Sdim  /// \brief Determine the state of the lock file.
74234285Sdim  LockFileState getState() const;
75234285Sdim
76234285Sdim  operator LockFileState() const { return getState(); }
77234285Sdim
78234285Sdim  /// \brief For a shared lock, wait until the owner releases the lock.
79276479Sdim  WaitForUnlockResult waitForUnlock();
80234285Sdim};
81234285Sdim
82234285Sdim} // end namespace llvm
83234285Sdim
84234285Sdim#endif // LLVM_SUPPORT_LOCKFILEMANAGER_H
85