Qore Programming Language - C/C++ Library  0.9.14
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 
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 
117 public:
120 
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:
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 
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:
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:
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:
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
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack,...
Definition: QoreThreadLock.h:136
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:149
DLLLOCAL ~AutoLocker()
destroys the object and releases the lock
Definition: QoreThreadLock.h:181
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
DLLLOCAL ~AutoUnlocker()
grabs the lock and destroys the object
Definition: QoreThreadLock.h:223
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:208
provides a safe and exception-safe way to hold optional locks in Qore, only to be used on the stack,...
Definition: QoreThreadLock.h:308
DLLLOCAL ~OptLocker()
releases the lock if there is a lock pointer being managed and destroys the object
Definition: QoreThreadLock.h:331
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:321
a thread condition class implementing a wrapper for pthread_cond_t
Definition: QoreCondition.h:45
Implements a recursive lock.
Definition: QoreThreadLock.h:116
DLLEXPORT QoreRecursiveThreadLock()
Creates the object.
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:49
DLLLOCAL ~QoreThreadLock()
destroys the lock
Definition: QoreThreadLock.h:71
DLLLOCAL QoreThreadLock()
creates the lock
Definition: QoreThreadLock.h:54
DLLLOCAL void lock()
grabs the lock (assumes that the lock is unlocked)
Definition: QoreThreadLock.h:78
DLLLOCAL int trylock()
attempts to acquire the mutex and returns the status immediately; does not block
Definition: QoreThreadLock.h:101
DLLLOCAL void unlock()
releases the lock (assumes that the lock is locked)
Definition: QoreThreadLock.h:89
provides an exception-safe way to manage locks in Qore, only to be used on the stack,...
Definition: QoreThreadLock.h:238
bool locked
flag indicating if the lock is held or not
Definition: QoreThreadLock.h:254
DLLLOCAL void relock()
relocks an unlock lock
Definition: QoreThreadLock.h:296
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held
Definition: QoreThreadLock.h:276
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:251
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
DLLLOCAL ~SafeLocker()
destroys the object and unlocks the lock if it's held
Definition: QoreThreadLock.h:270
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition: QoreThreadLock.h:283