resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmFileLockPool.cxx
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
5 #include <algorithm>
6 #include <cassert>
7 #include <utility>
8
9 #include "cmFileLock.h"
10 #include "cmFileLockResult.h"
11
12 cmFileLockPool::cmFileLockPool() = default;
13
14 cmFileLockPool::~cmFileLockPool() = default;
15
16 void cmFileLockPool::PushFunctionScope()
17 {
18   this->FunctionScopes.push_back(ScopePool());
19 }
20
21 void cmFileLockPool::PopFunctionScope()
22 {
23   assert(!this->FunctionScopes.empty());
24   this->FunctionScopes.pop_back();
25 }
26
27 void cmFileLockPool::PushFileScope()
28 {
29   this->FileScopes.push_back(ScopePool());
30 }
31
32 void cmFileLockPool::PopFileScope()
33 {
34   assert(!this->FileScopes.empty());
35   this->FileScopes.pop_back();
36 }
37
38 cmFileLockResult cmFileLockPool::LockFunctionScope(const std::string& filename,
39                                                    unsigned long timeoutSec)
40 {
41   if (this->IsAlreadyLocked(filename)) {
42     return cmFileLockResult::MakeAlreadyLocked();
43   }
44   if (this->FunctionScopes.empty()) {
45     return cmFileLockResult::MakeNoFunction();
46   }
47   return this->FunctionScopes.back().Lock(filename, timeoutSec);
48 }
49
50 cmFileLockResult cmFileLockPool::LockFileScope(const std::string& filename,
51                                                unsigned long timeoutSec)
52 {
53   if (this->IsAlreadyLocked(filename)) {
54     return cmFileLockResult::MakeAlreadyLocked();
55   }
56   assert(!this->FileScopes.empty());
57   return this->FileScopes.back().Lock(filename, timeoutSec);
58 }
59
60 cmFileLockResult cmFileLockPool::LockProcessScope(const std::string& filename,
61                                                   unsigned long timeoutSec)
62 {
63   if (this->IsAlreadyLocked(filename)) {
64     return cmFileLockResult::MakeAlreadyLocked();
65   }
66   return this->ProcessScope.Lock(filename, timeoutSec);
67 }
68
69 cmFileLockResult cmFileLockPool::Release(const std::string& filename)
70 {
71   for (auto& funcScope : this->FunctionScopes) {
72     const cmFileLockResult result = funcScope.Release(filename);
73     if (!result.IsOk()) {
74       return result;
75     }
76   }
77
78   for (auto& fileScope : this->FileScopes) {
79     const cmFileLockResult result = fileScope.Release(filename);
80     if (!result.IsOk()) {
81       return result;
82     }
83   }
84
85   return this->ProcessScope.Release(filename);
86 }
87
88 bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const
89 {
90   for (auto const& funcScope : this->FunctionScopes) {
91     const bool result = funcScope.IsAlreadyLocked(filename);
92     if (result) {
93       return true;
94     }
95   }
96
97   for (auto const& fileScope : this->FileScopes) {
98     const bool result = fileScope.IsAlreadyLocked(filename);
99     if (result) {
100       return true;
101     }
102   }
103
104   return this->ProcessScope.IsAlreadyLocked(filename);
105 }
106
107 cmFileLockPool::ScopePool::ScopePool() = default;
108
109 cmFileLockPool::ScopePool::~ScopePool() = default;
110
111 cmFileLockPool::ScopePool::ScopePool(ScopePool&&) noexcept = default;
112
113 cmFileLockPool::ScopePool& cmFileLockPool::ScopePool::operator=(
114   ScopePool&& other) noexcept
115 {
116   if (this != &other) {
117     this->Locks = std::move(other.Locks);
118   }
119
120   return *this;
121 }
122
123 cmFileLockResult cmFileLockPool::ScopePool::Lock(const std::string& filename,
124                                                  unsigned long timeoutSec)
125 {
126   cmFileLock lock;
127   const cmFileLockResult result = lock.Lock(filename, timeoutSec);
128   if (result.IsOk()) {
129     this->Locks.push_back(std::move(lock));
130     return cmFileLockResult::MakeOk();
131   }
132   return result;
133 }
134
135 cmFileLockResult cmFileLockPool::ScopePool::Release(
136   const std::string& filename)
137 {
138   for (auto& lock : this->Locks) {
139     if (lock.IsLocked(filename)) {
140       return lock.Release();
141     }
142   }
143   return cmFileLockResult::MakeOk();
144 }
145
146 bool cmFileLockPool::ScopePool::IsAlreadyLocked(
147   const std::string& filename) const
148 {
149   return std::any_of(this->Locks.begin(), this->Locks.end(),
150                      [&filename](cmFileLock const& lock) -> bool {
151                        return lock.IsLocked(filename);
152                      });
153 }