LLVM API Documentation

LockFileManager.h
Go to the documentation of this file.
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