135 lines
2.9 KiB
C++
135 lines
2.9 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: Event.cpp
|
|
Date: 2021-6-12
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "AuEvent.hpp"
|
|
|
|
namespace Aurora::Threading::Primitives
|
|
{
|
|
EventImpl::EventImpl(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers) :
|
|
triggered_(bTriggered),
|
|
atomicRelease_(bAtomicRelease),
|
|
permitMultipleTriggers_(bPermitMultipleTriggers),
|
|
condition_(AuUnsafeRaiiToShared(&this->mutex_))
|
|
{}
|
|
|
|
EventImpl::~EventImpl() {}
|
|
|
|
bool EventImpl::Init()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool EventImpl::Lock(AuUInt64 timeout /*=0*/)
|
|
{
|
|
AU_LOCK_GUARD(this->mutex_);
|
|
|
|
AuInt64 uStartTime = Time::SteadyClockMS();
|
|
AuInt64 uEndTime = uStartTime + timeout;
|
|
|
|
while (!AtomicIsEventSet())
|
|
{
|
|
AuUInt32 timeoutMs = 0;
|
|
|
|
if (timeout)
|
|
{
|
|
timeoutMs = uEndTime - Time::SteadyClockMS();
|
|
if (timeoutMs < 0)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!this->condition_.WaitForSignal(timeoutMs))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (this->atomicRelease_)
|
|
{
|
|
this->triggered_ = false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool EventImpl::TryLock()
|
|
{
|
|
AU_LOCK_GUARD(mutex_);
|
|
|
|
return AtomicIsEventSet();
|
|
}
|
|
|
|
bool EventImpl::AtomicIsEventSet()
|
|
{
|
|
if (!this->triggered_) return false;
|
|
|
|
if (this->atomicRelease_) this->triggered_ = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void EventImpl::Reset()
|
|
{
|
|
this->mutex_.Lock();
|
|
this->triggered_ = false;
|
|
this->mutex_.Unlock();
|
|
}
|
|
|
|
void EventImpl::Set()
|
|
{
|
|
AU_LOCK_GUARD(this->mutex_);
|
|
SysAssertExp((this->permitMultipleTriggers_) || (!this->triggered_), "Can not trigger an awake event object");
|
|
this->triggered_ = true;
|
|
this->condition_.Broadcast();
|
|
}
|
|
|
|
bool EventImpl::HasOSHandle(AuMach &mach)
|
|
{
|
|
mach = 0;
|
|
return false;
|
|
}
|
|
|
|
bool EventImpl::HasLockImplementation()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void EventImpl::Lock()
|
|
{
|
|
auto ok = Lock(0);
|
|
SysAssert(ok);
|
|
}
|
|
|
|
void EventImpl::Unlock()
|
|
{
|
|
// Unlike the other types, unlock is ways a nop
|
|
}
|
|
|
|
AUKN_SYM IEvent *EventNew(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers)
|
|
{
|
|
auto event = _new EventImpl(bTriggered, bAtomicRelease, bPermitMultipleTriggers);
|
|
if (!event)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
if (!event->Init())
|
|
{
|
|
EventRelease(event);
|
|
return nullptr;
|
|
}
|
|
|
|
return event;
|
|
}
|
|
|
|
AUKN_SYM void EventRelease(IEvent *pEvent)
|
|
{
|
|
AuSafeDelete<EventImpl *>(pEvent);
|
|
}
|
|
} |