140 lines
5.7 KiB
C++
140 lines
5.7 KiB
C++
/*! \file pireadwritelock.h
|
||
* \ingroup Thread
|
||
* \~\brief
|
||
* \~english Read-write lock with multiple readers or one writer
|
||
* \~russian Блокировка чтения-записи с несколькими читателями или одним писателем
|
||
*/
|
||
/*
|
||
PIP - Platform Independent Primitives
|
||
PIReadWriteLock, PIReadLocker, PIWriteLocker
|
||
Ivan Pelipenko peri4ko@yandex.ru
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU Lesser General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or
|
||
(at your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU Lesser General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public License
|
||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
#ifndef PIREADWRITELOCK_H
|
||
#define PIREADWRITELOCK_H
|
||
|
||
#include "piconditionvar.h"
|
||
|
||
//! \~\ingroup Thread
|
||
//! \~\brief
|
||
//! \~english Synchronization primitive that allows concurrent readers and exclusive writer access.
|
||
//! \~russian Примитив синхронизации, допускающий одновременных читателей и эксклюзивный доступ писателя.
|
||
class PIP_EXPORT PIReadWriteLock {
|
||
public:
|
||
NO_COPY_CLASS(PIReadWriteLock)
|
||
|
||
//! \~english Constructs %PIReadWriteLock.
|
||
//! \~russian Создает %PIReadWriteLock.
|
||
PIReadWriteLock();
|
||
|
||
//! \~english Destroy %PIReadWriteLock.
|
||
//! \~russian Деструктор %PIReadWriteLock.
|
||
~PIReadWriteLock();
|
||
|
||
|
||
//! \~english Acquires writer access, waiting until there are no active readers or writer.
|
||
//! \~russian Захватывает доступ на запись, ожидая отсутствия активных читателей и писателя.
|
||
void lockWrite();
|
||
|
||
//! \~english Tries to acquire writer access without waiting.
|
||
//! \~russian Пытается захватить доступ на запись без ожидания.
|
||
bool tryLockWrite();
|
||
|
||
//! \~english Tries to acquire writer access within \a timeout.
|
||
//! \~russian Пытается захватить доступ на запись в пределах \a timeout.
|
||
bool tryLockWrite(PISystemTime timeout);
|
||
|
||
//! \~english Releases writer access and wakes waiting threads.
|
||
//! \~russian Освобождает доступ на запись и пробуждает ожидающие потоки.
|
||
void unlockWrite();
|
||
|
||
|
||
//! \~english Acquires one reader slot, waiting while writer access is active.
|
||
//! \~russian Захватывает одно место читателя, ожидая пока активен доступ на запись.
|
||
void lockRead();
|
||
|
||
//! \~english Tries to acquire reader access without waiting.
|
||
//! \~russian Пытается захватить доступ на чтение без ожидания.
|
||
bool tryLockRead();
|
||
|
||
//! \~english Tries to acquire reader access within \a timeout.
|
||
//! \~russian Пытается захватить доступ на чтение в пределах \a timeout.
|
||
bool tryLockRead(PISystemTime timeout);
|
||
|
||
//! \~english Releases one reader slot and wakes waiting threads.
|
||
//! \~russian Освобождает одно место читателя и пробуждает ожидающие потоки.
|
||
void unlockRead();
|
||
|
||
private:
|
||
int reading = 0;
|
||
bool writing = false;
|
||
PIMutex mutex;
|
||
PIConditionVariable var;
|
||
};
|
||
|
||
//! \~\ingroup Thread
|
||
//! \~\brief
|
||
//! \~english Scope guard that acquires reader access in constructor and releases it in destructor.
|
||
//! \~russian Защитник области видимости, который захватывает доступ на чтение в конструкторе и освобождает его в деструкторе.
|
||
class PIP_EXPORT PIReadLocker {
|
||
public:
|
||
NO_COPY_CLASS(PIReadLocker);
|
||
|
||
//! \~english Constructs and lock for read %PIReadWriteLock "l" if "condition" is \c true.
|
||
//! \~russian Создается и блокирует на чтение %PIReadWriteLock "l" если "condition" \c true.
|
||
PIReadLocker(PIReadWriteLock & l, bool condition = true): rwl(l), cond(condition) {
|
||
if (cond) rwl.lockRead();
|
||
}
|
||
|
||
//! \~english Release read lock on %PIReadWriteLock if "condition" was \c true.
|
||
//! \~russian Освобождает блокировку на чтение %PIReadWriteLock если "condition" был \c true.
|
||
~PIReadLocker() {
|
||
if (cond) rwl.unlockRead();
|
||
}
|
||
|
||
private:
|
||
PIReadWriteLock & rwl;
|
||
bool cond = true;
|
||
};
|
||
|
||
//! \~\ingroup Thread
|
||
//! \~\brief
|
||
//! \~english Scope guard that acquires writer access in constructor and releases it in destructor.
|
||
//! \~russian Защитник области видимости, который захватывает доступ на запись в конструкторе и освобождает его в деструкторе.
|
||
class PIP_EXPORT PIWriteLocker {
|
||
public:
|
||
NO_COPY_CLASS(PIWriteLocker);
|
||
|
||
//! \~english Constructs and lock for write %PIReadWriteLock "l" if "condition" is \c true.
|
||
//! \~russian Создается и блокирует на запись %PIReadWriteLock "l" если "condition" \c true.
|
||
PIWriteLocker(PIReadWriteLock & l, bool condition = true): rwl(l), cond(condition) {
|
||
if (cond) rwl.lockWrite();
|
||
}
|
||
|
||
//! \~english Release write lock on %PIReadWriteLock if "condition" was \c true.
|
||
//! \~russian Освобождает блокировку на запись %PIReadWriteLock если "condition" был \c true.
|
||
~PIWriteLocker() {
|
||
if (cond) rwl.unlockWrite();
|
||
}
|
||
|
||
private:
|
||
PIReadWriteLock & rwl;
|
||
bool cond = true;
|
||
};
|
||
|
||
|
||
#endif // PIREADWRITELOCK_H
|