cmFileLockPool.cxx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmFileLockPool.h"
  4. #include <cassert>
  5. #include <utility>
  6. #include "cmFileLock.h"
  7. #include "cmFileLockResult.h"
  8. cmFileLockPool::cmFileLockPool() = default;
  9. cmFileLockPool::~cmFileLockPool() = default;
  10. void cmFileLockPool::PushFunctionScope()
  11. {
  12. this->FunctionScopes.push_back(ScopePool());
  13. }
  14. void cmFileLockPool::PopFunctionScope()
  15. {
  16. assert(!this->FunctionScopes.empty());
  17. this->FunctionScopes.pop_back();
  18. }
  19. void cmFileLockPool::PushFileScope()
  20. {
  21. this->FileScopes.push_back(ScopePool());
  22. }
  23. void cmFileLockPool::PopFileScope()
  24. {
  25. assert(!this->FileScopes.empty());
  26. this->FileScopes.pop_back();
  27. }
  28. cmFileLockResult cmFileLockPool::LockFunctionScope(const std::string& filename,
  29. unsigned long timeoutSec)
  30. {
  31. if (this->IsAlreadyLocked(filename)) {
  32. return cmFileLockResult::MakeAlreadyLocked();
  33. }
  34. if (this->FunctionScopes.empty()) {
  35. return cmFileLockResult::MakeNoFunction();
  36. }
  37. return this->FunctionScopes.back().Lock(filename, timeoutSec);
  38. }
  39. cmFileLockResult cmFileLockPool::LockFileScope(const std::string& filename,
  40. unsigned long timeoutSec)
  41. {
  42. if (this->IsAlreadyLocked(filename)) {
  43. return cmFileLockResult::MakeAlreadyLocked();
  44. }
  45. assert(!this->FileScopes.empty());
  46. return this->FileScopes.back().Lock(filename, timeoutSec);
  47. }
  48. cmFileLockResult cmFileLockPool::LockProcessScope(const std::string& filename,
  49. unsigned long timeoutSec)
  50. {
  51. if (this->IsAlreadyLocked(filename)) {
  52. return cmFileLockResult::MakeAlreadyLocked();
  53. }
  54. return this->ProcessScope.Lock(filename, timeoutSec);
  55. }
  56. cmFileLockResult cmFileLockPool::Release(const std::string& filename)
  57. {
  58. for (auto& funcScope : this->FunctionScopes) {
  59. const cmFileLockResult result = funcScope.Release(filename);
  60. if (!result.IsOk()) {
  61. return result;
  62. }
  63. }
  64. for (auto& fileScope : this->FileScopes) {
  65. const cmFileLockResult result = fileScope.Release(filename);
  66. if (!result.IsOk()) {
  67. return result;
  68. }
  69. }
  70. return this->ProcessScope.Release(filename);
  71. }
  72. bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const
  73. {
  74. for (auto const& funcScope : this->FunctionScopes) {
  75. const bool result = funcScope.IsAlreadyLocked(filename);
  76. if (result) {
  77. return true;
  78. }
  79. }
  80. for (auto const& fileScope : this->FileScopes) {
  81. const bool result = fileScope.IsAlreadyLocked(filename);
  82. if (result) {
  83. return true;
  84. }
  85. }
  86. return this->ProcessScope.IsAlreadyLocked(filename);
  87. }
  88. cmFileLockPool::ScopePool::ScopePool() = default;
  89. cmFileLockPool::ScopePool::~ScopePool() = default;
  90. cmFileLockPool::ScopePool::ScopePool(ScopePool&&) noexcept = default;
  91. cmFileLockPool::ScopePool& cmFileLockPool::ScopePool::operator=(
  92. ScopePool&& other) noexcept
  93. {
  94. if (this != &other) {
  95. this->Locks = std::move(other.Locks);
  96. }
  97. return *this;
  98. }
  99. cmFileLockResult cmFileLockPool::ScopePool::Lock(const std::string& filename,
  100. unsigned long timeoutSec)
  101. {
  102. cmFileLock lock;
  103. const cmFileLockResult result = lock.Lock(filename, timeoutSec);
  104. if (result.IsOk()) {
  105. this->Locks.push_back(std::move(lock));
  106. return cmFileLockResult::MakeOk();
  107. }
  108. return result;
  109. }
  110. cmFileLockResult cmFileLockPool::ScopePool::Release(
  111. const std::string& filename)
  112. {
  113. for (auto& lock : this->Locks) {
  114. if (lock.IsLocked(filename)) {
  115. return lock.Release();
  116. }
  117. }
  118. return cmFileLockResult::MakeOk();
  119. }
  120. bool cmFileLockPool::ScopePool::IsAlreadyLocked(
  121. const std::string& filename) const
  122. {
  123. for (auto const& lock : this->Locks) {
  124. if (lock.IsLocked(filename)) {
  125. return true;
  126. }
  127. }
  128. return false;
  129. }