Files
pip/libs/main/thread/pireadwritelock.h
T
2026-03-12 14:46:57 +03:00

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