Qore Programming Language 2.2.0
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#ifndef NDEBUG
70 int rc = pthread_rwlock_wrlock(&m);
71 if (!rc) {
72 wr_tid = q_gettid();
73 }
74 return rc;
75#else
76 return pthread_rwlock_wrlock(&m);
77#endif
78 }
79
81 DLLLOCAL int trywrlock() {
82#ifndef NDEBUG
83 int rc = pthread_rwlock_trywrlock(&m);
84 if (!rc) {
85 wr_tid = q_gettid();
86 }
87 return rc;
88#else
89 return pthread_rwlock_trywrlock(&m);
90#endif
91 }
92
94 DLLLOCAL int unlock() {
95#ifndef NDEBUG
96 if (wr_tid != -1) {
97 wr_tid = -1;
98 }
99#endif
100 return pthread_rwlock_unlock(&m);
101 }
102
104 DLLLOCAL int rdlock() {
105 return pthread_rwlock_rdlock(&m);
106 }
107
109 DLLLOCAL int tryrdlock() {
110 return pthread_rwlock_tryrdlock(&m);
111 }
112
113protected:
115 pthread_rwlock_t m;
116#ifndef NDEBUG
117 int wr_tid = -1;
118#endif
119
120 QoreRWLock& operator=(const QoreRWLock&) = delete;
121};
122
124
129private:
132
134 DLLLOCAL QoreAutoRWReadLocker& operator=(const QoreAutoRWReadLocker&);
135
137 DLLLOCAL void *operator new(size_t);
138
139protected:
142
143public:
145 DLLLOCAL QoreAutoRWReadLocker(QoreRWLock &n_l) : l(&n_l) {
146 l->rdlock();
147 }
148
150 DLLLOCAL QoreAutoRWReadLocker(QoreRWLock *n_l) : l(n_l) {
151 if (l)
152 l->rdlock();
153 }
154
157 if (l)
158 l->unlock();
159 }
160};
161
163
168private:
171
173 DLLLOCAL QoreAutoRWWriteLocker& operator=(const QoreAutoRWWriteLocker&);
174
176 DLLLOCAL void *operator new(size_t);
177
178protected:
181
182public:
184 DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock &n_l) : l(&n_l) {
185 l->wrlock();
186 }
187
189 DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock *n_l) : l(n_l) {
190 if (l)
191 l->wrlock();
192 }
193
196 if (l)
197 l->unlock();
198 }
199};
200
202
207public:
209 DLLLOCAL QoreSafeRWReadLocker() : l(nullptr), locked(false) {
210 }
211
213 DLLLOCAL QoreSafeRWReadLocker(QoreRWLock& n_l) : l(&n_l) {
214 l->rdlock();
215 locked = true;
216 }
217
219 DLLLOCAL QoreSafeRWReadLocker(QoreRWLock* n_l) : l(n_l) {
220 l->rdlock();
221 locked = true;
222 }
223
226 if (locked) {
227 l->unlock();
228 }
229 }
230
232 DLLLOCAL void lock() {
233 assert(!locked);
234 assert(l);
235 l->rdlock();
236 locked = true;
237 }
238
240 DLLLOCAL void unlock() {
241 assert(locked);
242 assert(l);
243 locked = false;
244 l->unlock();
245 }
246
248 DLLLOCAL void stay_locked() {
249 assert(locked);
250 assert(l);
251 locked = false;
252 }
253
255 DLLLOCAL void handoffTo(QoreRWLock& n) {
256 if (l) {
257 unlock();
258 }
259 l = &n;
260 lock();
261 }
262
263protected:
266
268 bool locked;
269
270private:
272 DLLLOCAL QoreSafeRWReadLocker(const QoreSafeRWReadLocker&) = delete;
273
275 DLLLOCAL QoreSafeRWReadLocker& operator=(const QoreSafeRWReadLocker&) = delete;
276
278 DLLLOCAL void* operator new(size_t) = delete;
279};
280
282
287private:
290
292 DLLLOCAL QoreSafeRWWriteLocker& operator=(const QoreSafeRWWriteLocker&);
293
295 DLLLOCAL void *operator new(size_t);
296
297protected:
300
302 bool locked;
303
304public:
306 DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock &n_l) : l(&n_l) {
307 l->wrlock();
308 locked = true;
309 }
310
312 DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock *n_l) : l(n_l) {
313 l->wrlock();
314 locked = true;
315 }
316
319 if (locked)
320 l->unlock();
321 }
322
324 DLLLOCAL void lock() {
325 assert(!locked);
326 l->wrlock();
327 locked = true;
328 }
329
331 DLLLOCAL void unlock() {
332 assert(locked);
333 locked = false;
334 l->unlock();
335 }
336
338 DLLLOCAL void stay_locked() {
339 assert(locked);
340 locked = false;
341 }
342};
343
344class QoreOptionalRWWriteLocker {
345protected:
346 QoreRWLock* l;
347
348public:
349 DLLLOCAL QoreOptionalRWWriteLocker(QoreRWLock* n_l) : l(n_l->trywrlock() ? 0 : n_l) {
350 }
351
352 DLLLOCAL QoreOptionalRWWriteLocker(QoreRWLock& n_l) : l(n_l.trywrlock() ? 0 : &n_l) {
353 }
354
355 DLLLOCAL ~QoreOptionalRWWriteLocker() {
356 if (l)
357 l->unlock();
358 }
359
360 DLLLOCAL operator bool() const {
361 return (bool)l;
362 }
363};
364
365class QoreOptionalRWReadLocker {
366protected:
367 QoreRWLock* l;
368
369public:
370 DLLLOCAL QoreOptionalRWReadLocker(QoreRWLock* n_l) : l(n_l->tryrdlock() ? 0 : n_l) {
371 }
372
373 DLLLOCAL QoreOptionalRWReadLocker(QoreRWLock& n_l) : l(n_l.tryrdlock() ? 0 : &n_l) {
374 }
375
376 DLLLOCAL ~QoreOptionalRWReadLocker() {
377 if (l)
378 l->unlock();
379 }
380
381 DLLLOCAL operator bool() const {
382 return (bool)l;
383 }
384};
385
386class qore_var_rwlock_priv;
387
388class QoreVarRWLock {
389 friend class qore_var_rwlock_priv;
390public:
391 DLLLOCAL QoreVarRWLock();
392
394 DLLLOCAL ~QoreVarRWLock();
395
397 DLLLOCAL void wrlock();
398
400 DLLLOCAL int trywrlock();
401
403 DLLLOCAL void unlock();
404
406 DLLLOCAL void rdlock();
407
409 DLLLOCAL int tryrdlock();
410
411protected:
412 qore_var_rwlock_priv* priv;
413
414 DLLLOCAL QoreVarRWLock(qore_var_rwlock_priv* p);
415
416private:
417 QoreVarRWLock(const QoreVarRWLock&) = delete;
418 QoreVarRWLock& operator=(const QoreVarRWLock&) = delete;
419};
420
421#endif
provides a safe and exception-safe way to hold read locks in Qore, only to be used on the stack,...
Definition QoreRWLock.h:128
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:150
DLLLOCAL ~QoreAutoRWReadLocker()
destroys the object and releases the lock
Definition QoreRWLock.h:156
QoreRWLock * l
the pointer to the lock that will be managed
Definition QoreRWLock.h:141
DLLLOCAL QoreAutoRWReadLocker(QoreRWLock &n_l)
creates the object and grabs the read lock
Definition QoreRWLock.h:145
provides a safe and exception-safe way to hold write locks in Qore, only to be used on the stack,...
Definition QoreRWLock.h:167
DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock &n_l)
creates the object and grabs the write lock
Definition QoreRWLock.h:184
DLLLOCAL ~QoreAutoRWWriteLocker()
destroys the object and releases the lock
Definition QoreRWLock.h:195
QoreRWLock * l
the pointer to the lock that will be managed
Definition QoreRWLock.h:180
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:189
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:115
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:81
DLLLOCAL int unlock()
unlocks the lock (assumes the lock is locked)
Definition QoreRWLock.h:94
DLLLOCAL int rdlock()
grabs the read lock
Definition QoreRWLock.h:104
DLLLOCAL int tryrdlock()
tries to grab the read lock; does not block if unsuccessful; returns 0 if successful
Definition QoreRWLock.h:109
provides a safe and exception-safe way to hold read locks in Qore, only to be used on the stack,...
Definition QoreRWLock.h:206
DLLLOCAL void handoffTo(QoreRWLock &n)
Handoff to another read lock.
Definition QoreRWLock.h:255
DLLLOCAL QoreSafeRWReadLocker()
creates an empty object
Definition QoreRWLock.h:209
DLLLOCAL QoreSafeRWReadLocker(QoreRWLock *n_l)
creates the object and grabs the read lock
Definition QoreRWLock.h:219
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition QoreRWLock.h:240
bool locked
lock flag
Definition QoreRWLock.h:268
DLLLOCAL ~QoreSafeRWReadLocker()
destroys the object and releases the lock
Definition QoreRWLock.h:225
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held
Definition QoreRWLock.h:232
DLLLOCAL QoreSafeRWReadLocker(QoreRWLock &n_l)
creates the object and grabs the read lock
Definition QoreRWLock.h:213
QoreRWLock * l
the pointer to the lock that will be managed
Definition QoreRWLock.h:265
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:248
provides a safe and exception-safe way to hold write locks in Qore, only to be used on the stack,...
Definition QoreRWLock.h:286
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition QoreRWLock.h:331
DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock &n_l)
creates the object and grabs the write lock
Definition QoreRWLock.h:306
QoreRWLock * l
the pointer to the lock that will be managed
Definition QoreRWLock.h:299
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held
Definition QoreRWLock.h:324
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:338
DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock *n_l)
creates the object and grabs the write lock
Definition QoreRWLock.h:312
DLLLOCAL ~QoreSafeRWWriteLocker()
destroys the object and releases the lock
Definition QoreRWLock.h:318
bool locked
lock flag
Definition QoreRWLock.h:302
DLLEXPORT int q_gettid() noexcept
returns the current TID number