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

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 - 2020 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
105 class QoreAutoRWReadLocker {
106 private:
108 DLLLOCAL QoreAutoRWReadLocker(const QoreAutoRWReadLocker&);
109
111 DLLLOCAL QoreAutoRWReadLocker& operator=(const QoreAutoRWReadLocker&);
112
114 DLLLOCAL void *operator new(size_t);
115
116 protected:
118 QoreRWLock *l;
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
133 DLLLOCAL ~QoreAutoRWReadLocker() {
134 if (l)
135 l->unlock();
136 }
137 };
138
140
144 class QoreAutoRWWriteLocker {
145 private:
147 DLLLOCAL QoreAutoRWWriteLocker(const QoreAutoRWWriteLocker&);
148
150 DLLLOCAL QoreAutoRWWriteLocker& operator=(const QoreAutoRWWriteLocker&);
151
153 DLLLOCAL void *operator new(size_t);
154
155 protected:
157 QoreRWLock *l;
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
172 DLLLOCAL ~QoreAutoRWWriteLocker() {
173 if (l)
174 l->unlock();
175 }
176 };
177
179
183 class QoreSafeRWReadLocker {
184 private:
186 DLLLOCAL QoreSafeRWReadLocker(const QoreSafeRWReadLocker&);
187
189 DLLLOCAL QoreSafeRWReadLocker& operator=(const QoreSafeRWReadLocker&);
190
192 DLLLOCAL void *operator new(size_t);
193
194 protected:
196 QoreRWLock *l;
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
215 DLLLOCAL ~QoreSafeRWReadLocker() {
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
246 class QoreSafeRWWriteLocker {
247 private:
249 DLLLOCAL QoreSafeRWWriteLocker(const QoreSafeRWWriteLocker&);
250
252 DLLLOCAL QoreSafeRWWriteLocker& operator=(const QoreSafeRWWriteLocker&);
253
255 DLLLOCAL void *operator new(size_t);
256
257 protected:
259 QoreRWLock *l;
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
278 DLLLOCAL ~QoreSafeRWWriteLocker() {
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
QoreAutoRWWriteLocker
provides a safe and exception-safe way to hold write locks in Qore, only to be used on the stack...
Definition: QoreRWLock.h:144
QoreRWLock::wrlock
DLLLOCAL int wrlock()
grabs the write lock
Definition: QoreRWLock.h:75
QoreSafeRWReadLocker::unlock
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition: QoreRWLock.h:228
QoreSafeRWReadLocker::~QoreSafeRWReadLocker
DLLLOCAL ~QoreSafeRWReadLocker()
destroys the object and releases the lock
Definition: QoreRWLock.h:215
QoreSafeRWWriteLocker::unlock
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition: QoreRWLock.h:291
QoreRWLock::QoreRWLock
DLLLOCAL QoreRWLock()
creates and initializes the lock
Definition: QoreRWLock.h:57
QoreRWLock::~QoreRWLock
DLLLOCAL ~QoreRWLock()
destroys the lock
Definition: QoreRWLock.h:66
QoreAutoRWReadLocker::~QoreAutoRWReadLocker
DLLLOCAL ~QoreAutoRWReadLocker()
destroys the object and releases the lock
Definition: QoreRWLock.h:133
QoreAutoRWWriteLocker::~QoreAutoRWWriteLocker
DLLLOCAL ~QoreAutoRWWriteLocker()
destroys the object and releases the lock
Definition: QoreRWLock.h:172
QoreSafeRWWriteLocker::locked
bool locked
lock flag
Definition: QoreRWLock.h:262
QoreSafeRWReadLocker::locked
bool locked
lock flag
Definition: QoreRWLock.h:199
QoreSafeRWWriteLocker
provides a safe and exception-safe way to hold write locks in Qore, only to be used on the stack...
Definition: QoreRWLock.h:246
QoreRWLock::unlock
DLLLOCAL int unlock()
unlocks the lock (assumes the lock is locked)
Definition: QoreRWLock.h:85
QoreRWLock::rdlock
DLLLOCAL int rdlock()
grabs the read lock
Definition: QoreRWLock.h:90
QoreAutoRWReadLocker
provides a safe and exception-safe way to hold read locks in Qore, only to be used on the stack...
Definition: QoreRWLock.h:105
QoreSafeRWReadLocker
provides a safe and exception-safe way to hold read locks in Qore, only to be used on the stack...
Definition: QoreRWLock.h:183
QoreAutoRWWriteLocker::l
QoreRWLock * l
the pointer to the lock that will be managed
Definition: QoreRWLock.h:157
QoreSafeRWReadLocker::lock
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held ...
Definition: QoreRWLock.h:221
QoreAutoRWReadLocker::l
QoreRWLock * l
the pointer to the lock that will be managed
Definition: QoreRWLock.h:118
QoreSafeRWReadLocker::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: QoreRWLock.h:235
QoreRWLock
provides a simple POSIX-threads-based read-write lock
Definition: QoreRWLock.h:47
QoreRWLock::m
pthread_rwlock_t m
the actual locking primitive wrapped in this class
Definition: QoreRWLock.h:50
QoreSafeRWWriteLocker::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: QoreRWLock.h:298
QoreRWLock::tryrdlock
DLLLOCAL int tryrdlock()
tries to grab the read lock; does not block if unsuccessful; returns 0 if successful ...
Definition: QoreRWLock.h:95
q_gettid
DLLEXPORT int q_gettid() noexcept
returns the current TID number
QoreRWLock::operator=
DLLLOCAL QoreRWLock & operator=(const QoreRWLock &)
this function is not implemented; it is here as a private function in order to prohibit it from being...
QoreSafeRWWriteLocker::l
QoreRWLock * l
the pointer to the lock that will be managed
Definition: QoreRWLock.h:259
QoreSafeRWReadLocker::l
QoreRWLock * l
the pointer to the lock that will be managed
Definition: QoreRWLock.h:196
QoreSafeRWWriteLocker::lock
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held ...
Definition: QoreRWLock.h:284
QoreRWLock::trywrlock
DLLLOCAL int trywrlock()
tries to grab the write lock; does not block if unsuccessful; returns 0 if successful ...
Definition: QoreRWLock.h:80
QoreSafeRWWriteLocker::~QoreSafeRWWriteLocker
DLLLOCAL ~QoreSafeRWWriteLocker()
destroys the object and releases the lock
Definition: QoreRWLock.h:278