Qore Programming Language  0.9.16
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 
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:
119  DLLEXPORT QoreRecursiveThreadLock();
120 
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:
179 };
180 
182 
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:
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:
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:
315 };
316 
317 #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:256
SafeLocker::locked
bool locked
flag indicating if the lock is held or not
Definition: QoreThreadLock.h:285
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:282
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:216
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:249
AutoLocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:178
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:190
AutoUnlocker::~AutoUnlocker
DLLLOCAL ~AutoUnlocker()
grabs the lock and destroys the object
Definition: QoreThreadLock.h:204
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
AutoLocker::AutoLocker
DLLLOCAL AutoLocker(QoreThreadLock *l)
creates the object and grabs the lock
Definition: QoreThreadLock.h:139
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:293
QoreThreadLock::QoreThreadLock
DLLLOCAL QoreThreadLock()
creates the lock
Definition: QoreThreadLock.h:54
OptLocker::OptLocker
DLLLOCAL OptLocker(QoreThreadLock *l)
creates the object and grabs the lock if the argument is not NULL
Definition: QoreThreadLock.h:296
AutoUnlocker::AutoUnlocker
DLLLOCAL AutoUnlocker(QoreThreadLock *l)
creates the object and releases the lock
Definition: QoreThreadLock.h:193
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:228
SafeLocker::~SafeLocker
DLLLOCAL ~SafeLocker()
destroys the object and unlocks the lock if it's held
Definition: QoreThreadLock.h:243
SafeLocker::SafeLocker
DLLLOCAL SafeLocker(QoreThreadLock *l)
creates the object and grabs the lock
Definition: QoreThreadLock.h:231
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:314
SafeLocker::relock
DLLLOCAL void relock()
relocks an unlock lock
Definition: QoreThreadLock.h:269
OptLocker::~OptLocker
DLLLOCAL ~OptLocker()
releases the lock if there is a lock pointer being managed and destroys the object
Definition: QoreThreadLock.h:302
AutoLocker::~AutoLocker
DLLLOCAL ~AutoLocker()
destroys the object and releases the lock
Definition: QoreThreadLock.h:167