cmFileLockPool.cxx 3.79 KB
Newer Older
1 2
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
3 4 5 6
#include "cmFileLockPool.h"

#include <assert.h>

7
#include "cmAlgorithms.h"
8 9 10
#include "cmFileLock.h"
#include "cmFileLockResult.h"

wahikihiki's avatar
wahikihiki committed
11
cmFileLockPool::cmFileLockPool() = default;
12 13 14

cmFileLockPool::~cmFileLockPool()
{
15 16
  cmDeleteAll(this->FunctionScopes);
  cmDeleteAll(this->FileScopes);
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
}

void cmFileLockPool::PushFunctionScope()
{
  this->FunctionScopes.push_back(new ScopePool());
}

void cmFileLockPool::PopFunctionScope()
{
  assert(!this->FunctionScopes.empty());
  delete this->FunctionScopes.back();
  this->FunctionScopes.pop_back();
}

void cmFileLockPool::PushFileScope()
{
  this->FileScopes.push_back(new ScopePool());
}

void cmFileLockPool::PopFileScope()
{
  assert(!this->FileScopes.empty());
  delete this->FileScopes.back();
  this->FileScopes.pop_back();
}

43 44
cmFileLockResult cmFileLockPool::LockFunctionScope(const std::string& filename,
                                                   unsigned long timeoutSec)
45
{
46
  if (this->IsAlreadyLocked(filename)) {
47
    return cmFileLockResult::MakeAlreadyLocked();
48 49
  }
  if (this->FunctionScopes.empty()) {
50
    return cmFileLockResult::MakeNoFunction();
51
  }
52 53 54
  return this->FunctionScopes.back()->Lock(filename, timeoutSec);
}

55 56
cmFileLockResult cmFileLockPool::LockFileScope(const std::string& filename,
                                               unsigned long timeoutSec)
57
{
58
  if (this->IsAlreadyLocked(filename)) {
59
    return cmFileLockResult::MakeAlreadyLocked();
60
  }
61 62 63 64
  assert(!this->FileScopes.empty());
  return this->FileScopes.back()->Lock(filename, timeoutSec);
}

65 66
cmFileLockResult cmFileLockPool::LockProcessScope(const std::string& filename,
                                                  unsigned long timeoutSec)
67
{
68
  if (this->IsAlreadyLocked(filename)) {
69
    return cmFileLockResult::MakeAlreadyLocked();
70
  }
71 72 73 74 75
  return this->ProcessScope.Lock(filename, timeoutSec);
}

cmFileLockResult cmFileLockPool::Release(const std::string& filename)
{
76 77
  for (auto& funcScope : this->FunctionScopes) {
    const cmFileLockResult result = funcScope->Release(filename);
78
    if (!result.IsOk()) {
79 80
      return result;
    }
81
  }
82

83 84
  for (auto& fileScope : this->FileScopes) {
    const cmFileLockResult result = fileScope->Release(filename);
85
    if (!result.IsOk()) {
86 87
      return result;
    }
88
  }
89 90 91 92 93 94

  return this->ProcessScope.Release(filename);
}

bool cmFileLockPool::IsAlreadyLocked(const std::string& filename) const
{
95 96
  for (auto const& funcScope : this->FunctionScopes) {
    const bool result = funcScope->IsAlreadyLocked(filename);
97
    if (result) {
98 99
      return true;
    }
100
  }
101

102 103
  for (auto const& fileScope : this->FileScopes) {
    const bool result = fileScope->IsAlreadyLocked(filename);
104
    if (result) {
105 106
      return true;
    }
107
  }
108 109 110 111

  return this->ProcessScope.IsAlreadyLocked(filename);
}

wahikihiki's avatar
wahikihiki committed
112
cmFileLockPool::ScopePool::ScopePool() = default;
113 114 115

cmFileLockPool::ScopePool::~ScopePool()
{
116
  cmDeleteAll(this->Locks);
117 118
}

119 120
cmFileLockResult cmFileLockPool::ScopePool::Lock(const std::string& filename,
                                                 unsigned long timeoutSec)
121
{
122
  cmFileLock* lock = new cmFileLock();
123
  const cmFileLockResult result = lock->Lock(filename, timeoutSec);
124
  if (result.IsOk()) {
125 126
    this->Locks.push_back(lock);
    return cmFileLockResult::MakeOk();
127
  }
128 129
  delete lock;
  return result;
130 131 132
}

cmFileLockResult cmFileLockPool::ScopePool::Release(
133
  const std::string& filename)
134
{
135 136 137
  for (auto& lock : this->Locks) {
    if (lock->IsLocked(filename)) {
      return lock->Release();
138
    }
139
  }
140 141 142 143
  return cmFileLockResult::MakeOk();
}

bool cmFileLockPool::ScopePool::IsAlreadyLocked(
144
  const std::string& filename) const
145
{
146 147
  for (auto const& lock : this->Locks) {
    if (lock->IsLocked(filename)) {
148 149
      return true;
    }
150
  }
151 152
  return false;
}