/*! \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 . */ #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