Coverage Report

Created: 2026-02-09 06:05

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