Plasma Engine  2.0
Loading...
Searching...
No Matches
ConditionVariable_Posix.h
1#include <Foundation/FoundationInternal.h>
2PL_FOUNDATION_INTERNAL_HEADER
3
4#include <Foundation/Threading/ConditionVariable.h>
5#include <Foundation/Time/Time.h>
6
7#include <errno.h>
8#include <pthread.h>
9#include <sys/time.h>
10
11plConditionVariable::plConditionVariable()
12{
13 pthread_cond_init(&m_Data.m_ConditionVariable, nullptr);
14}
15
16plConditionVariable::~plConditionVariable()
17{
18 PL_ASSERT_DEV(m_iLockCount == 0, "Thread-signal must be unlocked during destruction.");
19
20 pthread_cond_destroy(&m_Data.m_ConditionVariable);
21}
22
24{
25 pthread_cond_signal(&m_Data.m_ConditionVariable);
26}
27
29{
30 pthread_cond_broadcast(&m_Data.m_ConditionVariable);
31}
32
34{
35 PL_ASSERT_DEV(m_iLockCount > 0, "plConditionVariable must be locked when calling UnlockWaitForSignalAndLock.");
36
37 pthread_cond_wait(&m_Data.m_ConditionVariable, &m_Mutex.GetMutexHandle());
38}
39
40plConditionVariable::WaitResult plConditionVariable::UnlockWaitForSignalAndLock(plTime timeout) const
41{
42 PL_ASSERT_DEV(m_iLockCount > 0, "plConditionVariable must be locked when calling UnlockWaitForSignalAndLock.");
43
44 // inside the lock
45 --m_iLockCount;
46
47 timeval now;
48 gettimeofday(&now, nullptr);
49
50 // pthread_cond_timedwait needs an absolute time value, so compute it from the current time.
51 struct timespec timeToWait;
52
53 const plInt64 iNanoSecondsPerSecond = 1000000000LL;
54 const plInt64 iMicroSecondsPerNanoSecond = 1000LL;
55
56 plInt64 endTime = now.tv_sec * iNanoSecondsPerSecond + now.tv_usec * iMicroSecondsPerNanoSecond + static_cast<plInt64>(timeout.GetNanoseconds());
57
58 timeToWait.tv_sec = endTime / iNanoSecondsPerSecond;
59 timeToWait.tv_nsec = endTime % iNanoSecondsPerSecond;
60
61 if (pthread_cond_timedwait(&m_Data.m_ConditionVariable, &m_Mutex.GetMutexHandle(), &timeToWait) == ETIMEDOUT)
62 {
63 // inside the lock
64 ++m_iLockCount;
65 return WaitResult::Timeout;
66 }
67
68 // inside the lock
69 ++m_iLockCount;
70 return WaitResult::Signaled;
71}
void SignalAll()
Wakes up all the threads that are currently waiting for the variable.
Definition ConditionVariable_Posix.h:28
void UnlockWaitForSignalAndLock() const
Puts the calling thread to sleep and waits for the variable to get signaled.
Definition ConditionVariable_Posix.h:33
void SignalOne()
Wakes up one of the threads that are currently waiting for the variable.
Definition ConditionVariable_Posix.h:23
The time class encapsulates a double value storing the time in seconds.
Definition Time.h:12
constexpr double GetNanoseconds() const
Returns the nanoseconds value.
Definition Time_inl.h:15