195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor//===--- LockFileManager.h - File-level locking utility ---------*- C++ -*-===// 295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// 395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// The LLVM Compiler Infrastructure 495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// 595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// This file is distributed under the University of Illinois Open Source 695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// License. See LICENSE.TXT for details. 795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor// 895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor//===----------------------------------------------------------------------===// 995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#ifndef LLVM_SUPPORT_LOCKFILEMANAGER_H 1095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#define LLVM_SUPPORT_LOCKFILEMANAGER_H 1195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 1295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include "llvm/ADT/Optional.h" 1395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include "llvm/ADT/SmallString.h" 1495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include "llvm/ADT/StringRef.h" 1595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include "llvm/Support/system_error.h" 1695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#include <utility> // for std::pair 1795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 1895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregornamespace llvm { 1995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 2095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// \brief Class that manages the creation of a lock file to aid 2195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// implicit coordination between different processes. 2295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// 2395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// The implicit coordination works by creating a ".lock" file alongside 2495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// the file that we're coordinating for, using the atomicity of the file 2595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// system to ensure that only a single process can create that ".lock" file. 2695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// When the lock file is removed, the owning process has finished the 2795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor/// operation. 2895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregorclass LockFileManager { 2995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregorpublic: 3095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor /// \brief Describes the state of a lock file. 3195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor enum LockFileState { 3295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor /// \brief The lock file has been created and is owned by this instance 3395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor /// of the object. 3495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor LFS_Owned, 3595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor /// \brief The lock file already exists and is owned by some other 3695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor /// instance. 3795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor LFS_Shared, 3895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor /// \brief An error occurred while trying to create or find the lock 3995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor /// file. 4095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor LFS_Error 4195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor }; 4295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 4395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregorprivate: 4495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor SmallString<128> LockFileName; 4595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor SmallString<128> UniqueLockFileName; 4695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 4795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Optional<std::pair<std::string, int> > Owner; 4895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor Optional<error_code> Error; 4995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 5095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor LockFileManager(const LockFileManager &); 5195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor LockFileManager &operator=(const LockFileManager &); 5295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 5395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor static Optional<std::pair<std::string, int> > 5495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor readLockFile(StringRef LockFileName); 5595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 5695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor static bool processStillExecuting(StringRef Hostname, int PID); 5795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 5895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregorpublic: 5995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 6095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor LockFileManager(StringRef FileName); 6195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor ~LockFileManager(); 6295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 6395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor /// \brief Determine the state of the lock file. 6495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor LockFileState getState() const; 6595fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 6695fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor operator LockFileState() const { return getState(); } 6795fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 6895fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor /// \brief For a shared lock, wait until the owner releases the lock. 6995fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor void waitForUnlock(); 7095fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor}; 7195fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 7295fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor} // end namespace llvm 7395fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor 7495fa4005f5aa99878c4053e95b230f0b8b6a4d6dDouglas Gregor#endif // LLVM_SUPPORT_LOCKFILEMANAGER_H 75