Qx v0.5.8
Qt Extensions Library
Loading...
Searching...
No Matches
qx-exclusiveaccess.h
1#ifndef QX_EXCLUSIVE_ACCESS_H
2#define QX_EXCLUSIVE_ACCESS_H
3
4// Extra-component Includes
6
7class QMutex;
9
10namespace Qx
11{
12
13template<typename AccessType, typename Mutex>
14 requires any_of<Mutex, QMutex, QRecursiveMutex>
16{
17//-Instance Variables---------------------------------------------------------------------------------------
18private:
19 AccessType* mAccess;
20 Mutex* mMutex;
21 bool mLocked;
22
23//-Constructor----------------------------------------------------------------------------------------------
24private:
25 ExclusiveAccess(const ExclusiveAccess&) = delete;
26
27public:
28 [[nodiscard]] explicit ExclusiveAccess(AccessType* data, Mutex* mutex) noexcept:
29 mLocked(false)
30 {
31 mAccess = data;
32 mMutex = mutex;
33 if(mMutex) [[likely]]
34 {
35 mMutex->lock();
36 mLocked = true;
37 }
38 }
39
40 [[nodiscard]] ExclusiveAccess(ExclusiveAccess&& other) noexcept :
41 mAccess(std::exchange(other.mAccess, nullptr)),
42 mMutex(std::exchange(other.mMutex, nullptr)),
43 mLocked(std::exchange(other.mLocked, false))
44 {}
45
46//-Destructor----------------------------------------------------------------------------------------------
47public:
49 {
50 if(mLocked)
51 unlock();
52 }
53
54//-Instance Functions----------------------------------------------------------------------------------------------
55public:
56 bool isLocked() const noexcept { return mLocked; }
57
58 void unlock() noexcept
59 {
60 Q_ASSERT(mLocked);
61 mMutex->unlock();
62 mLocked = false;
63 }
64
65 void relock() noexcept
66 {
67 Q_ASSERT(!mLocked);
68 mMutex->lock();
69 mLocked = true;
70 }
71
72 void swap(ExclusiveAccess& other) noexcept
73 {
74 using std::swap; // Allows use of specialized swap method for members, if they exist
75 swap(mAccess, other.mAccess);
76 swap(mMutex, other.mMutex);
77 swap(mLocked, other.mLocked);
78 }
79
80 Mutex* mutex() const { return mMutex; }
81
82 AccessType* access() { return mAccess; }
83 const AccessType* access() const { return mAccess; }
84
85 AccessType& operator*() { Q_ASSERT(mAccess); return *mAccess; }
86 const AccessType& operator*() const { Q_ASSERT(mAccess); return *mAccess; }
87
88 AccessType* operator->() { Q_ASSERT(mAccess); return mAccess; }
89 const AccessType* operator->() const { Q_ASSERT(mAccess); return mAccess; }
90
91 // Move-and-swap, which insures other's data is fully cleared (i.e. it loses exclusive access) due to the move construct
93 {
94 ExclusiveAccess moved(std::move(other));
95 swap(other);
96 return *this;
97 }
98};
99
100}
101
102#endif // QX_EXCLUSIVE_ACCESS_H
The ExclusiveAccess template class is a convenience class that simplifies access to resources secured...
Definition qx-exclusiveaccess.h:16
ExclusiveAccess & operator=(ExclusiveAccess &&other) noexcept
Definition qx-exclusiveaccess.h:92
ExclusiveAccess(AccessType *data, Mutex *mutex) noexcept
Definition qx-exclusiveaccess.h:28
AccessType * access()
Definition qx-exclusiveaccess.h:82
AccessType & operator*()
Definition qx-exclusiveaccess.h:85
void unlock() noexcept
Definition qx-exclusiveaccess.h:58
void swap(ExclusiveAccess &other) noexcept
Definition qx-exclusiveaccess.h:72
void relock() noexcept
Definition qx-exclusiveaccess.h:65
const AccessType * access() const
Definition qx-exclusiveaccess.h:83
~ExclusiveAccess()
Definition qx-exclusiveaccess.h:48
bool isLocked() const noexcept
Definition qx-exclusiveaccess.h:56
const AccessType * operator->() const
Definition qx-exclusiveaccess.h:89
const AccessType & operator*() const
Definition qx-exclusiveaccess.h:86
AccessType * operator->()
Definition qx-exclusiveaccess.h:88
Mutex * mutex() const
Definition qx-exclusiveaccess.h:80
ExclusiveAccess(ExclusiveAccess &&other) noexcept
Definition qx-exclusiveaccess.h:40
The Qx namespace is the main namespace through which all non-global functionality of the Qx library i...
Definition qx-processwaiter.cpp:5
The qx-concepts header file provides a library of general purpose concepts as an extension of the sta...