Qore Programming Language  1.7.0
QoreRWLock.h
1 /* -*- mode: c++; indent-tabs-mode: nil -*- */
2 /*
3  QoreRWLock.h
4 
5  simple pthreads-based read-write lock
6 
7  Qore Programming Language
8 
9  Copyright (C) 2003 - 2022 Qore Technologies, s.r.o.
10 
11  Permission is hereby granted, free of charge, to any person obtaining a
12  copy of this software and associated documentation files (the "Software"),
13  to deal in the Software without restriction, including without limitation
14  the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  and/or sell copies of the Software, and to permit persons to whom the
16  Software is furnished to do so, subject to the following conditions:
17 
18  The above copyright notice and this permission notice shall be included in
19  all copies or substantial portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  DEALINGS IN THE SOFTWARE.
28 
29  Note that the Qore library is released under a choice of three open-source
30  licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
31  information.
32 */
33 
34 #ifndef _QORE_QORERWLOCK_H
35 #define _QORE_QORERWLOCK_H
36 
37 #include <pthread.h>
38 
39 #ifdef DEBUG
40 extern int q_gettid() noexcept;
41 #endif
42 
44 
47 class QoreRWLock {
48 protected:
50  pthread_rwlock_t m;
51 
53  DLLLOCAL QoreRWLock& operator=(const QoreRWLock&);
54 
55 public:
57  DLLLOCAL QoreRWLock() {
58 #ifndef NDEBUG
59  int rc =
60 #endif
61  pthread_rwlock_init(&m, 0);
62  assert(!rc);
63  }
64 
66  DLLLOCAL ~QoreRWLock() {
67 #ifndef NDEBUG
68  int rc =
69 #endif
70  pthread_rwlock_destroy(&m);
71  assert(!rc);
72  }
73 
75  DLLLOCAL int wrlock() {
76  return pthread_rwlock_wrlock(&m);
77  }
78 
80  DLLLOCAL int trywrlock() {
81  return pthread_rwlock_trywrlock(&m);
82  }
83 
85  DLLLOCAL int unlock() {
86  return pthread_rwlock_unlock(&m);
87  }
88 
90  DLLLOCAL int rdlock() {
91  return pthread_rwlock_rdlock(&m);
92  }
93 
95  DLLLOCAL int tryrdlock() {
96  return pthread_rwlock_tryrdlock(&m);
97  }
98 };
99 
101 
106 private:
109 
111  DLLLOCAL QoreAutoRWReadLocker& operator=(const QoreAutoRWReadLocker&);
112 
114  DLLLOCAL void *operator new(size_t);
115 
116 protected:
119 
120 public:
122  DLLLOCAL QoreAutoRWReadLocker(QoreRWLock &n_l) : l(&n_l) {
123  l->rdlock();
124  }
125 
127  DLLLOCAL QoreAutoRWReadLocker(QoreRWLock *n_l) : l(n_l) {
128  if (l)
129  l->rdlock();
130  }
131 
134  if (l)
135  l->unlock();
136  }
137 };
138 
140 
145 private:
148 
150  DLLLOCAL QoreAutoRWWriteLocker& operator=(const QoreAutoRWWriteLocker&);
151 
153  DLLLOCAL void *operator new(size_t);
154 
155 protected:
158 
159 public:
161  DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock &n_l) : l(&n_l) {
162  l->wrlock();
163  }
164 
166  DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock *n_l) : l(n_l) {
167  if (l)
168  l->wrlock();
169  }
170 
173  if (l)
174  l->unlock();
175  }
176 };
177 
179 
184 private:
187 
189  DLLLOCAL QoreSafeRWReadLocker& operator=(const QoreSafeRWReadLocker&);
190 
192  DLLLOCAL void *operator new(size_t);
193 
194 protected:
197 
199  bool locked;
200 
201 public:
203  DLLLOCAL QoreSafeRWReadLocker(QoreRWLock &n_l) : l(&n_l) {
204  l->rdlock();
205  locked = true;
206  }
207 
209  DLLLOCAL QoreSafeRWReadLocker(QoreRWLock *n_l) : l(n_l) {
210  l->rdlock();
211  locked = true;
212  }
213 
216  if (locked)
217  l->unlock();
218  }
219 
221  DLLLOCAL void lock() {
222  assert(!locked);
223  l->rdlock();
224  locked = true;
225  }
226 
228  DLLLOCAL void unlock() {
229  assert(locked);
230  locked = false;
231  l->unlock();
232  }
233 
235  DLLLOCAL void stay_locked() {
236  assert(locked);
237  locked = false;
238  }
239 };
240 
242 
247 private:
250 
252  DLLLOCAL QoreSafeRWWriteLocker& operator=(const QoreSafeRWWriteLocker&);
253 
255  DLLLOCAL void *operator new(size_t);
256 
257 protected:
260 
262  bool locked;
263 
264 public:
266  DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock &n_l) : l(&n_l) {
267  l->wrlock();
268  locked = true;
269  }
270 
272  DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock *n_l) : l(n_l) {
273  l->wrlock();
274  locked = true;
275  }
276 
279  if (locked)
280  l->unlock();
281  }
282 
284  DLLLOCAL void lock() {
285  assert(!locked);
286  l->wrlock();
287  locked = true;
288  }
289 
291  DLLLOCAL void unlock() {
292  assert(locked);
293  locked = false;
294  l->unlock();
295  }
296 
298  DLLLOCAL void stay_locked() {
299  assert(locked);
300  locked = false;
301  }
302 };
303 
304 class QoreOptionalRWWriteLocker {
305 protected:
306  QoreRWLock* l;
307 
308 public:
309  DLLLOCAL QoreOptionalRWWriteLocker(QoreRWLock* n_l) : l(n_l->trywrlock() ? 0 : n_l) {
310  }
311 
312  DLLLOCAL QoreOptionalRWWriteLocker(QoreRWLock& n_l) : l(n_l.trywrlock() ? 0 : &n_l) {
313  }
314 
315  DLLLOCAL ~QoreOptionalRWWriteLocker() {
316  if (l)
317  l->unlock();
318  }
319 
320  DLLLOCAL operator bool() const {
321  return (bool)l;
322  }
323 };
324 
325 class QoreOptionalRWReadLocker {
326 protected:
327  QoreRWLock* l;
328 
329 public:
330  DLLLOCAL QoreOptionalRWReadLocker(QoreRWLock* n_l) : l(n_l->tryrdlock() ? 0 : n_l) {
331  }
332 
333  DLLLOCAL QoreOptionalRWReadLocker(QoreRWLock& n_l) : l(n_l.tryrdlock() ? 0 : &n_l) {
334  }
335 
336  DLLLOCAL ~QoreOptionalRWReadLocker() {
337  if (l)
338  l->unlock();
339  }
340 
341  DLLLOCAL operator bool() const {
342  return (bool)l;
343  }
344 };
345 
346 class qore_var_rwlock_priv;
347 
348 class QoreVarRWLock {
349 private:
351  DLLLOCAL QoreVarRWLock(const QoreVarRWLock&);
353  DLLLOCAL QoreVarRWLock& operator=(const QoreVarRWLock&);
354 
355 protected:
356  qore_var_rwlock_priv* priv;
357 
358  DLLLOCAL QoreVarRWLock(qore_var_rwlock_priv* p);
359 
360 public:
361  DLLLOCAL QoreVarRWLock();
362 
364  DLLLOCAL ~QoreVarRWLock();
365 
367  DLLLOCAL void wrlock();
368 
370  DLLLOCAL int trywrlock();
371 
373  DLLLOCAL void unlock();
374 
376  DLLLOCAL void rdlock();
377 
379  DLLLOCAL int tryrdlock();
380 };
381 
382 #endif
provides a safe and exception-safe way to hold read locks in Qore, only to be used on the stack,...
Definition: QoreRWLock.h:105
DLLLOCAL ~QoreAutoRWReadLocker()
destroys the object and releases the lock
Definition: QoreRWLock.h:133
QoreRWLock * l
the pointer to the lock that will be managed
Definition: QoreRWLock.h:118
provides a safe and exception-safe way to hold write locks in Qore, only to be used on the stack,...
Definition: QoreRWLock.h:144
DLLLOCAL ~QoreAutoRWWriteLocker()
destroys the object and releases the lock
Definition: QoreRWLock.h:172
QoreRWLock * l
the pointer to the lock that will be managed
Definition: QoreRWLock.h:157
provides a simple POSIX-threads-based read-write lock
Definition: QoreRWLock.h:47
pthread_rwlock_t m
the actual locking primitive wrapped in this class
Definition: QoreRWLock.h:50
DLLLOCAL ~QoreRWLock()
destroys the lock
Definition: QoreRWLock.h:66
DLLLOCAL int wrlock()
grabs the write lock
Definition: QoreRWLock.h:75
DLLLOCAL QoreRWLock()
creates and initializes the lock
Definition: QoreRWLock.h:57
DLLLOCAL int trywrlock()
tries to grab the write lock; does not block if unsuccessful; returns 0 if successful
Definition: QoreRWLock.h:80
DLLLOCAL int unlock()
unlocks the lock (assumes the lock is locked)
Definition: QoreRWLock.h:85
DLLLOCAL int rdlock()
grabs the read lock
Definition: QoreRWLock.h:90
DLLLOCAL QoreRWLock & operator=(const QoreRWLock &)
this function is not implemented; it is here as a private function in order to prohibit it from being...
DLLLOCAL int tryrdlock()
tries to grab the read lock; does not block if unsuccessful; returns 0 if successful
Definition: QoreRWLock.h:95
provides a safe and exception-safe way to hold read locks in Qore, only to be used on the stack,...
Definition: QoreRWLock.h:183
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition: QoreRWLock.h:228
bool locked
lock flag
Definition: QoreRWLock.h:199
DLLLOCAL ~QoreSafeRWReadLocker()
destroys the object and releases the lock
Definition: QoreRWLock.h:215
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held
Definition: QoreRWLock.h:221
QoreRWLock * l
the pointer to the lock that will be managed
Definition: QoreRWLock.h:196
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: QoreRWLock.h:235
provides a safe and exception-safe way to hold write locks in Qore, only to be used on the stack,...
Definition: QoreRWLock.h:246
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition: QoreRWLock.h:291
QoreRWLock * l
the pointer to the lock that will be managed
Definition: QoreRWLock.h:259
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held
Definition: QoreRWLock.h:284
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: QoreRWLock.h:298
DLLLOCAL ~QoreSafeRWWriteLocker()
destroys the object and releases the lock
Definition: QoreRWLock.h:278
bool locked
lock flag
Definition: QoreRWLock.h:262
DLLEXPORT int q_gettid() noexcept
returns the current TID number