QoreThreadLock.h
/* -*- mode: c++; indent-tabs-mode: nil -*- */
/*
QoreThreadLock.h
Qore Programming Language
Copyright (C) 2003 - 2021 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_QORETHREADLOCK_H
#define _QORE_QORETHREADLOCK_H
#include <cassert>
#include <csignal>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <pthread.h>
class QoreThreadLock {
friend class QoreCondition;
public:
DLLLOCAL QoreThreadLock() : QoreThreadLock(nullptr) {
}
DLLLOCAL QoreThreadLock(const pthread_mutexattr_t* ma) {
#ifndef NDEBUG
int rc =
#endif
pthread_mutex_init(&ptm_lock, ma);
assert(!rc);
}
DLLLOCAL QoreThreadLock(const QoreThreadLock&) : QoreThreadLock(nullptr) {
}
DLLLOCAL ~QoreThreadLock() {
pthread_mutex_destroy(&ptm_lock);
}
DLLLOCAL void lock() {
#ifndef NDEBUG
int rc =
#endif
pthread_mutex_lock(&ptm_lock);
assert(!rc);
}
DLLLOCAL void unlock() {
#ifndef NDEBUG
int rc =
#endif
pthread_mutex_unlock(&ptm_lock);
assert(!rc);
}
DLLLOCAL int trylock() {
return pthread_mutex_trylock(&ptm_lock);
}
private:
pthread_mutex_t ptm_lock;
DLLLOCAL QoreThreadLock& operator=(const QoreThreadLock&) = delete;
};
class QoreRecursiveThreadLock : public QoreThreadLock {
public:
DLLEXPORT QoreRecursiveThreadLock();
DLLLOCAL QoreRecursiveThreadLock(const QoreRecursiveThreadLock&) : QoreRecursiveThreadLock() {
}
};
class AutoLocker {
public:
DLLLOCAL AutoLocker(QoreThreadLock* l) : lck(l) {
lck->lock();
}
DLLLOCAL AutoLocker(QoreThreadLock& l) : lck(&l) {
lck->lock();
}
DLLLOCAL AutoLocker(QoreThreadLock* l, bool already_locked) : lck(l) {
if (!already_locked) {
lck->lock();
}
}
DLLLOCAL AutoLocker(QoreThreadLock& l, bool already_locked) : lck(&l) {
if (!already_locked) {
lck->lock();
}
}
DLLLOCAL ~AutoLocker() {
lck->unlock();
}
private:
DLLLOCAL AutoLocker(const AutoLocker&) = delete;
DLLLOCAL AutoLocker& operator=(const AutoLocker&) = delete;
DLLLOCAL void *operator new(size_t) = delete;
protected:
QoreThreadLock* lck;
};
class AutoUnlocker {
public:
DLLLOCAL AutoUnlocker(QoreThreadLock* l) : lck(l) {
if (lck)
lck->unlock();
}
DLLLOCAL AutoUnlocker(QoreThreadLock& l) : lck(&l) {
lck->unlock();
}
DLLLOCAL ~AutoUnlocker() {
if (lck)
lck->lock();
}
private:
DLLLOCAL AutoUnlocker(const AutoUnlocker&) = delete;
DLLLOCAL AutoUnlocker& operator=(const AutoUnlocker&) = delete;
DLLLOCAL void *operator new(size_t) = delete;
protected:
QoreThreadLock* lck;
};
class SafeLocker {
public:
DLLLOCAL SafeLocker(QoreThreadLock* l) : lck(l) {
lck->lock();
locked = true;
}
DLLLOCAL SafeLocker(QoreThreadLock& l) : lck(&l) {
lck->lock();
locked = true;
}
DLLLOCAL ~SafeLocker() {
if (locked)
lck->unlock();
}
DLLLOCAL void lock() {
assert(!locked);
lck->lock();
locked = true;
}
DLLLOCAL void unlock() {
assert(locked);
locked = false;
lck->unlock();
}
DLLLOCAL void stay_locked() {
assert(locked);
locked = false;
}
DLLLOCAL void relock() {
assert(!locked);
lck->lock();
locked = true;
}
private:
DLLLOCAL SafeLocker(const SafeLocker&) = delete;
DLLLOCAL SafeLocker& operator=(const SafeLocker&) = delete;
DLLLOCAL void *operator new(size_t) = delete;
protected:
QoreThreadLock* lck;
bool locked;
};
class OptLocker {
public:
DLLLOCAL OptLocker(QoreThreadLock* l) : lck(l) {
if (lck)
lck->lock();
}
DLLLOCAL ~OptLocker() {
if (lck)
lck->unlock();
}
private:
DLLLOCAL OptLocker(const OptLocker&) = delete;
DLLLOCAL OptLocker& operator=(const OptLocker&) = delete;
DLLLOCAL void *operator new(size_t) = delete;
protected:
QoreThreadLock* lck;
};
#endif // _QORE_QORETHREADLOCK_H
QoreThreadLock::~QoreThreadLock
DLLLOCAL ~QoreThreadLock()
destroys the lock
Definition: QoreThreadLock.h:71
AutoUnlocker::~AutoUnlocker
DLLLOCAL ~AutoUnlocker()
grabs the lock and destroys the object
Definition: QoreThreadLock.h:204
AutoLocker::~AutoLocker
DLLLOCAL ~AutoLocker()
destroys the object and releases the lock
Definition: QoreThreadLock.h:167
AutoLocker::AutoLocker
DLLLOCAL AutoLocker(QoreThreadLock *l)
creates the object and grabs the lock
Definition: QoreThreadLock.h:139
QoreRecursiveThreadLock::QoreRecursiveThreadLock
DLLEXPORT QoreRecursiveThreadLock()
Creates the object.
SafeLocker::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: QoreThreadLock.h:263
AutoUnlocker::AutoUnlocker
DLLLOCAL AutoUnlocker(QoreThreadLock *l)
creates the object and releases the lock
Definition: QoreThreadLock.h:193
QoreThreadLock::trylock
DLLLOCAL int trylock()
attempts to acquire the mutex and returns the status immediately; does not block
Definition: QoreThreadLock.h:101
QoreCondition
a thread condition class implementing a wrapper for pthread_cond_t
Definition: QoreCondition.h:45
QoreRecursiveThreadLock
Implements a recursive lock.
Definition: QoreThreadLock.h:116
SafeLocker::unlock
DLLLOCAL void unlock()
unlocks the object and updates the locked flag, assumes that the lock is held
Definition: QoreThreadLock.h:256
SafeLocker::relock
DLLLOCAL void relock()
relocks an unlock lock
Definition: QoreThreadLock.h:269
AutoLocker
provides a safe and exception-safe way to hold locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:136
OptLocker
provides a safe and exception-safe way to hold optional locks in Qore, only to be used on the stack...
Definition: QoreThreadLock.h:293
QoreThreadLock::lock
DLLLOCAL void lock()
grabs the lock (assumes that the lock is unlocked)
Definition: QoreThreadLock.h:78
AutoLocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:178
QoreThreadLock::unlock
DLLLOCAL void unlock()
releases the lock (assumes that the lock is locked)
Definition: QoreThreadLock.h:89
AutoUnlocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:216
OptLocker::OptLocker
DLLLOCAL OptLocker(QoreThreadLock *l)
creates the object and grabs the lock if the argument is not NULL
Definition: QoreThreadLock.h:296
SafeLocker::~SafeLocker
DLLLOCAL ~SafeLocker()
destroys the object and unlocks the lock if it&#39;s held
Definition: QoreThreadLock.h:243
SafeLocker::locked
bool locked
flag indicating if the lock is held or not
Definition: QoreThreadLock.h:285
QoreThreadLock
provides a mutually-exclusive thread lock
Definition: QoreThreadLock.h:49
SafeLocker::SafeLocker
DLLLOCAL SafeLocker(QoreThreadLock *l)
creates the object and grabs the lock
Definition: QoreThreadLock.h:231
OptLocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:314
QoreThreadLock::QoreThreadLock
DLLLOCAL QoreThreadLock()
creates the lock
Definition: QoreThreadLock.h:54
SafeLocker::lck
QoreThreadLock * lck
the pointer to the lock that will be managed
Definition: QoreThreadLock.h:282
SafeLocker::lock
DLLLOCAL void lock()
locks the object and updates the locked flag, assumes that the lock is not already held ...
Definition: QoreThreadLock.h:249
SafeLocker
provides an exception-safe way to manage locks in Qore, only to be used on the stack, cannot be dynamically allocated
Definition: QoreThreadLock.h:228
AutoUnlocker
provides a safe and exception-safe way to release and re-acquire locks in Qore, only to be used on th...
Definition: QoreThreadLock.h:190
OptLocker::~OptLocker
DLLLOCAL ~OptLocker()
releases the lock if there is a lock pointer being managed and destroys the object ...
Definition: QoreThreadLock.h:302