LLVM API Documentation
00001 //===--- LockFileManager.h - File-level locking utility ---------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 #ifndef LLVM_SUPPORT_LOCKFILEMANAGER_H 00010 #define LLVM_SUPPORT_LOCKFILEMANAGER_H 00011 00012 #include "llvm/ADT/Optional.h" 00013 #include "llvm/ADT/SmallString.h" 00014 #include "llvm/ADT/StringRef.h" 00015 #include <system_error> 00016 #include <utility> // for std::pair 00017 00018 namespace llvm { 00019 /// \brief Class that manages the creation of a lock file to aid 00020 /// implicit coordination between different processes. 00021 /// 00022 /// The implicit coordination works by creating a ".lock" file alongside 00023 /// the file that we're coordinating for, using the atomicity of the file 00024 /// system to ensure that only a single process can create that ".lock" file. 00025 /// When the lock file is removed, the owning process has finished the 00026 /// operation. 00027 class LockFileManager { 00028 public: 00029 /// \brief Describes the state of a lock file. 00030 enum LockFileState { 00031 /// \brief The lock file has been created and is owned by this instance 00032 /// of the object. 00033 LFS_Owned, 00034 /// \brief The lock file already exists and is owned by some other 00035 /// instance. 00036 LFS_Shared, 00037 /// \brief An error occurred while trying to create or find the lock 00038 /// file. 00039 LFS_Error 00040 }; 00041 00042 /// \brief Describes the result of waiting for the owner to release the lock. 00043 enum WaitForUnlockResult { 00044 /// \brief The lock was released successfully. 00045 Res_Success, 00046 /// \brief Owner died while holding the lock. 00047 Res_OwnerDied, 00048 /// \brief Reached timeout while waiting for the owner to release the lock. 00049 Res_Timeout 00050 }; 00051 00052 private: 00053 SmallString<128> FileName; 00054 SmallString<128> LockFileName; 00055 SmallString<128> UniqueLockFileName; 00056 00057 Optional<std::pair<std::string, int> > Owner; 00058 Optional<std::error_code> Error; 00059 00060 LockFileManager(const LockFileManager &) LLVM_DELETED_FUNCTION; 00061 LockFileManager &operator=(const LockFileManager &) LLVM_DELETED_FUNCTION; 00062 00063 static Optional<std::pair<std::string, int> > 00064 readLockFile(StringRef LockFileName); 00065 00066 static bool processStillExecuting(StringRef Hostname, int PID); 00067 00068 public: 00069 00070 LockFileManager(StringRef FileName); 00071 ~LockFileManager(); 00072 00073 /// \brief Determine the state of the lock file. 00074 LockFileState getState() const; 00075 00076 operator LockFileState() const { return getState(); } 00077 00078 /// \brief For a shared lock, wait until the owner releases the lock. 00079 WaitForUnlockResult waitForUnlock(); 00080 }; 00081 00082 } // end namespace llvm 00083 00084 #endif // LLVM_SUPPORT_LOCKFILEMANAGER_H