Libkleo

uniquelock.h
1 /*
2  utils/uniquelock.h
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 #pragma once
14 
15 #include "kleo_export.h"
16 
17 #include <QMutex>
18 
19 #include <chrono>
20 #include <memory>
21 
22 namespace Kleo
23 {
24 
25 /// Do not acquire ownership of the mutex.
26 struct DeferLockType {
27  explicit DeferLockType() = default;
28 };
29 
30 /// Try to acquire ownership of the mutex without blocking.
31 struct TryToLockType {
32  explicit TryToLockType() = default;
33 };
34 
35 /// Assume the calling thread has already obtained mutex ownership
36 /// and manage it.
37 struct AdoptLockType {
38  explicit AdoptLockType() = default;
39 };
40 
41 /// Tag used to prevent a scoped lock from acquiring ownership of a mutex.
42 inline constexpr DeferLockType deferLock{};
43 
44 /// Tag used to prevent a scoped lock from blocking if a mutex is locked.
45 inline constexpr TryToLockType tryToLock{};
46 
47 /// Tag used to make a scoped lock take ownership of a locked mutex.
48 inline constexpr AdoptLockType adoptLock{};
49 
50 /** @brief A movable scoped lock type for QMutex.
51  *
52  * A UniqueLock controls mutex ownership within a scope. Ownership of the
53  * mutex can be delayed until after construction and can be transferred
54  * to another UniqueLock by move construction or move assignment. If a
55  * mutex lock is owned when the destructor runs ownership will be released.
56  */
57 class KLEO_EXPORT UniqueLock
58 {
59 public:
60  UniqueLock() noexcept;
61  explicit UniqueLock(QMutex &mutex);
62 
63  UniqueLock(QMutex &mutex, DeferLockType) noexcept;
65  UniqueLock(QMutex &mutex, AdoptLockType) noexcept;
66 
67  template<typename Clock, typename Duration>
68  UniqueLock(QMutex &mutex, const std::chrono::time_point<Clock, Duration> &timePoint)
69  : mMutex{std::addressof(mutex)}
70  , mOwnsMutex{mMutex->try_lock_until(timePoint)}
71  {
72  }
73 
74  template<typename Rep, typename Period>
75  UniqueLock(QMutex &mutex, const std::chrono::duration<Rep, Period> &duration)
76  : mMutex{std::addressof(mutex)}
77  , mOwnsMutex{mMutex->try_lock_for(duration)}
78  {
79  }
80 
81  ~UniqueLock();
82 
83  UniqueLock(const UniqueLock &) = delete;
84  UniqueLock &operator=(const UniqueLock &) = delete;
85 
86  UniqueLock(UniqueLock &&u) noexcept;
87  UniqueLock &operator=(UniqueLock &&u) noexcept;
88 
89  void lock();
90 
91  bool try_lock();
92 
93  template<typename Clock, typename Duration>
94  bool try_lock_until(const std::chrono::time_point<Clock, Duration> &timePoint)
95  {
96  Q_ASSERT(mMutex);
97  Q_ASSERT(!mOwnsMutex);
98  if (mMutex && !mOwnsMutex) {
99  mOwnsMutex = mMutex->try_lock_until(timePoint);
100  return mOwnsMutex;
101  }
102  }
103 
104  template<typename Rep, typename Period>
105  bool try_lock_for(const std::chrono::duration<Rep, Period> &duration)
106  {
107  Q_ASSERT(mMutex);
108  Q_ASSERT(!mOwnsMutex);
109  if (mMutex && !mOwnsMutex) {
110  mOwnsMutex = mMutex->try_lock_for(duration);
111  return mOwnsMutex;
112  }
113  }
114 
115  void unlock();
116 
117  void swap(UniqueLock &u) noexcept;
118 
119  QMutex *release() noexcept;
120 
121  bool owns_lock() const noexcept;
122 
123  explicit operator bool() const noexcept;
124 
125  QMutex *mutex() const noexcept;
126 
127 private:
128  QMutex *mMutex;
129  bool mOwnsMutex;
130 };
131 
132 } // namespace Kleo
133 
134 namespace std
135 {
136 
137 /// Swap overload for UniqueLock objects.
138 /// @relates UniqueLock
139 inline void swap(Kleo::UniqueLock &x, Kleo::UniqueLock &y) noexcept
140 {
141  x.swap(y);
142 }
143 
144 }
Do not acquire ownership of the mutex.
Definition: uniquelock.h:26
A movable scoped lock type for QMutex.
Definition: uniquelock.h:57
Try to acquire ownership of the mutex without blocking.
Definition: uniquelock.h:31
Assume the calling thread has already obtained mutex ownership and manage it.
Definition: uniquelock.h:37
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.