141 lines
3.0 KiB
C++
141 lines
3.0 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 <RuntimeInternal.hpp>
|
|
#include "Event.hpp"
|
|
|
|
namespace Aurora::Threading::Primitives
|
|
{
|
|
EventImpl::EventImpl(bool trigged, bool atomicRelease, bool permitMultipleTriggers) : triggered_(trigged), atomicRelease_(atomicRelease), permitMultipleTriggers_(permitMultipleTriggers) {}
|
|
EventImpl::~EventImpl() {}
|
|
|
|
bool EventImpl::Init()
|
|
{
|
|
mutex_ = ConditionMutexUnique();
|
|
if (!mutex_)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
condition_ = ConditionVariableUnique(mutex_.get());
|
|
if (!condition_)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool EventImpl::Lock(AuUInt64 timeout /*=0*/)
|
|
{
|
|
LockGuardPtr re(mutex_);
|
|
|
|
AuInt64 startTime = Aurora::Time::CurrentClockMS();
|
|
AuInt64 endTime = startTime + timeout;
|
|
|
|
while (!AtomicIsEventSet())
|
|
{
|
|
AuUInt32 timeoutMs = 0;
|
|
|
|
if (timeout)
|
|
{
|
|
timeoutMs = endTime - static_cast<AuInt64>(Aurora::Time::CurrentClockMS());
|
|
if (timeoutMs < 0)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!condition_->WaitForSignal(timeoutMs))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
}
|
|
|
|
if (atomicRelease_)
|
|
{
|
|
triggered_ = false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool EventImpl::TryLock()
|
|
{
|
|
LockGuardPtr re(mutex_);
|
|
|
|
return AtomicIsEventSet();
|
|
}
|
|
|
|
bool EventImpl::AtomicIsEventSet()
|
|
{
|
|
if (!triggered_) return false;
|
|
|
|
if (atomicRelease_) triggered_ = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void EventImpl::Reset()
|
|
{
|
|
mutex_->Lock();
|
|
triggered_ = false;
|
|
mutex_->Unlock();
|
|
}
|
|
|
|
void EventImpl::Set()
|
|
{
|
|
LockGuardPtr re(mutex_);
|
|
SysAssertExp((permitMultipleTriggers_) || (!triggered_), "Can not trigger an awake event object");
|
|
triggered_ = true;
|
|
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 trigged, bool atomicRelease, bool permitMultipleTriggers)
|
|
{
|
|
auto event = _new EventImpl(trigged, atomicRelease, permitMultipleTriggers);
|
|
if (!event)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
if (!event->Init())
|
|
{
|
|
EventRelease(event);
|
|
return nullptr;
|
|
}
|
|
|
|
return event;
|
|
}
|
|
|
|
AUKN_SYM void EventRelease(IEvent *event)
|
|
{
|
|
SafeDelete<EventImpl *>(event);
|
|
}
|
|
} |