LockFileManager.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. //===--- LockFileManager.h - File-level locking utility ---------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLVM_SUPPORT_LOCKFILEMANAGER_H
  9. #define LLVM_SUPPORT_LOCKFILEMANAGER_H
  10. #include "llvm/ADT/Optional.h"
  11. #include "llvm/ADT/SmallString.h"
  12. #include <system_error>
  13. #include <utility> // for std::pair
  14. namespace llvm {
  15. class StringRef;
  16. /// Class that manages the creation of a lock file to aid
  17. /// implicit coordination between different processes.
  18. ///
  19. /// The implicit coordination works by creating a ".lock" file alongside
  20. /// the file that we're coordinating for, using the atomicity of the file
  21. /// system to ensure that only a single process can create that ".lock" file.
  22. /// When the lock file is removed, the owning process has finished the
  23. /// operation.
  24. class LockFileManager {
  25. public:
  26. /// Describes the state of a lock file.
  27. enum LockFileState {
  28. /// The lock file has been created and is owned by this instance
  29. /// of the object.
  30. LFS_Owned,
  31. /// The lock file already exists and is owned by some other
  32. /// instance.
  33. LFS_Shared,
  34. /// An error occurred while trying to create or find the lock
  35. /// file.
  36. LFS_Error
  37. };
  38. /// Describes the result of waiting for the owner to release the lock.
  39. enum WaitForUnlockResult {
  40. /// The lock was released successfully.
  41. Res_Success,
  42. /// Owner died while holding the lock.
  43. Res_OwnerDied,
  44. /// Reached timeout while waiting for the owner to release the lock.
  45. Res_Timeout
  46. };
  47. private:
  48. SmallString<128> FileName;
  49. SmallString<128> LockFileName;
  50. SmallString<128> UniqueLockFileName;
  51. Optional<std::pair<std::string, int> > Owner;
  52. std::error_code ErrorCode;
  53. std::string ErrorDiagMsg;
  54. LockFileManager(const LockFileManager &) = delete;
  55. LockFileManager &operator=(const LockFileManager &) = delete;
  56. static Optional<std::pair<std::string, int> >
  57. readLockFile(StringRef LockFileName);
  58. static bool processStillExecuting(StringRef Hostname, int PID);
  59. public:
  60. LockFileManager(StringRef FileName);
  61. ~LockFileManager();
  62. /// Determine the state of the lock file.
  63. LockFileState getState() const;
  64. operator LockFileState() const { return getState(); }
  65. /// For a shared lock, wait until the owner releases the lock.
  66. /// Total timeout for the file to appear is ~1.5 minutes.
  67. /// \param MaxSeconds the maximum total wait time in seconds.
  68. WaitForUnlockResult waitForUnlock(const unsigned MaxSeconds = 90);
  69. /// Remove the lock file. This may delete a different lock file than
  70. /// the one previously read if there is a race.
  71. std::error_code unsafeRemoveLockFile();
  72. /// Get error message, or "" if there is no error.
  73. std::string getErrorMessage() const;
  74. /// Set error and error message
  75. void setError(const std::error_code &EC, StringRef ErrorMsg = "") {
  76. ErrorCode = EC;
  77. ErrorDiagMsg = ErrorMsg.str();
  78. }
  79. };
  80. } // end namespace llvm
  81. #endif // LLVM_SUPPORT_LOCKFILEMANAGER_H