[+] LSTimer (NT)
[*] Bug fix stupid mismatching variable usage with similar name in LoopQueue.NT.cpp
This commit is contained in:
parent
8cbe481dba
commit
7dca8ecd29
@ -47,13 +47,14 @@ namespace Aurora::Loop
|
||||
struct ITimer : public ILoopSource
|
||||
{
|
||||
virtual void UpdateTime(AuUInt64 absTimeMs) = 0;
|
||||
virtual void UpdateTickRateIfAny(AuUInt32 reschedStepMsOrZero = 0, AuUInt32 maxIterationsOrZero = 0) = 0;
|
||||
virtual void Stop() = 0;
|
||||
};
|
||||
|
||||
AUKN_SYM AuSPtr<IConditionVar> NewLSCondVar(const AuSPtr<Threading::IWaitable> &primitive);
|
||||
AUKN_SYM AuSPtr<IConditionVar> NewLSCondVar(const AuSPtr<ILSMutex> &source);
|
||||
|
||||
AUKN_SYM AuSPtr<ITimer> NewLSTimer(AuUInt64 absTimeMs, AuUInt32 reschedMs = 0);
|
||||
AUKN_SYM AuSPtr<ITimer> NewLSTimer(AuUInt64 absStartTimeMs /*CurrentClockMS()*/, AuUInt32 reschedStepMsOrZero = 0, AuUInt32 maxIterationsOrZero = 0);
|
||||
AUKN_SYM AuSPtr<ILSMutex> NewLSMutex();
|
||||
AUKN_SYM AuSPtr<ILSEvent> NewLSEvent(bool triggerd = false, bool atomicRelease = true, bool permitMultipleTriggers = false);
|
||||
AUKN_SYM AuSPtr<ILSSemaphore> NewLSSemaphore(AuUInt32 initialCount = 0);
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
LSMutex::LSMutex(HANDLE handle) : LSHandle(reinterpret_cast<AuUInt>(handle))
|
||||
LSMutex::LSMutex(HANDLE handle) : LSHandle(AuReinterpretCast<AuUInt>(handle))
|
||||
{}
|
||||
|
||||
LSMutex::~LSMutex()
|
||||
|
@ -10,9 +10,8 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
class LSMutex : public ILSMutex, public LSHandle
|
||||
struct LSMutex : ILSMutex, LSHandle
|
||||
{
|
||||
public:
|
||||
LSMutex(HANDLE handle);
|
||||
~LSMutex();
|
||||
|
||||
|
@ -10,12 +10,12 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
LSSemaphore::LSSemaphore(HANDLE handle) : LSHandle(reinterpret_cast<AuUInt>(handle))
|
||||
LSSemaphore::LSSemaphore(HANDLE handle) : LSHandle(AuReinterpretCast<AuUInt>(handle))
|
||||
{}
|
||||
|
||||
LSSemaphore::~LSSemaphore()
|
||||
{
|
||||
auto handle = reinterpret_cast<HANDLE>(this->handle);
|
||||
auto handle = AuReinterpretCast<HANDLE>(this->handle);
|
||||
AuWin32CloseHandle(handle);
|
||||
this->handle = kInvalidHandle;
|
||||
}
|
||||
@ -23,7 +23,7 @@ namespace Aurora::Loop
|
||||
bool LSSemaphore::AddOne()
|
||||
{
|
||||
LONG atomicOld;
|
||||
return ReleaseSemaphore(reinterpret_cast<HANDLE>(handle), 1, &atomicOld);
|
||||
return ReleaseSemaphore(AuReinterpretCast<HANDLE>(handle), 1, &atomicOld);
|
||||
}
|
||||
|
||||
bool LSSemaphore::IsSignaled()
|
||||
|
@ -10,9 +10,8 @@
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
class LSSemaphore : public ILSSemaphore, public LSHandle
|
||||
struct LSSemaphore : ILSSemaphore, LSHandle
|
||||
{
|
||||
public:
|
||||
LSSemaphore(HANDLE handle);
|
||||
~LSSemaphore();
|
||||
|
||||
|
@ -7,8 +7,143 @@
|
||||
***/
|
||||
#include <Source/RuntimeInternal.hpp>
|
||||
#include "LSTimer.hpp"
|
||||
#include <Source/Time/Time.hpp>
|
||||
|
||||
namespace Aurora::Loop
|
||||
{
|
||||
struct LSTimer : ITimer, LSHandle
|
||||
{
|
||||
LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, HANDLE handle);
|
||||
~LSTimer();
|
||||
|
||||
virtual void UpdateTime(AuUInt64 absTimeMs) override;
|
||||
virtual void UpdateTickRateIfAny(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero) override;
|
||||
virtual void Stop() override;
|
||||
|
||||
virtual bool OnTrigger(AuUInt handle) override;
|
||||
|
||||
virtual bool IsSignaled() override;
|
||||
virtual bool WaitOn(AuUInt32 timeout) override;
|
||||
virtual ELoopSource GetType() override;
|
||||
|
||||
void UpdateTimeInternal(AuUInt64 absTimeMs);
|
||||
|
||||
private:
|
||||
AuUInt32 reschedStepMsOrZero_ {}, maxIterationsOrZero_ {};
|
||||
AuUInt64 targetTime_ {};
|
||||
AuUInt32 count_ {};
|
||||
};
|
||||
|
||||
LSTimer::LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, HANDLE handle) :
|
||||
LSHandle(AuReinterpretCast<AuUInt>(handle)),
|
||||
reschedStepMsOrZero_(reschedStepMsOrZero),
|
||||
maxIterationsOrZero_(maxIterationsOrZero)
|
||||
{
|
||||
this->targetTime_ = AuTime::ConvertTimestamp(AuTime::CurrentClockMS());
|
||||
}
|
||||
|
||||
LSTimer::~LSTimer()
|
||||
{
|
||||
auto handle = AuReinterpretCast<HANDLE>(this->handle);
|
||||
AuWin32CloseHandle(handle);
|
||||
this->handle = kInvalidHandle;
|
||||
}
|
||||
|
||||
void LSTimer::UpdateTime(AuUInt64 absTimeMs)
|
||||
{
|
||||
this->targetTime_ = AuTime::ConvertTimestamp(absTimeMs);
|
||||
UpdateTimeInternal(this->targetTime_);
|
||||
}
|
||||
|
||||
void LSTimer::UpdateTimeInternal(AuUInt64 absTimeMs)
|
||||
{
|
||||
this->targetTime_ = absTimeMs;
|
||||
LARGE_INTEGER i;
|
||||
i.QuadPart = absTimeMs;
|
||||
SysAssert(::SetWaitableTimer(AuReinterpretCast<HANDLE>(this->handle), &i, 0, nullptr, nullptr, false));
|
||||
}
|
||||
|
||||
void LSTimer::UpdateTickRateIfAny(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero)
|
||||
{
|
||||
this->reschedStepMsOrZero_ = reschedStepMsOrZero;
|
||||
this->maxIterationsOrZero_ = maxIterationsOrZero;
|
||||
this->count_ = 0;
|
||||
this->UpdateTime(this->targetTime_);
|
||||
}
|
||||
|
||||
bool LSTimer::OnTrigger(AuUInt handle)
|
||||
{
|
||||
SysAssert(this->targetTime_ <= AuTime::ConvertTimestamp(AuTime::CurrentClockMS()));
|
||||
if (!this->reschedStepMsOrZero_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!this->maxIterationsOrZero_)
|
||||
{
|
||||
this->UpdateTimeInternal(this->targetTime_ + (AuUInt64(this->reschedStepMsOrZero_) * 10'000ULL));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ok = AuAtomicAdd<AuUInt32>(&this->count_, 1) < this->maxIterationsOrZero_;
|
||||
if (ok)
|
||||
{
|
||||
this->UpdateTimeInternal(this->targetTime_ + (AuUInt64(this->reschedStepMsOrZero_) * 10'000ULL));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void LSTimer::Stop()
|
||||
{
|
||||
bool bSuccess = ::CancelWaitableTimer(AuReinterpretCast<HANDLE>(handle));
|
||||
SysAssertDbg(bSuccess);
|
||||
LARGE_INTEGER i;
|
||||
i.QuadPart = AuNumericLimits<AuInt64>::max();
|
||||
SysAssert(::SetWaitableTimer(AuReinterpretCast<HANDLE>(this->handle), &i, 0, nullptr, nullptr, false));
|
||||
}
|
||||
|
||||
bool LSTimer::IsSignaled()
|
||||
{
|
||||
return LSHandle::IsSignaled();
|
||||
}
|
||||
|
||||
bool LSTimer::WaitOn(AuUInt32 timeout)
|
||||
{
|
||||
return LSHandle::WaitOn(timeout);
|
||||
}
|
||||
|
||||
ELoopSource LSTimer::GetType()
|
||||
{
|
||||
return ELoopSource::eSourceTimer;
|
||||
}
|
||||
|
||||
AUKN_SYM AuSPtr<ITimer> NewLSTimer(AuUInt64 absStartTimeMs, AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero)
|
||||
{
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/threadpoolapiset/nf-threadpoolapiset-setthreadpoolwait
|
||||
// TODO: Is that any better with an event?
|
||||
|
||||
auto handle = CreateWaitableTimerW(nullptr, false, nullptr);
|
||||
if (!handle)
|
||||
{
|
||||
SysPushErrorIO();
|
||||
return {};
|
||||
}
|
||||
|
||||
auto object = AuMakeShared<LSTimer>(reschedStepMsOrZero, maxIterationsOrZero, handle);
|
||||
if (!object)
|
||||
{
|
||||
SysPushErrorMem();
|
||||
AuWin32CloseHandle(handle);
|
||||
return {};
|
||||
}
|
||||
|
||||
object->UpdateTime(absStartTimeMs);
|
||||
|
||||
return object;
|
||||
}
|
||||
}
|
@ -661,19 +661,18 @@ namespace Aurora::Loop
|
||||
auto now = AuTime::CurrentInternalClockMS();
|
||||
for (queueIterator.Start(); queueIterator.End() != queueIterator.itr; )
|
||||
{
|
||||
bool shouldRemove {true};
|
||||
auto &source = *queueIterator.itr;
|
||||
|
||||
auto [ticked, bShouldRemove] = source.DoWork(this, source.source->Singular() ? source.source->GetHandle() : source.source->GetHandles()[0]);
|
||||
|
||||
if (!shouldRemove && source.ConsiderTimeout(now))
|
||||
if (!bShouldRemove && source.ConsiderTimeout(now))
|
||||
{
|
||||
shouldRemove = true;
|
||||
bShouldRemove = true;
|
||||
}
|
||||
|
||||
source.source->OnFinishSleep();
|
||||
|
||||
if (shouldRemove)
|
||||
if (bShouldRemove)
|
||||
{
|
||||
if (source.source->GetType() == ELoopSource::eSourceWin32)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user