J Reece Wilson
6de5cbfb95
[*] NT: Added TTY handle static getter optimization alongside a secret setter API [*] Made ILoopSource virtual [+] Linux: Added console TTY stubs [*] Renamed ConsoleTTY.Linux.cpp -> ConsoleTTY.Unix.cpp [-] Redundant commented out shm_unlink (zero ref condition should unlink, i believe.) [+] Added IProcess async pipe transaction getter stubs [+] Added additional userland env lookup variables: XDG_SESSION_DESKTOP, DESKTOP_SESSION [+] Unix: AuTime::ns2ts
143 lines
4.2 KiB
C++
143 lines
4.2 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: LSTimer.NT.cpp
|
|
Date: 2021-10-1
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "LSTimer.hpp"
|
|
#include <Source/Time/Time.hpp>
|
|
|
|
namespace Aurora::Loop
|
|
{
|
|
LSTimer::LSTimer(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero, bool bSingleshot, HANDLE handle) :
|
|
LSHandle(AuReinterpretCast<AuUInt>(handle)),
|
|
reschedStepNsOrZero_(AuMSToNS<AuUInt64>(reschedStepMsOrZero)),
|
|
bSingleshot(bSingleshot),
|
|
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::UpdateTimeNs(AuUInt64 absTimeNs)
|
|
{
|
|
this->targetTime_ = AuTime::ConvertTimestampNs(absTimeNs);
|
|
UpdateTimeInternal(this->targetTime_);
|
|
}
|
|
|
|
void LSTimer::UpdateTimeInternal(AuUInt64 absTimeNs)
|
|
{
|
|
LARGE_INTEGER i;
|
|
this->targetTime_ = absTimeNs;
|
|
i.QuadPart = absTimeNs;
|
|
SysAssert(::SetWaitableTimer(AuReinterpretCast<HANDLE>(this->handle), &i, 0, nullptr, nullptr, false));
|
|
}
|
|
|
|
void LSTimer::UpdateTickRateIfAny(AuUInt32 reschedStepMsOrZero, AuUInt32 maxIterationsOrZero)
|
|
{
|
|
this->reschedStepNsOrZero_ = AuMSToNS<AuUInt64>(reschedStepMsOrZero);
|
|
this->maxIterationsOrZero_ = maxIterationsOrZero;
|
|
this->count_ = 0;
|
|
}
|
|
|
|
void LSTimer::UpdateTickRateIfAnyNs(AuUInt64 reschedStepNsOrZero, AuUInt32 maxIterationsOrZero)
|
|
{
|
|
this->reschedStepNsOrZero_ = reschedStepNsOrZero;
|
|
this->maxIterationsOrZero_ = maxIterationsOrZero;
|
|
this->count_ = 0;
|
|
}
|
|
|
|
bool LSTimer::OnTrigger(AuUInt handle)
|
|
{
|
|
SysAssert(this->targetTime_ <= AuTime::ConvertTimestampNs(AuTime::CurrentClockNS()));
|
|
|
|
if (!this->reschedStepNsOrZero_)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (!this->maxIterationsOrZero_)
|
|
{
|
|
this->UpdateTimeInternal(this->targetTime_ + (AuUInt64(this->reschedStepNsOrZero_) / 100ULL));
|
|
return true;
|
|
}
|
|
|
|
bool ok = AuAtomicAdd<AuUInt32>(&this->count_, 1) <= this->maxIterationsOrZero_;
|
|
if (ok)
|
|
{
|
|
this->UpdateTimeInternal(this->targetTime_ + (AuUInt64(this->reschedStepNsOrZero_) / 100ULL));
|
|
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, bool bSingleshot)
|
|
{
|
|
// 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, !bSingleshot, nullptr);
|
|
if (!handle)
|
|
{
|
|
SysPushErrorIO();
|
|
return {};
|
|
}
|
|
|
|
auto object = AuMakeShared<LSTimer>(reschedStepMsOrZero, maxIterationsOrZero, bSingleshot, handle);
|
|
if (!object)
|
|
{
|
|
SysPushErrorMem();
|
|
AuWin32CloseHandle(handle);
|
|
return {};
|
|
}
|
|
|
|
if (absStartTimeMs)
|
|
{
|
|
object->UpdateTime(absStartTimeMs);
|
|
}
|
|
|
|
return object;
|
|
}
|
|
} |