/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: ConditionVariable.Unix.cpp Date: 2021-6-12 Author: Reece ***/ #include #include "ConditionVariable.Generic.hpp" #if !defined(_AURUNTIME_GENERICCV) namespace Aurora::Threading::Primitives { ConditionVariableImpl::ConditionVariableImpl(IConditionMutex *mutex) : mutex_(dynamic_cast(mutex)) { auto ret = pthread_cond_init(&pthreadCv_, NULL); SysAssert(ret == 0, "Couldn't initialize CV"); } ConditionVariableImpl::~ConditionVariableImpl() { pthread_cond_destroy(&pthreadCv_); } IConditionMutex *ConditionVariableImpl::GetMutex() { return mutex_; } bool ConditionVariableImpl::WaitForSignal(AuUInt32 timeout) { auto mutex = reinterpret_cast(mutex_->GetOSHandle()); if (timeout == 0) { auto ret = pthread_cond_wait(&pthreadCv_, mutex); SysAssert(ret == 0, "Couldn't wait on CV"); return true; } else { struct timespec tspec; ms2ts(&tspec, timeout); auto ret = pthread_cond_timedwait(&pthreadCv_, mutex, &tspec); if (ret != 0) { SysAssert(errno == ETIMEDOUT, "conditional timed wait failed"); return false; } return true; } } void ConditionVariableImpl::Signal() { auto ret = pthread_cond_signal(&pthreadCv_); SysAssert(ret == 0, "Couldn't wake any CV waiters"); } void ConditionVariableImpl::Broadcast() { auto ret = pthread_cond_broadcast(&pthreadCv_); SysAssert(ret == 0, "Couldn't wake any CV waiters"); } AUKN_SYM IConditionVariable *ConditionVariableNew(IConditionMutex *mutex) { return _new ConditionVariableImpl(mutex); } AUKN_SYM void ConditionVariableRelease(IConditionVariable *mutex) { SafeDelete(mutex); } } #endif