Qore Programming Language 2.1.1
Loading...
Searching...
No Matches
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 - 2024 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
40extern int q_gettid() noexcept;
41#endif
42
44
48public:
50 DLLLOCAL QoreRWLock() {
51#ifndef NDEBUG
52 int rc =
53#endif
54 pthread_rwlock_init(&m, 0);
55 assert(!rc);
56 }
57
59 DLLLOCAL ~QoreRWLock() {
60#ifndef NDEBUG
61 int rc =
62#endif
63 pthread_rwlock_destroy(&m);
64 assert(!rc);
65 }
66
68 DLLLOCAL int wrlock() {
69 return pthread_rwlock_wrlock(&m);
70 }
71
73 DLLLOCAL int trywrlock() {
74 return pthread_rwlock_trywrlock(&m);
75 }
76
78 DLLLOCAL int unlock() {
79 return pthread_rwlock_unlock(&m);
80 }
81
83 DLLLOCAL int rdlock() {
84 return pthread_rwlock_rdlock(&m);
85 }
86
88 DLLLOCAL int tryrdlock() {
89 return pthread_rwlock_tryrdlock(&m);
90 }
91
92protected:
94 pthread_rwlock_t m;
95
96 QoreRWLock& operator=(const QoreRWLock&) = delete;
97};
98
100
105private:
108
110 DLLLOCAL QoreAutoRWReadLocker& operator=(const QoreAutoRWReadLocker&);
111
113 DLLLOCAL void *operator new(size_t);
114
115protected:
118
119public:
121 DLLLOCAL QoreAutoRWReadLocker(QoreRWLock &n_l) : l(&n_l) {
122 l->rdlock();
123 }
124
126 DLLLOCAL QoreAutoRWReadLocker(QoreRWLock *n_l) : l(n_l) {
127 if (l)
128 l->rdlock();
129 }
130
133 if (l)
134 l->unlock();
135 }
136};
137
139
144private:
147
149 DLLLOCAL QoreAutoRWWriteLocker& operator=(const QoreAutoRWWriteLocker&);
150
152 DLLLOCAL void *operator new(size_t);
153
154protected:
157
158public:
160 DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock &n_l) : l(&n_l) {
161 l->wrlock();
162 }
163
165 DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock *n_l) : l(n_l) {
166 if (l)
167 l->wrlock();
168 }
169
172 if (l)
173 l->unlock();
174 }
175};
176
178
183public:
185 DLLLOCAL QoreSafeRWReadLocker() : l(nullptr), locked(false) {
186 }
187
189 DLLLOCAL QoreSafeRWReadLocker(QoreRWLock& n_l) : l(&n_l) {
190 l->rdlock();
191 locked = true;
192 }
193
195 DLLLOCAL QoreSafeRWReadLocker(QoreRWLock* n_l) : l(n_l) {
196 l->rdlock();
197 locked = true;
198 }
199
202 if (locked) {
203 l->unlock();
204 }
205 }
206
208 DLLLOCAL void lock() {
209 assert(!locked);
210 assert(l);
211 l->rdlock();
212 locked = true;
213 }
214
216 DLLLOCAL void unlock() {
217 assert(locked);
218 assert(l);
219 locked = false;
220 l->unlock();
221 }
222
224 DLLLOCAL void stay_locked() {
225 assert(locked);
226 assert(l);
227 locked = false;
228 }
229
231 DLLLOCAL void handoffTo(QoreRWLock& n) {
232 if (l) {
233 unlock();
234 }
235 l = &n;
236 lock();
237 }
238
239protected:
242
244 bool locked;
245
246private:
248 DLLLOCAL QoreSafeRWReadLocker(const QoreSafeRWReadLocker&) = delete;
249
251 DLLLOCAL QoreSafeRWReadLocker& operator=(const QoreSafeRWReadLocker&) = delete;
252
254 DLLLOCAL void* operator new(size_t) = delete;
255};
256
258
263private:
266
268 DLLLOCAL QoreSafeRWWriteLocker& operator=(const QoreSafeRWWriteLocker&);
269
271 DLLLOCAL void *operator new(size_t);
272
273protected:
276
278 bool locked;
279
280public:
282 DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock &n_l) : l(&n_l) {
283 l->wrlock();
284 locked = true;
285 }
286
288 DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock *n_l) : l(n_l) {
289 l->wrlock();
290 locked = true;
291 }
292
295 if (locked)
296 l->unlock();
297 }
298
300 DLLLOCAL void lock() {
301 assert(!locked);
302 l->wrlock();
303 locked = true;
304 }
305
307 DLLLOCAL void unlock() {
308 assert(locked);
309 locked = false;
310 l->unlock();
311 }
312
314 DLLLOCAL void stay_locked() {
315 assert(locked);
316 locked = false;
317 }
318};
319
320class QoreOptionalRWWriteLocker {
321protected:
322 QoreRWLock* l;
323
324public:
325 DLLLOCAL QoreOptionalRWWriteLocker(QoreRWLock* n_l) : l(n_l->trywrlock() ? 0 : n_l) {
326 }
327
328 DLLLOCAL QoreOptionalRWWriteLocker(QoreRWLock& n_l) : l(n_l.trywrlock() ? 0 : &n_l) {
329 }
330
331 DLLLOCAL ~QoreOptionalRWWriteLocker() {
332 if (l)
333 l->unlock();
334 }
335
336 DLLLOCAL operator bool() const {
337 return (bool)l;
338 }
339};
340
341class QoreOptionalRWReadLocker {
342protected:
343 QoreRWLock* l;
344
345public:
346 DLLLOCAL QoreOptionalRWReadLocker(QoreRWLock* n_l) : l(n_l->tryrdlock() ? 0 : n_l) {
347 }
348
349 DLLLOCAL QoreOptionalRWReadLocker(QoreRWLock& n_l) : l(n_l.tryrdlock() ? 0 : &n_l) {
350 }
351
352 DLLLOCAL ~QoreOptionalRWReadLocker() {
353 if (l)
354 l->unlock();
355 }
356
357 DLLLOCAL operator bool() const {
358 return (bool)l;
359 }
360};
361
362class qore_var_rwlock_priv;
363
364class QoreVarRWLock {
365 friend class qore_var_rwlock_priv;
366public:
367 DLLLOCAL QoreVarRWLock();
368
370 DLLLOCAL ~QoreVarRWLock();
371
373 DLLLOCAL void wrlock();
374
376 DLLLOCAL int trywrlock();
377
379 DLLLOCAL void unlock();
380
382 DLLLOCAL void rdlock();
383
385 DLLLOCAL int tryrdlock();
386
387protected:
388 qore_var_rwlock_priv* priv;
389
390 DLLLOCAL QoreVarRWLock(qore_var_rwlock_priv* p);
391
392private:
393 QoreVarRWLock(const QoreVarRWLock&) = delete;
394 QoreVarRWLock& operator=(const QoreVarRWLock&) = delete;
395};
396
397#endif
provides a safe and exception-safe way to hold read locks in Qore, only to be used on the stack,...
Definition QoreRWLock.h:104
DLLLOCAL QoreAutoRWReadLocker(QoreRWLock *n_l)
creates the object and grabs the read lock. If parameter is null then no function is performed.
Definition QoreRWLock.h:126
DLLLOCAL ~QoreAutoRWReadLocker()
destroys the object and releases the lock
Definition QoreRWLock.h:132
QoreRWLock * l
the pointer to the lock that will be managed
Definition QoreRWLock.h:117
DLLLOCAL QoreAutoRWReadLocker(QoreRWLock &n_l)
creates the object and grabs the read lock
Definition QoreRWLock.h:121
provides a safe and exception-safe way to hold write locks in Qore, only to be used on the stack,...
Definition QoreRWLock.h:143
DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock &n_l)
creates the object and grabs the write lock
Definition QoreRWLock.h:160
DLLLOCAL ~QoreAutoRWWriteLocker()
destroys the object and releases the lock
Definition QoreRWLock.h:171
QoreRWLock * l
the pointer to the lock that will be managed
Definition QoreRWLock.h:156
DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock *n_l)
creates the object and grabs the write lock. If parameter is null then no function is performed.
Definition QoreRWLock.h:165
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:94
DLLLOCAL ~QoreRWLock()
destroys the lock
Definition QoreRWLock.h:59
DLLLOCAL int wrlock()
grabs the write lock
Definition QoreRWLock.h:68
DLLLOCAL QoreRWLock()
creates and initializes the lock
Definition QoreRWLock.h:50
DLLLOCAL int trywrlock()
tries to grab the write lock; does not block if unsuccessful; returns 0 if successful
Definition QoreRWLock.h:73
DLLLOCAL int unlock()
unlocks the lock (assumes the lock is locked)
Definition QoreRWLock.h:78
DLLLOCAL int rdlock()
grabs the read lock
Definition QoreRWLock.h:83
DLLLOCAL int tryrdlock()
tries to grab the read lock; does not block if unsuccessful; returns 0 if successful
Definition QoreRWLock.h:88
provides a safe and exception-safe way to hold read locks in Qore, only to be used on the stack,...
Definition QoreRWLock.h:182
DLLLOCAL void handoffTo(QoreRWLock &n)
Handoff to another read lock.
Definition QoreRWLock.h:231
DLLLOCAL QoreSafeRWReadLocker()
creates an empty object
Definition QoreRWLock.h:185
DLLLOCAL QoreSafeRWReadLocker(QoreRWLock *n_l)
creates the object and grabs the read lock
Definition QoreRWLock.h:195
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition QoreRWLock.h:216
bool locked
lock flag
Definition QoreRWLock.h:244
DLLLOCAL ~QoreSafeRWReadLocker()
destroys the object and releases the lock
Definition QoreRWLock.h:201
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held
Definition QoreRWLock.h:208
DLLLOCAL QoreSafeRWReadLocker(QoreRWLock &n_l)
creates the object and grabs the read lock
Definition QoreRWLock.h:189
QoreRWLock * l
the pointer to the lock that will be managed
Definition QoreRWLock.h:241
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:224
provides a safe and exception-safe way to hold write locks in Qore, only to be used on the stack,...
Definition QoreRWLock.h:262
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition QoreRWLock.h:307
DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock &n_l)
creates the object and grabs the write lock
Definition QoreRWLock.h:282
QoreRWLock * l
the pointer to the lock that will be managed
Definition QoreRWLock.h:275
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held
Definition QoreRWLock.h:300
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:314
DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock *n_l)
creates the object and grabs the write lock
Definition QoreRWLock.h:288
DLLLOCAL ~QoreSafeRWWriteLocker()
destroys the object and releases the lock
Definition QoreRWLock.h:294
bool locked
lock flag
Definition QoreRWLock.h:278
DLLEXPORT int q_gettid() noexcept
returns the current TID number