//! \~\file piconditionvar.h //! \~\ingroup Thread //! \~\brief //! \~english Condition variable for waiting and notification between threads //! \~russian Переменная условия для ожидания и уведомления между потоками /* PIP - Platform Independent Primitives Condition variable for waiting and notification between threads Stephan Fomenko 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 PICONDITIONVAR_H #define PICONDITIONVAR_H #include "pimutex.h" #include "pisystemtime.h" //! \~\ingroup Thread //! \~\brief //! \~english Condition variable used together with external %PIMutex. //! \~russian Переменная условия, используемая вместе с внешним %PIMutex. class PIP_EXPORT PIConditionVariable { public: NO_COPY_CLASS(PIConditionVariable); //! \~english Constructs condition variable. //! \~russian Создает переменную условия. explicit PIConditionVariable(); //! \~english Destroys condition variable. //! \~russian Уничтожает переменную условия. virtual ~PIConditionVariable(); //! \~english Wakes one waiting thread, if any. //! \~russian Пробуждает один ожидающий поток, если он есть. void notifyOne(); //! \~english Wakes all threads currently waiting on this variable. //! \~russian Пробуждает все потоки, ожидающие на этой переменной. void notifyAll(); //! \~english Waits until notification, temporarily releasing \a lk while blocked. //! \~russian Ожидает уведомления, временно освобождая \a lk на время блокировки. virtual void wait(PIMutex & lk); //! \~\brief //! \~english Waits until \a condition becomes true, rechecking it after each wakeup while \a lk is locked. //! \~russian Ожидает, пока \a condition не станет истинным, повторно проверяя его после каждого пробуждения при заблокированном \a lk. //! \~\details //! \~english //! The execution of the current thread (which shall have locked with lk method PIMutex::lock()) is blocked //! until notified. //! //! At the moment of blocking the thread, the function automatically calls lk.unlock() (PIMutex::unlock()), //! allowing other locked threads to continue. //! //! Once notified (explicitly, by some other thread), the function unblocks and calls lk.lock() (PIMutex::lock()), //! leaving lk in the same state as when the function was called. Then the function returns (notice that this last mutex //! locking may block again the thread before returning). //! //! Generally, the function is notified to wake up by a call in another thread either to member notifyOne() or to //! member notifyAll(). But certain implementations may produce spurious wake-up calls without any of these functions //! being called. Therefore, users of this function shall ensure their condition for resumption is met. //! //! If condition is specified, the function only blocks if condition returns false, and notifications can only unblock //! the thread when it becomes true (which is specially useful to check against spurious wake-up calls). //! //! \param lk lock object used by method wait for data protection //! \param condition A callable object or function that takes no arguments and returns a value that can be evaluated //! as a bool. This is called repeatedly until it evaluates to true. //! //! \~russian //! Выполнение текущего потока (который должен быть заблокирован с помощью \a lk методом PIMutex::lock()) //! приостанавливается до получения уведомления. //! //! В момент блокировки потока функция автоматически вызывает lk.unlock() (PIMutex::unlock()), //! позволяя другим заблокированным потокам продолжить выполнение. //! //! После получения уведомления (явного, от другого потока) функция разблокируется и вызывает //! lk.lock() (PIMutex::lock()), возвращая lk в то же состояние, в котором он находился при вызове //! функции. Затем функция завершается (обратите внимание, что эта последняя блокировка мьютекса //! может снова заблокировать поток перед возвратом). //! //! Обычно функция пробуждается при вызове в другом потоке либо notifyOne(), либо notifyAll(). //! Однако некоторые реализации могут создавать ложные пробуждения без вызова любой из этих функций. //! Поэтому пользователи этой функции должны убедиться, что условие для возобновления выполнено. //! //! Если указано condition, функция блокируется только если condition возвращает false, //! а уведомления могут разблокировать поток только когда оно станет true (что особенно полезно //! для проверки ложных пробуждений). //! //! \param lk объект блокировки, используемый методом wait для защиты данных //! \param condition вызываемый объект или функция, не принимающая аргументов и возвращающая значение, которое может быть оценено как //! bool. Вызывается повторно, пока не примет значение true //! virtual void wait(PIMutex & lk, const std::function & condition); //! \~english Waits for at most \a timeout and returns \c true if awakened before it expires. //! \~russian Ожидает не дольше \a timeout и возвращает \c true, если пробуждение произошло до его истечения. virtual bool waitFor(PIMutex & lk, PISystemTime timeout); //! \brief //! \~english Waits until \a condition becomes true or \a timeout expires. //! \~russian Ожидает, пока \a condition не станет истинным или не истечет \a timeout. //! \~\details //! \~english //! The execution of the current thread (which shall have locked with lk method PIMutex::lock()) is blocked //! during timeout, or until notified (if the latter happens first). //! //! At the moment of blocking the thread, the function automatically calls lk.lock() (PIMutex::lock()), allowing //! other locked threads to continue. //! //! Once notified or once timeout has passed, the function unblocks and calls lk.unlock() (PIMutex::unlock()), //! leaving lk in the same state as when the function was called. Then the function returns (notice that this last //! mutex locking may block again the thread before returning). //! //! Generally, the function is notified to wake up by a call in another thread either to member notifyOne() or to //! member notifyAll(). But certain implementations may produce spurious wake-up calls without any of these functions //! being called. Therefore, users of this function shall ensure their condition for resumption is met. //! //! If condition is specified, the function only blocks if condition returns false, and notifications can only unblock //! the thread when it becomes true (which is especially useful to check against spurious wake-up calls). //! //! \param lk lock object used by method wait for data protection //! \param condition A callable object or function that takes no arguments and returns a value that can be evaluated //! as a bool. This is called repeatedly until it evaluates to true. //! \return false if timeout reached or true if wakeup condition is true //! //! \~russian //! Выполнение текущего потока (который должен быть заблокирован с помощью lk методом PIMutex::lock()) //! приостанавливается на время timeout, или до получения уведомления (в зависимости от того, //! что произойдет раньше). //! //! В момент блокировки потока функция автоматически вызывает lk.unlock() (PIMutex::unlock()), //! позволяя другим заблокированным потокам продолжить выполнение. //! //! После получения уведомления или истечения таймаута функция разблокируется и вызывает //! lk.lock() (PIMutex::lock()), возвращая lk в то же состояние, в котором он находился при вызове //! функции. Затем функция завершается (обратите внимание, что эта последняя блокировка мьютекса //! может снова заблокировать поток перед возвратом). //! //! Обычно функция пробуждается при вызове в другом потоке либо notifyOne(), либо notifyAll(). //! Однако некоторые реализации могут создавать ложные пробуждения без вызова любой из этих функций. //! Поэтому пользователи этой функции должны убедиться, что условие для возобновления выполнено. //! //! Если указано condition, функция блокируется только если condition возвращает false, //! а уведомления могут разблокировать поток только когда оно станет true (что особенно полезно //! для проверки ложных пробуждений). //! //! \param lk объект блокировки, используемый методом wait для защиты данных //! \param timeout время ожидания //! \param condition вызываемый объект или функция, не принимающая аргументов и возвращающая значение, которое может быть оценено как //! bool. Вызывается повторно, пока не примет значение true //! \return false если достигнут таймаут, или true если условие пробуждения истинно //! virtual bool waitFor(PIMutex & lk, PISystemTime timeout, const std::function & condition); private: PRIVATE_DECLARATION(PIP_EXPORT) }; #endif // PICONDITIONVAR_H