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