/*! \file pisemaphore.h * \ingroup Thread * \~\brief * \~english Counting semaphore for shared resources * \~russian Счетный семафор для общих ресурсов */ /* PIP - Platform Independent Primitives PISemaphore, PISemaphoreLocker 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 PISEMAPHORE_H #define PISEMAPHORE_H #include "piconditionvar.h" //! \~\ingroup Thread //! \~\brief //! \~english Counting semaphore that tracks available resource units. //! \~russian Счетный семафор, отслеживающий количество доступных единиц ресурса. class PIP_EXPORT PISemaphore { public: NO_COPY_CLASS(PISemaphore) //! \~english Constructs semaphore with \"initial\" available resources. //! \~russian Создает семафор с \"initial\" начальными свободными ресурсами. PISemaphore(int initial = 0); //! \~english Destroy semaphore. //! \~russian Деструктор семафора. ~PISemaphore(); //! \~english Acquires \a cnt resource units, waiting until enough units become available. //! \~russian Захватывает \a cnt единиц ресурса, ожидая появления достаточного количества. void acquire(int cnt = 1); //! \~english Tries to acquire \a cnt resource units without waiting. //! \~russian Пытается захватить \a cnt единиц ресурса без ожидания. bool tryAcquire(int cnt = 1); //! \~english Tries to acquire \a cnt resource units within \a timeout. //! \~russian Пытается захватить \a cnt единиц ресурса в пределах \a timeout. bool tryAcquire(int cnt, PISystemTime timeout); //! \~english Releases \a cnt resource units and wakes waiting threads. //! \~russian Освобождает \a cnt единиц ресурса и пробуждает ожидающие потоки. void release(int cnt = 1); //! \~english Returns the current number of available resource units. //! \~russian Возвращает текущее количество доступных единиц ресурса. int available() const; private: int count = 0; mutable PIMutex mutex; PIConditionVariable var; }; //! \~\ingroup Thread //! \~\brief //! \~english Scope guard that acquires semaphore units in constructor and releases them in destructor. //! \~russian Защитник области видимости, который захватывает единицы семафора в конструкторе и освобождает их в деструкторе. class PIP_EXPORT PISemaphoreLocker { public: NO_COPY_CLASS(PISemaphoreLocker); //! \~english Constructs and acquire \"cnt\" resources on semaphore "s" if "condition" is \c true. //! \~russian Создается и захватывает \"cnt\" ресурсов у семафора "s" если "condition" \c true. PISemaphoreLocker(PISemaphore & s, int cnt = 1, bool condition = true): sem(s), count(cnt), cond(condition) { if (cond) sem.acquire(count); } //! \~english Release "cnt" resources on semaphore if "condition" was \c true. //! \~russian Освобождает "cnt" ресурсов у семафора если "condition" был \c true. ~PISemaphoreLocker() { if (cond) sem.release(count); } private: PISemaphore & sem; int count = 1; bool cond = true; }; #endif // PISEMAPHORE_H