152 lines
3.3 KiB
C++
152 lines
3.3 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"
|
|
#include "SMTYield.hpp"
|
|
|
|
namespace Aurora::Threading::Primitives
|
|
{
|
|
EventImpl::EventImpl(bool bTriggered, bool bAtomicRelease, bool bPermitMultipleTriggers) :
|
|
bTriggered_(bTriggered),
|
|
bAtomicRelease_(bAtomicRelease),
|
|
bPermitMultipleTriggers_(bPermitMultipleTriggers)
|
|
{}
|
|
|
|
EventImpl::~EventImpl() {}
|
|
|
|
bool EventImpl::Init()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool EventImpl::LockMS(AuUInt64 uTimeout /*=0*/)
|
|
{
|
|
return LockNS(AuMSToNS<AuUInt64>(uTimeout));
|
|
}
|
|
|
|
bool EventImpl::LockNS(AuUInt64 uTimeout /*=0*/)
|
|
{
|
|
AuInt64 uStartTime {};
|
|
AuInt64 uEndTime {};
|
|
|
|
if (uTimeout)
|
|
{
|
|
uStartTime = Time::SteadyClockNS();
|
|
uEndTime = uStartTime + uTimeout;
|
|
}
|
|
|
|
AU_LOCK_GUARD(this->mutex_);
|
|
|
|
while (!AtomicIsEventSetLogic())
|
|
{
|
|
AuUInt32 uTimeoutNS {};
|
|
|
|
if (uTimeout)
|
|
{
|
|
uStartTime = Time::SteadyClockNS();
|
|
if (uStartTime >= uEndTime)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
uTimeoutNS = uEndTime - uStartTime;
|
|
}
|
|
|
|
if (!this->condition_.WaitForSignalNsEx(&this->mutex_, uTimeoutNS))
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool EventImpl::TryLock()
|
|
{
|
|
AU_LOCK_GUARD(this->mutex_);
|
|
|
|
return AtomicIsEventSetLogic();
|
|
}
|
|
|
|
bool EventImpl::AtomicIsEventSetLogic()
|
|
{
|
|
if (!this->bTriggered_)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (this->bAtomicRelease_)
|
|
{
|
|
this->bTriggered_ = false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void EventImpl::Reset()
|
|
{
|
|
AU_LOCK_GUARD(this->mutex_);
|
|
this->bTriggered_ = false;
|
|
}
|
|
|
|
void EventImpl::Set()
|
|
{
|
|
{
|
|
AU_LOCK_GUARD(this->mutex_);
|
|
SysAssertExp((this->bPermitMultipleTriggers_) || (!this->bTriggered_), "Can not trigger an awake event object");
|
|
this->bTriggered_ = true;
|
|
}
|
|
this->condition_.Broadcast();
|
|
}
|
|
|
|
bool EventImpl::HasOSHandle(AuMach &mach)
|
|
{
|
|
mach = 0;
|
|
return false;
|
|
}
|
|
|
|
bool EventImpl::HasLockImplementation()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void EventImpl::Lock()
|
|
{
|
|
auto ok = LockNS(0);
|
|
SysAssert(ok);
|
|
}
|
|
|
|
void EventImpl::Unlock()
|
|
{
|
|
// Unlock is always a NOP; inverse of a lock/wait is nothing
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
AUROXTL_INTERFACE_SOO_SRC_EX(AURORA_SYMBOL_EXPORT, Event, EventImpl, (bool, bTriggered), (bool, bAtomicRelease), (bool, bPermitMultipleTriggers))
|
|
} |