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
19namespace Kleo
20{
21
22UniqueLock::UniqueLock() noexcept
23 : mMutex{nullptr}
24 , mOwnsMutex{false}
25{
26}
27
28UniqueLock::UniqueLock(QMutex &mutex)
29 : mMutex{std::addressof(mutex)}
30 , mOwnsMutex{false}
31{
32 lock();
33 mOwnsMutex = true;
34}
35
36UniqueLock::UniqueLock(QMutex &mutex, DeferLockType) noexcept
37 : mMutex{std::addressof(mutex)}
38 , mOwnsMutex{false}
39{
40}
41
42UniqueLock::UniqueLock(QMutex &mutex, TryToLockType)
43 : mMutex{std::addressof(mutex)}
44 , mOwnsMutex{mMutex->try_lock()}
45{
46}
47
48UniqueLock::UniqueLock(QMutex &mutex, AdoptLockType) noexcept
49 : mMutex{std::addressof(mutex)}
50 , mOwnsMutex{true}
51{
52 // XXX calling thread owns mutex
53}
54
55UniqueLock::~UniqueLock()
56{
57 if (mOwnsMutex) {
58 unlock();
59 }
60}
61
62UniqueLock::UniqueLock(UniqueLock &&u) noexcept
63 : mMutex{u.mMutex}
64 , mOwnsMutex{u.mOwnsMutex}
65{
66 u.mMutex = nullptr;
67 u.mOwnsMutex = false;
68}
69
70UniqueLock &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
84void 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
98bool 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
114void 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
124void UniqueLock::swap(UniqueLock &u) noexcept
125{
126 std::swap(mMutex, u.mMutex);
127 std::swap(mOwnsMutex, u.mOwnsMutex);
128}
129
130QMutex *UniqueLock::release() noexcept
131{
132 QMutex *ret = mMutex;
133 mMutex = nullptr;
134 mOwnsMutex = false;
135 return ret;
136}
137
138bool UniqueLock::owns_lock() const noexcept
139{
140 return mOwnsMutex;
141}
142
143UniqueLock::operator bool() const noexcept
144{
145 return owns_lock();
146}
147
148QMutex *UniqueLock::mutex() const noexcept
149{
150 return mMutex;
151}
152
153} // namespace Kleo
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:12 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.