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

140 lines
5.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*! \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