Libkleo

uniquelock.cpp
1 /*
2  utils/uniquelock.cpp
3  QMutex-compatible replacement for std::unique_lock
4 
5  This file is part of libkleopatra, the KDE keymanagement library
6  SPDX-FileCopyrightText: 2008-2021 Free Software Foundation, Inc.
7  SPDX-FileCopyrightText: 2021 g10 Code GmbH
8  SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
9 
10  SPDX-License-Identifier: GPL-3.0-or-later WITH GCC-exception-3.1
11 */
12 
13 #include <config-libkleo.h>
14 
15 #include "uniquelock.h"
16 
17 #include <libkleo_debug.h>
18 
19 namespace Kleo
20 {
21 
22 UniqueLock::UniqueLock() noexcept
23  : mMutex{nullptr}
24  , mOwnsMutex{false}
25 {
26 }
27 
28 UniqueLock::UniqueLock(QMutex &mutex)
29  : mMutex{std::addressof(mutex)}
30  , mOwnsMutex{false}
31 {
32  lock();
33  mOwnsMutex = true;
34 }
35 
36 UniqueLock::UniqueLock(QMutex &mutex, DeferLockType) noexcept
37  : mMutex{std::addressof(mutex)}
38  , mOwnsMutex{false}
39 {
40 }
41 
42 UniqueLock::UniqueLock(QMutex &mutex, TryToLockType)
43  : mMutex{std::addressof(mutex)}
44  , mOwnsMutex{mMutex->try_lock()}
45 {
46 }
47 
48 UniqueLock::UniqueLock(QMutex &mutex, AdoptLockType) noexcept
49  : mMutex{std::addressof(mutex)}
50  , mOwnsMutex{true}
51 {
52  // XXX calling thread owns mutex
53 }
54 
55 UniqueLock::~UniqueLock()
56 {
57  if (mOwnsMutex) {
58  unlock();
59  }
60 }
61 
62 UniqueLock::UniqueLock(UniqueLock &&u) noexcept
63  : mMutex{u.mMutex}
64  , mOwnsMutex{u.mOwnsMutex}
65 {
66  u.mMutex = nullptr;
67  u.mOwnsMutex = false;
68 }
69 
70 UniqueLock &UniqueLock::operator=(UniqueLock &&u) noexcept
71 {
72  if (mOwnsMutex) {
73  unlock();
74  }
75 
76  UniqueLock(std::move(u)).swap(*this);
77 
78  u.mMutex = nullptr;
79  u.mOwnsMutex = false;
80 
81  return *this;
82 }
83 
84 void UniqueLock::lock()
85 {
86  Q_ASSERT(mMutex);
87  Q_ASSERT(!mOwnsMutex);
88  if (!mMutex) {
89  qCWarning(LIBKLEO_LOG) << __func__ << "Error: operation not permitted";
90  } else if (mOwnsMutex) {
91  qCWarning(LIBKLEO_LOG) << __func__ << "Error: resource deadlock would occur";
92  } else {
93  mMutex->lock();
94  mOwnsMutex = true;
95  }
96 }
97 
98 bool UniqueLock::try_lock()
99 {
100  Q_ASSERT(mMutex);
101  Q_ASSERT(!mOwnsMutex);
102  if (!mMutex) {
103  qCWarning(LIBKLEO_LOG) << __func__ << "Error: operation not permitted";
104  return false;
105  } else if (mOwnsMutex) {
106  qCWarning(LIBKLEO_LOG) << __func__ << "Error: resource deadlock would occur";
107  return false;
108  } else {
109  mOwnsMutex = mMutex->try_lock();
110  return mOwnsMutex;
111  }
112 }
113 
114 void UniqueLock::unlock()
115 {
116  if (!mOwnsMutex) {
117  qCWarning(LIBKLEO_LOG) << __func__ << "Error: operation not permitted";
118  } else if (mMutex) {
119  mMutex->unlock();
120  mOwnsMutex = false;
121  }
122 }
123 
124 void UniqueLock::swap(UniqueLock &u) noexcept
125 {
126  std::swap(mMutex, u.mMutex);
127  std::swap(mOwnsMutex, u.mOwnsMutex);
128 }
129 
130 QMutex *UniqueLock::release() noexcept
131 {
132  QMutex *ret = mMutex;
133  mMutex = nullptr;
134  mOwnsMutex = false;
135  return ret;
136 }
137 
138 bool UniqueLock::owns_lock() const noexcept
139 {
140  return mOwnsMutex;
141 }
142 
143 UniqueLock::operator bool() const noexcept
144 {
145  return owns_lock();
146 }
147 
148 QMutex *UniqueLock::mutex() const noexcept
149 {
150  return mMutex;
151 }
152 
153 } // namespace Kleo
bool try_lock()
void lock()
void unlock()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Thu Feb 15 2024 03:56:14 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.