| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying | |
| file LICENSE.rst or https://cmake.org/licensing for details. */ | |
| #include "cmFileLockPool.h" | |
| #include <algorithm> | |
| #include <cassert> | |
| #include <utility> | |
| #include "cmFileLock.h" | |
| #include "cmFileLockResult.h" | |
| cmFileLockPool::cmFileLockPool() = default; | |
| cmFileLockPool::~cmFileLockPool() = default; | |
| void cmFileLockPool::PushFunctionScope() | |
| { | |
| this->FunctionScopes.emplace_back(); | |
| } | |
| void cmFileLockPool::PopFunctionScope() | |
| { | |
| assert(!this->FunctionScopes.empty()); | |
| this->FunctionScopes.pop_back(); | |
| } | |
| void cmFileLockPool::PushFileScope() | |
| { | |
| this->FileScopes.emplace_back(); | |
| } | |
| void cmFileLockPool::PopFileScope() | |
| { | |
| assert(!this->FileScopes.empty()); | |
| this->FileScopes.pop_back(); | |
| } | |
| cmFileLockResult cmFileLockPool::LockFunctionScope(std::string const& filename, | |
| unsigned long timeoutSec) | |
| { | |
| if (this->IsAlreadyLocked(filename)) { | |
| return cmFileLockResult::MakeAlreadyLocked(); | |
| } | |
| if (this->FunctionScopes.empty()) { | |
| return cmFileLockResult::MakeNoFunction(); | |
| } | |
| return this->FunctionScopes.back().Lock(filename, timeoutSec); | |
| } | |
| cmFileLockResult cmFileLockPool::LockFileScope(std::string const& filename, | |
| unsigned long timeoutSec) | |
| { | |
| if (this->IsAlreadyLocked(filename)) { | |
| return cmFileLockResult::MakeAlreadyLocked(); | |
| } | |
| assert(!this->FileScopes.empty()); | |
| return this->FileScopes.back().Lock(filename, timeoutSec); | |
| } | |
| cmFileLockResult cmFileLockPool::LockProcessScope(std::string const& filename, | |
| unsigned long timeoutSec) | |
| { | |
| if (this->IsAlreadyLocked(filename)) { | |
| return cmFileLockResult::MakeAlreadyLocked(); | |
| } | |
| return this->ProcessScope.Lock(filename, timeoutSec); | |
| } | |
| cmFileLockResult cmFileLockPool::Release(std::string const& filename) | |
| { | |
| for (auto& funcScope : this->FunctionScopes) { | |
| cmFileLockResult const result = funcScope.Release(filename); | |
| if (!result.IsOk()) { | |
| return result; | |
| } | |
| } | |
| for (auto& fileScope : this->FileScopes) { | |
| cmFileLockResult const result = fileScope.Release(filename); | |
| if (!result.IsOk()) { | |
| return result; | |
| } | |
| } | |
| return this->ProcessScope.Release(filename); | |
| } | |
| bool cmFileLockPool::IsAlreadyLocked(std::string const& filename) const | |
| { | |
| for (auto const& funcScope : this->FunctionScopes) { | |
| bool const result = funcScope.IsAlreadyLocked(filename); | |
| if (result) { | |
| return true; | |
| } | |
| } | |
| for (auto const& fileScope : this->FileScopes) { | |
| bool const result = fileScope.IsAlreadyLocked(filename); | |
| if (result) { | |
| return true; | |
| } | |
| } | |
| return this->ProcessScope.IsAlreadyLocked(filename); | |
| } | |
| cmFileLockPool::ScopePool::ScopePool() = default; | |
| cmFileLockPool::ScopePool::~ScopePool() = default; | |
| cmFileLockPool::ScopePool::ScopePool(ScopePool&&) noexcept = default; | |
| cmFileLockPool::ScopePool& cmFileLockPool::ScopePool::operator=( | |
| ScopePool&& other) noexcept | |
| { | |
| if (this != &other) { | |
| this->Locks = std::move(other.Locks); | |
| } | |
| return *this; | |
| } | |
| cmFileLockResult cmFileLockPool::ScopePool::Lock(std::string const& filename, | |
| unsigned long timeoutSec) | |
| { | |
| cmFileLock lock; | |
| cmFileLockResult const result = lock.Lock(filename, timeoutSec); | |
| if (result.IsOk()) { | |
| this->Locks.push_back(std::move(lock)); | |
| return cmFileLockResult::MakeOk(); | |
| } | |
| return result; | |
| } | |
| cmFileLockResult cmFileLockPool::ScopePool::Release( | |
| std::string const& filename) | |
| { | |
| for (auto& lock : this->Locks) { | |
| if (lock.IsLocked(filename)) { | |
| return lock.Release(); | |
| } | |
| } | |
| return cmFileLockResult::MakeOk(); | |
| } | |
| bool cmFileLockPool::ScopePool::IsAlreadyLocked( | |
| std::string const& filename) const | |
| { | |
| return std::any_of(this->Locks.begin(), this->Locks.end(), | |
| [&filename](cmFileLock const& lock) -> bool { | |
| return lock.IsLocked(filename); | |
| }); | |
| } |