| Qore Programming Language - C/C++ Library 1.0.8

QoreThreadLock.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3 QoreThreadLock.h
4
5 Qore Programming Language
6
7 Copyright (C) 2003 - 2021 Qore Technologies, s.r.o.
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the "Software"),
11 to deal in the Software without restriction, including without limitation
12 the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 and/or sell copies of the Software, and to permit persons to whom the
14 Software is furnished to do so, subject to the following conditions:
15
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26
27 Note that the Qore library is released under a choice of three open-source
28 licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
29 information.
30 */
31
32 #ifndef _QORE_QORETHREADLOCK_H
33
34 #define _QORE_QORETHREADLOCK_H
35
36 #include <cassert>
37 #include <csignal>
38 #include <cstdio>
39 #include <cstdlib>
40 #include <cstring>
41 #include <pthread.h>
42
44
49 class QoreThreadLock {
50 friend class QoreCondition;
51
52 public:
54 DLLLOCAL QoreThreadLock() : QoreThreadLock(nullptr) {
55 }
56
58 DLLLOCAL QoreThreadLock(const pthread_mutexattr_t* ma) {
59 #ifndef NDEBUG
60 int rc =
61 #endif
62 pthread_mutex_init(&ptm_lock, ma);
63 assert(!rc);
64 }
65
67 DLLLOCAL QoreThreadLock(const QoreThreadLock&) : QoreThreadLock(nullptr) {
68 }
69
71 DLLLOCAL ~QoreThreadLock() {
72 pthread_mutex_destroy(&ptm_lock);
73 }
74
76
78 DLLLOCAL void lock() {
79 #ifndef NDEBUG
80 int rc =
81 #endif
82 pthread_mutex_lock(&ptm_lock);
83 assert(!rc);
84 }
85
87
89 DLLLOCAL void unlock() {
90 #ifndef NDEBUG
91 int rc =
92 #endif
93 pthread_mutex_unlock(&ptm_lock);
94 assert(!rc);
95 }
96
98
101 DLLLOCAL int trylock() {
102 return pthread_mutex_trylock(&ptm_lock);
103 }
104
105 private:
107 pthread_mutex_t ptm_lock;
108
110 DLLLOCAL QoreThreadLock& operator=(const QoreThreadLock&) = delete;
111 };
112
114
116 class QoreRecursiveThreadLock : public QoreThreadLock {
117 public:
119 DLLEXPORT QoreRecursiveThreadLock();
120
122 DLLLOCAL QoreRecursiveThreadLock(const QoreRecursiveThreadLock&) : QoreRecursiveThreadLock() {
123 }
124 };
125
127
136 class AutoLocker {
137 public:
139 DLLLOCAL AutoLocker(QoreThreadLock* l) : lck(l) {
140 lck->lock();
141 }
142
144 DLLLOCAL AutoLocker(QoreThreadLock& l) : lck(&l) {
145 lck->lock();
146 }
147
149
151 DLLLOCAL AutoLocker(QoreThreadLock* l, bool already_locked) : lck(l) {
152 if (!already_locked) {
153 lck->lock();
154 }
155 }
156
158
160 DLLLOCAL AutoLocker(QoreThreadLock& l, bool already_locked) : lck(&l) {
161 if (!already_locked) {
162 lck->lock();
163 }
164 }
165
167 DLLLOCAL ~AutoLocker() {
168 lck->unlock();
169 }
170
171 private:
172 DLLLOCAL AutoLocker(const AutoLocker&) = delete;
173 DLLLOCAL AutoLocker& operator=(const AutoLocker&) = delete;
174 DLLLOCAL void *operator new(size_t) = delete;
175
176 protected:
178 QoreThreadLock* lck;
179 };
180
182
190 class AutoUnlocker {
191 public:
193 DLLLOCAL AutoUnlocker(QoreThreadLock* l) : lck(l) {
194 if (lck)
195 lck->unlock();
196 }
197
199 DLLLOCAL AutoUnlocker(QoreThreadLock& l) : lck(&l) {
200 lck->unlock();
201 }
202
204 DLLLOCAL ~AutoUnlocker() {
205 if (lck)
206 lck->lock();
207 }
208
209 private:
210 DLLLOCAL AutoUnlocker(const AutoUnlocker&) = delete;
211 DLLLOCAL AutoUnlocker& operator=(const AutoUnlocker&) = delete;
212 DLLLOCAL void *operator new(size_t) = delete;
213
214 protected:
216 QoreThreadLock* lck;
217 };
218
220
228 class SafeLocker {
229 public:
231 DLLLOCAL SafeLocker(QoreThreadLock* l) : lck(l) {
232 lck->lock();
233 locked = true;
234 }
235
237 DLLLOCAL SafeLocker(QoreThreadLock& l) : lck(&l) {
238 lck->lock();
239 locked = true;
240 }
241
243 DLLLOCAL ~SafeLocker() {
244 if (locked)
245 lck->unlock();
246 }
247
249 DLLLOCAL void lock() {
250 assert(!locked);
251 lck->lock();
252 locked = true;
253 }
254
256 DLLLOCAL void unlock() {
257 assert(locked);
258 locked = false;
259 lck->unlock();
260 }
261
263 DLLLOCAL void stay_locked() {
264 assert(locked);
265 locked = false;
266 }
267
269 DLLLOCAL void relock() {
270 assert(!locked);
271 lck->lock();
272 locked = true;
273 }
274
275 private:
276 DLLLOCAL SafeLocker(const SafeLocker&) = delete;
277 DLLLOCAL SafeLocker& operator=(const SafeLocker&) = delete;
278 DLLLOCAL void *operator new(size_t) = delete;
279
280 protected:
282 QoreThreadLock* lck;
283
285 bool locked;
286 };
287
289
293 class OptLocker {
294 public:
296 DLLLOCAL OptLocker(QoreThreadLock* l) : lck(l) {
297 if (lck)
298 lck->lock();
299 }
300
302 DLLLOCAL ~OptLocker() {
303 if (lck)
304 lck->unlock();
305 }
306
307 private:
308 DLLLOCAL OptLocker(const OptLocker&) = delete;
309 DLLLOCAL OptLocker& operator=(const OptLocker&) = delete;
310 DLLLOCAL void *operator new(size_t) = delete;
311
312 protected:
314 QoreThreadLock* lck;
315 };
316
317 #endif // _QORE_QORETHREADLOCK_H
QoreThreadLock::~QoreThreadLock
DLLLOCAL ~QoreThreadLock()
destroys the lock
Definition: QoreThreadLock.h:71
AutoUnlocker::~AutoUnlocker
DLLLOCAL ~AutoUnlocker()
grabs the lock and destroys the object
Definition: QoreThreadLock.h:204
AutoLocker::~AutoLocker
DLLLOCAL ~AutoLocker()
destroys the object and releases the lock
Definition: QoreThreadLock.h:167
AutoLocker::AutoLocker
DLLLOCAL AutoLocker(QoreThreadLock *l)
creates the object and grabs the lock
Definition: QoreThreadLock.h:139
QoreRecursiveThreadLock::QoreRecursiveThreadLock
DLLEXPORT QoreRecursiveThreadLock()
Creates the object.
SafeLocker::stay_locked
DLLLOCAL void stay_locked()
will not unlock the lock when the destructor is run; do not use any other functions of this class aft...
Definition: QoreThreadLock.h:263
AutoUnlocker::AutoUnlocker
DLLLOCAL AutoUnlocker(QoreThreadLock *l)
creates the object and releases the lock
Definition: QoreThreadLock.h:193
QoreThreadLock::trylock
DLLLOCAL int trylock()
attempts to acquire the mutex and returns the status immediately; does not block
Definition: QoreThreadLock.h:101
QoreCondition
a thread condition class implementing a wrapper for pthread_cond_t
Definition: QoreCondition.h:45
QoreRecursiveThreadLock
Implements a recursive lock.
Definition: QoreThreadLock.h:116
SafeLocker::unlock
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition: QoreThreadLock.h:256
SafeLocker::relock
DLLLOCAL void relock()
relocks an unlock lock
Definition: QoreThreadLock.h:269
AutoLocker
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:136
OptLocker
provides a safe and exception-safe way to hold optional locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:293
QoreThreadLock::lock
DLLLOCAL void lock()
grabs the lock (assumes that the lock is unlocked)
Definition: QoreThreadLock.h:78
AutoLocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:178
QoreThreadLock::unlock
DLLLOCAL void unlock()
releases the lock (assumes that the lock is locked)
Definition: QoreThreadLock.h:89
AutoUnlocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:216
OptLocker::OptLocker
DLLLOCAL OptLocker(QoreThreadLock *l)
creates the object and grabs the lock if the argument is not NULL
Definition: QoreThreadLock.h:296
SafeLocker::~SafeLocker
DLLLOCAL ~SafeLocker()
destroys the object and unlocks the lock if it&#39;s held
Definition: QoreThreadLock.h:243
SafeLocker::locked
bool locked
flag indicating if the lock is held or not
Definition: QoreThreadLock.h:285
QoreThreadLock
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:49
SafeLocker::SafeLocker
DLLLOCAL SafeLocker(QoreThreadLock *l)
creates the object and grabs the lock
Definition: QoreThreadLock.h:231
OptLocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:314
QoreThreadLock::QoreThreadLock
DLLLOCAL QoreThreadLock()
creates the lock
Definition: QoreThreadLock.h:54
SafeLocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:282
SafeLocker::lock
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held ...
Definition: QoreThreadLock.h:249
SafeLocker
provides an exception-safe way to manage locks in Qore, only to be used on the stack, cannot be dynamically allocated
Definition: QoreThreadLock.h:228
AutoUnlocker
provides a safe and exception-safe way to release and re-acquire locks in Qore, only to be used on th...
Definition: QoreThreadLock.h:190
OptLocker::~OptLocker
DLLLOCAL ~OptLocker()
releases the lock if there is a lock pointer being managed and destroys the object ...
Definition: QoreThreadLock.h:302