Qore Programming Language  0.9.0
QoreThreadLock.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreThreadLock.h
4 
5  Qore Programming Language
6 
7  Copyright (C) 2003 - 2018 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 
48  friend class QoreCondition;
49 
50 private:
52  pthread_mutex_t ptm_lock;
53 
55  DLLLOCAL QoreThreadLock& operator=(const QoreThreadLock&);
56 
58  DLLLOCAL void init(const pthread_mutexattr_t* pma = 0) {
59 #ifndef NDEBUG
60  int rc =
61 #endif
62  pthread_mutex_init(&ptm_lock, pma);
63  assert(!rc);
64  }
65 
66 public:
68  DLLLOCAL QoreThreadLock() {
69  init();
70  }
71 
73  DLLLOCAL QoreThreadLock(const pthread_mutexattr_t* ma) {
74  init(ma);
75  }
76 
78  DLLLOCAL ~QoreThreadLock() {
79  pthread_mutex_destroy(&ptm_lock);
80  }
81 
83  DLLLOCAL QoreThreadLock(const QoreThreadLock&) {
84  init();
85  }
86 
88 
90  DLLLOCAL void lock() {
91 #ifndef NDEBUG
92  int rc =
93 #endif
94  pthread_mutex_lock(&ptm_lock);
95  assert(!rc);
96  }
97 
99 
101  DLLLOCAL void unlock() {
102 #ifndef NDEBUG
103  int rc =
104 #endif
105  pthread_mutex_unlock(&ptm_lock);
106  assert(!rc);
107  }
108 
110 
113  DLLLOCAL int trylock() {
114  return pthread_mutex_trylock(&ptm_lock);
115  }
116 };
117 
119 
128 class AutoLocker {
129 private:
131  DLLLOCAL AutoLocker(const AutoLocker&);
132 
134  DLLLOCAL AutoLocker& operator=(const AutoLocker&);
135 
137  DLLLOCAL void *operator new(size_t);
138 
139 protected:
142 
143 public:
145  DLLLOCAL AutoLocker(QoreThreadLock* l) : lck(l) {
146  lck->lock();
147  }
148 
150  DLLLOCAL AutoLocker(QoreThreadLock& l) : lck(&l) {
151  lck->lock();
152  }
153 
155 
157  DLLLOCAL AutoLocker(QoreThreadLock* l, bool already_locked) : lck(l) {
158  if (!already_locked) {
159  lck->lock();
160  }
161  }
162 
164 
166  DLLLOCAL AutoLocker(QoreThreadLock& l, bool already_locked) : lck(&l) {
167  if (!already_locked) {
168  lck->lock();
169  }
170  }
171 
173  DLLLOCAL ~AutoLocker() {
174  lck->unlock();
175  }
176 };
177 
179 
188 private:
190  DLLLOCAL AutoUnlocker(const AutoUnlocker&);
191 
193  DLLLOCAL AutoUnlocker& operator=(const AutoUnlocker&);
194 
196  DLLLOCAL void *operator new(size_t);
197 
198 protected:
201 
202 public:
204  DLLLOCAL AutoUnlocker(QoreThreadLock* l) : lck(l) {
205  if (lck)
206  lck->unlock();
207  }
208 
210  DLLLOCAL AutoUnlocker(QoreThreadLock& l) : lck(&l) {
211  lck->unlock();
212  }
213 
215  DLLLOCAL ~AutoUnlocker() {
216  if (lck)
217  lck->lock();
218  }
219 };
220 
222 
230 class SafeLocker {
231 private:
233  DLLLOCAL SafeLocker(const SafeLocker&);
234 
236  DLLLOCAL SafeLocker& operator=(const SafeLocker&);
237 
239  DLLLOCAL void *operator new(size_t);
240 
241 protected:
244 
246  bool locked;
247 
248 public:
250  DLLLOCAL SafeLocker(QoreThreadLock* l) : lck(l) {
251  lck->lock();
252  locked = true;
253  }
254 
256  DLLLOCAL SafeLocker(QoreThreadLock& l) : lck(&l) {
257  lck->lock();
258  locked = true;
259  }
260 
262  DLLLOCAL ~SafeLocker() {
263  if (locked)
264  lck->unlock();
265  }
266 
268  DLLLOCAL void lock() {
269  assert(!locked);
270  lck->lock();
271  locked = true;
272  }
273 
275  DLLLOCAL void unlock() {
276  assert(locked);
277  locked = false;
278  lck->unlock();
279  }
280 
282  DLLLOCAL void stay_locked() {
283  assert(locked);
284  locked = false;
285  }
286 
288  DLLLOCAL void relock() {
289  assert(!locked);
290  lck->lock();
291  locked = true;
292  }
293 };
294 
296 
300 class OptLocker {
301 private:
303  DLLLOCAL OptLocker(const OptLocker&);
304 
306  DLLLOCAL OptLocker& operator=(const OptLocker&);
307 
309  DLLLOCAL void *operator new(size_t);
310 
311 protected:
314 
315 public:
317  DLLLOCAL OptLocker(QoreThreadLock* l) : lck(l) {
318  if (lck)
319  lck->lock();
320  }
321 
323  DLLLOCAL ~OptLocker() {
324  if (lck)
325  lck->unlock();
326  }
327 };
328 
329 #endif // _QORE_QORETHREADLOCK_H
DLLLOCAL ~QoreThreadLock()
destroys the lock
Definition: QoreThreadLock.h:78
DLLLOCAL ~AutoUnlocker()
grabs the lock and destroys the object
Definition: QoreThreadLock.h:215
DLLLOCAL ~AutoLocker()
destroys the object and releases the lock
Definition: QoreThreadLock.h:173
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:282
DLLLOCAL int trylock()
attempts to acquire the mutex and returns the status immediately; does not block
Definition: QoreThreadLock.h:113
a thread condition class implementing a wrapper for pthread_cond_t
Definition: QoreCondition.h:45
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition: QoreThreadLock.h:275
DLLLOCAL void relock()
relocks an unlock lock
Definition: QoreThreadLock.h:288
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:128
provides a safe and exception-safe way to hold optional locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:300
DLLLOCAL void lock()
grabs the lock (assumes that the lock is unlocked)
Definition: QoreThreadLock.h:90
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:141
DLLLOCAL void unlock()
releases the lock (assumes that the lock is locked)
Definition: QoreThreadLock.h:101
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:200
DLLLOCAL ~SafeLocker()
destroys the object and unlocks the lock if it&#39;s held
Definition: QoreThreadLock.h:262
bool locked
flag indicating if the lock is held or not
Definition: QoreThreadLock.h:246
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:47
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:313
DLLLOCAL QoreThreadLock()
creates the lock
Definition: QoreThreadLock.h:68
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:243
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held ...
Definition: QoreThreadLock.h:268
provides an exception-safe way to manage locks in Qore, only to be used on the stack, cannot be dynamically allocated
Definition: QoreThreadLock.h:230
provides a safe and exception-safe way to release and re-acquire locks in Qore, only to be used on th...
Definition: QoreThreadLock.h:187
DLLLOCAL ~OptLocker()
releases the lock if there is a lock pointer being managed and destroys the object ...
Definition: QoreThreadLock.h:323