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

QoreThreadLock.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3 QoreThreadLock.h
4
5 Qore Programming Language
6
7 Copyright (C) 2003 - 2020 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 private:
139 DLLLOCAL AutoLocker(const AutoLocker&);
140
142 DLLLOCAL AutoLocker& operator=(const AutoLocker&);
143
145 DLLLOCAL void *operator new(size_t);
146
147 protected:
149 QoreThreadLock* lck;
150
151 public:
153 DLLLOCAL AutoLocker(QoreThreadLock* l) : lck(l) {
154 lck->lock();
155 }
156
158 DLLLOCAL AutoLocker(QoreThreadLock& l) : lck(&l) {
159 lck->lock();
160 }
161
163
165 DLLLOCAL AutoLocker(QoreThreadLock* l, bool already_locked) : lck(l) {
166 if (!already_locked) {
167 lck->lock();
168 }
169 }
170
172
174 DLLLOCAL AutoLocker(QoreThreadLock& l, bool already_locked) : lck(&l) {
175 if (!already_locked) {
176 lck->lock();
177 }
178 }
179
181 DLLLOCAL ~AutoLocker() {
182 lck->unlock();
183 }
184 };
185
187
195 class AutoUnlocker {
196 private:
198 DLLLOCAL AutoUnlocker(const AutoUnlocker&);
199
201 DLLLOCAL AutoUnlocker& operator=(const AutoUnlocker&);
202
204 DLLLOCAL void *operator new(size_t);
205
206 protected:
208 QoreThreadLock* lck;
209
210 public:
212 DLLLOCAL AutoUnlocker(QoreThreadLock* l) : lck(l) {
213 if (lck)
214 lck->unlock();
215 }
216
218 DLLLOCAL AutoUnlocker(QoreThreadLock& l) : lck(&l) {
219 lck->unlock();
220 }
221
223 DLLLOCAL ~AutoUnlocker() {
224 if (lck)
225 lck->lock();
226 }
227 };
228
230
238 class SafeLocker {
239 private:
241 DLLLOCAL SafeLocker(const SafeLocker&);
242
244 DLLLOCAL SafeLocker& operator=(const SafeLocker&);
245
247 DLLLOCAL void *operator new(size_t);
248
249 protected:
251 QoreThreadLock* lck;
252
254 bool locked;
255
256 public:
258 DLLLOCAL SafeLocker(QoreThreadLock* l) : lck(l) {
259 lck->lock();
260 locked = true;
261 }
262
264 DLLLOCAL SafeLocker(QoreThreadLock& l) : lck(&l) {
265 lck->lock();
266 locked = true;
267 }
268
270 DLLLOCAL ~SafeLocker() {
271 if (locked)
272 lck->unlock();
273 }
274
276 DLLLOCAL void lock() {
277 assert(!locked);
278 lck->lock();
279 locked = true;
280 }
281
283 DLLLOCAL void unlock() {
284 assert(locked);
285 locked = false;
286 lck->unlock();
287 }
288
290 DLLLOCAL void stay_locked() {
291 assert(locked);
292 locked = false;
293 }
294
296 DLLLOCAL void relock() {
297 assert(!locked);
298 lck->lock();
299 locked = true;
300 }
301 };
302
304
308 class OptLocker {
309 private:
311 DLLLOCAL OptLocker(const OptLocker&);
312
314 DLLLOCAL OptLocker& operator=(const OptLocker&);
315
317 DLLLOCAL void *operator new(size_t);
318
319 protected:
321 QoreThreadLock* lck;
322
323 public:
325 DLLLOCAL OptLocker(QoreThreadLock* l) : lck(l) {
326 if (lck)
327 lck->lock();
328 }
329
331 DLLLOCAL ~OptLocker() {
332 if (lck)
333 lck->unlock();
334 }
335 };
336
337 #endif // _QORE_QORETHREADLOCK_H
SafeLocker::unlock
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition: QoreThreadLock.h:283
SafeLocker::locked
bool locked
flag indicating if the lock is held or not
Definition: QoreThreadLock.h:254
QoreThreadLock::~QoreThreadLock
DLLLOCAL ~QoreThreadLock()
destroys the lock
Definition: QoreThreadLock.h:71
SafeLocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:251
QoreRecursiveThreadLock::QoreRecursiveThreadLock
DLLEXPORT QoreRecursiveThreadLock()
Creates the object.
QoreThreadLock::lock
DLLLOCAL void lock()
grabs the lock (assumes that the lock is unlocked)
Definition: QoreThreadLock.h:78
QoreCondition
a thread condition class implementing a wrapper for pthread_cond_t
Definition: QoreCondition.h:45
AutoUnlocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:208
AutoLocker
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack,...
Definition: QoreThreadLock.h:136
SafeLocker::lock
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held
Definition: QoreThreadLock.h:276
AutoLocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:149
QoreThreadLock::trylock
DLLLOCAL int trylock()
attempts to acquire the mutex and returns the status immediately; does not block
Definition: QoreThreadLock.h:101
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:195
AutoUnlocker::~AutoUnlocker
DLLLOCAL ~AutoUnlocker()
grabs the lock and destroys the object
Definition: QoreThreadLock.h:223
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:290
QoreRecursiveThreadLock
Implements a recursive lock.
Definition: QoreThreadLock.h:116
OptLocker
provides a safe and exception-safe way to hold optional locks in Qore, only to be used on the stack,...
Definition: QoreThreadLock.h:308
QoreThreadLock::QoreThreadLock
DLLLOCAL QoreThreadLock()
creates the lock
Definition: QoreThreadLock.h:54
QoreThreadLock
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:49
SafeLocker
provides an exception-safe way to manage locks in Qore, only to be used on the stack,...
Definition: QoreThreadLock.h:238
SafeLocker::~SafeLocker
DLLLOCAL ~SafeLocker()
destroys the object and unlocks the lock if it's held
Definition: QoreThreadLock.h:270
QoreThreadLock::unlock
DLLLOCAL void unlock()
releases the lock (assumes that the lock is locked)
Definition: QoreThreadLock.h:89
OptLocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:321
SafeLocker::relock
DLLLOCAL void relock()
relocks an unlock lock
Definition: QoreThreadLock.h:296
OptLocker::~OptLocker
DLLLOCAL ~OptLocker()
releases the lock if there is a lock pointer being managed and destroys the object
Definition: QoreThreadLock.h:331
AutoLocker::~AutoLocker
DLLLOCAL ~AutoLocker()
destroys the object and releases the lock
Definition: QoreThreadLock.h:181