// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #if PLATFORM_UNIX #include "UnixCriticalSection.h" #include #include /// /// Unix implementation of a condition variables. Condition variables are synchronization primitives that enable threads to wait until a particular condition occurs. Condition variables enable threads to atomically release a lock and enter the sleeping state. /// class FLAXENGINE_API UnixConditionVariable { private: pthread_cond_t _cond; UnixConditionVariable(const UnixConditionVariable&); UnixConditionVariable& operator=(const UnixConditionVariable&); public: /// /// Initializes a new instance of the class. /// UnixConditionVariable() { pthread_cond_init(&_cond, nullptr); } /// /// Finalizes an instance of the class. /// ~UnixConditionVariable() { pthread_cond_destroy(&_cond); } public: /// /// Blocks the current thread execution until the condition variable is woken up. /// /// The critical section locked by the current thread. void Wait(const UnixCriticalSection& lock) { pthread_cond_wait(&_cond, lock._mutexPtr); } /// /// Blocks the current thread execution until the condition variable is woken up or after the specified timeout duration. /// /// The critical section locked by the current thread. /// The time-out interval, in milliseconds. If the time-out interval elapses, the function re-acquires the critical section and returns zero. If timeout is zero, the function tests the states of the specified objects and returns immediately. If timeout is INFINITE, the function's time-out interval never elapses. /// If the function succeeds, the return value is true, otherwise, if the function fails or the time-out interval elapses, the return value is false. bool Wait(const UnixCriticalSection& lock, const int32 timeout) { struct timeval tv; struct timespec ts; gettimeofday(&tv, NULL); ts.tv_sec = time(NULL) + timeout / 1000; ts.tv_nsec = tv.tv_usec * 1000 + 1000 * 1000 * (timeout % 1000); ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000); ts.tv_nsec %= (1000 * 1000 * 1000); return pthread_cond_timedwait(&_cond, lock._mutexPtr, &ts) == 0; } /// /// Notifies one waiting thread. /// void NotifyOne() { pthread_cond_signal(&_cond); } /// /// Notifies all waiting threads. /// void NotifyAll() { pthread_cond_broadcast(&_cond); } }; #endif