QoreRWLock.h
/* -*- mode: c++; indent-tabs-mode: nil -*- */
/*
QoreRWLock.h
simple pthreads-based read-write lock
Qore Programming Language
Copyright (C) 2003 - 2020 Qore Technologies, s.r.o.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
Note that the Qore library is released under a choice of three open-source
licenses: MIT (as above), LGPL 2+, or GPL 2+; see README-LICENSE for more
information.
*/
#ifndef _QORE_QORERWLOCK_H
#define _QORE_QORERWLOCK_H
#include <pthread.h>
#ifdef DEBUG
extern int q_gettid() noexcept;
#endif
class QoreRWLock {
protected:
pthread_rwlock_t m;
DLLLOCAL QoreRWLock& operator=(const QoreRWLock&);
public:
DLLLOCAL QoreRWLock() {
#ifndef NDEBUG
int rc =
#endif
pthread_rwlock_init(&m, 0);
assert(!rc);
}
DLLLOCAL ~QoreRWLock() {
#ifndef NDEBUG
int rc =
#endif
pthread_rwlock_destroy(&m);
assert(!rc);
}
DLLLOCAL int wrlock() {
return pthread_rwlock_wrlock(&m);
}
DLLLOCAL int trywrlock() {
return pthread_rwlock_trywrlock(&m);
}
DLLLOCAL int unlock() {
return pthread_rwlock_unlock(&m);
}
DLLLOCAL int rdlock() {
return pthread_rwlock_rdlock(&m);
}
DLLLOCAL int tryrdlock() {
return pthread_rwlock_tryrdlock(&m);
}
};
class QoreAutoRWReadLocker {
private:
DLLLOCAL QoreAutoRWReadLocker(const QoreAutoRWReadLocker&);
DLLLOCAL QoreAutoRWReadLocker& operator=(const QoreAutoRWReadLocker&);
DLLLOCAL void *operator new(size_t);
protected:
QoreRWLock *l;
public:
DLLLOCAL QoreAutoRWReadLocker(QoreRWLock &n_l) : l(&n_l) {
l->rdlock();
}
DLLLOCAL QoreAutoRWReadLocker(QoreRWLock *n_l) : l(n_l) {
if (l)
l->rdlock();
}
DLLLOCAL ~QoreAutoRWReadLocker() {
if (l)
l->unlock();
}
};
class QoreAutoRWWriteLocker {
private:
DLLLOCAL QoreAutoRWWriteLocker(const QoreAutoRWWriteLocker&);
DLLLOCAL QoreAutoRWWriteLocker& operator=(const QoreAutoRWWriteLocker&);
DLLLOCAL void *operator new(size_t);
protected:
QoreRWLock *l;
public:
DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock &n_l) : l(&n_l) {
l->wrlock();
}
DLLLOCAL QoreAutoRWWriteLocker(QoreRWLock *n_l) : l(n_l) {
if (l)
l->wrlock();
}
DLLLOCAL ~QoreAutoRWWriteLocker() {
if (l)
l->unlock();
}
};
class QoreSafeRWReadLocker {
private:
DLLLOCAL QoreSafeRWReadLocker(const QoreSafeRWReadLocker&);
DLLLOCAL QoreSafeRWReadLocker& operator=(const QoreSafeRWReadLocker&);
DLLLOCAL void *operator new(size_t);
protected:
QoreRWLock *l;
bool locked;
public:
DLLLOCAL QoreSafeRWReadLocker(QoreRWLock &n_l) : l(&n_l) {
l->rdlock();
locked = true;
}
DLLLOCAL QoreSafeRWReadLocker(QoreRWLock *n_l) : l(n_l) {
l->rdlock();
locked = true;
}
DLLLOCAL ~QoreSafeRWReadLocker() {
if (locked)
l->unlock();
}
DLLLOCAL void lock() {
assert(!locked);
l->rdlock();
locked = true;
}
DLLLOCAL void unlock() {
assert(locked);
locked = false;
l->unlock();
}
DLLLOCAL void stay_locked() {
assert(locked);
locked = false;
}
};
class QoreSafeRWWriteLocker {
private:
DLLLOCAL QoreSafeRWWriteLocker(const QoreSafeRWWriteLocker&);
DLLLOCAL QoreSafeRWWriteLocker& operator=(const QoreSafeRWWriteLocker&);
DLLLOCAL void *operator new(size_t);
protected:
QoreRWLock *l;
bool locked;
public:
DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock &n_l) : l(&n_l) {
l->wrlock();
locked = true;
}
DLLLOCAL QoreSafeRWWriteLocker(QoreRWLock *n_l) : l(n_l) {
l->wrlock();
locked = true;
}
DLLLOCAL ~QoreSafeRWWriteLocker() {
if (locked)
l->unlock();
}
DLLLOCAL void lock() {
assert(!locked);
l->wrlock();
locked = true;
}
DLLLOCAL void unlock() {
assert(locked);
locked = false;
l->unlock();
}
DLLLOCAL void stay_locked() {
assert(locked);
locked = false;
}
};
class QoreOptionalRWWriteLocker {
protected:
QoreRWLock* l;
public:
DLLLOCAL QoreOptionalRWWriteLocker(QoreRWLock* n_l) : l(n_l->trywrlock() ? 0 : n_l) {
}
DLLLOCAL QoreOptionalRWWriteLocker(QoreRWLock& n_l) : l(n_l.trywrlock() ? 0 : &n_l) {
}
DLLLOCAL ~QoreOptionalRWWriteLocker() {
if (l)
l->unlock();
}
DLLLOCAL operator bool() const {
return (bool)l;
}
};
class QoreOptionalRWReadLocker {
protected:
QoreRWLock* l;
public:
DLLLOCAL QoreOptionalRWReadLocker(QoreRWLock* n_l) : l(n_l->tryrdlock() ? 0 : n_l) {
}
DLLLOCAL QoreOptionalRWReadLocker(QoreRWLock& n_l) : l(n_l.tryrdlock() ? 0 : &n_l) {
}
DLLLOCAL ~QoreOptionalRWReadLocker() {
if (l)
l->unlock();
}
DLLLOCAL operator bool() const {
return (bool)l;
}
};
class qore_var_rwlock_priv;
class QoreVarRWLock {
private:
DLLLOCAL QoreVarRWLock(const QoreVarRWLock&);
DLLLOCAL QoreVarRWLock& operator=(const QoreVarRWLock&);
protected:
qore_var_rwlock_priv* priv;
DLLLOCAL QoreVarRWLock(qore_var_rwlock_priv* p);
public:
DLLLOCAL QoreVarRWLock();
DLLLOCAL ~QoreVarRWLock();
DLLLOCAL void wrlock();
DLLLOCAL int trywrlock();
DLLLOCAL void unlock();
DLLLOCAL void rdlock();
DLLLOCAL int tryrdlock();
};
#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