Skip to content

Instantly share code, notes, and snippets.

@rbmm
Created May 20, 2023 16:42
Show Gist options
  • Save rbmm/0751b4e089c3f67f4e66db97244070a3 to your computer and use it in GitHub Desktop.
Save rbmm/0751b4e089c3f67f4e66db97244070a3 to your computer and use it in GitHub Desktop.
struct DTimer
{
HANDLE _M_hTimer = 0;
LONG _M_dwRefCount = 1;
ULONG _M_n = 0;
ULONG _M_dwThreadId = GetCurrentThreadId();
LONG _M_stopping = FALSE;
void AddRef()
{
InterlockedIncrementNoFence(&_M_dwRefCount);
}
void Release()
{
if (!InterlockedDecrement(&_M_dwRefCount))
{
delete this;
}
}
void OnTimer()
{
printf("%x: %s<%p>(%x)\n", GetCurrentThreadId(), __FUNCTION__, this, _M_n);
if (!--_M_n)
{
Stop();
}
}
static VOID NTAPI WaitOrTimerCallback(PVOID This, BOOLEAN )
{
reinterpret_cast<DTimer*>(This)->OnTimer();
}
static void NTAPI timer_canceled_callback(PVOID This)
{
printf("%x: %s<%p>\n", GetCurrentThreadId(), __FUNCTION__, This);
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// Simulate a long cleanup here
Sleep(5000);
reinterpret_cast<DTimer*>(This)->Release();
}
DTimer(ULONG n) : _M_n(n)
{
printf("%x: %s<%p>\n", GetCurrentThreadId(), __FUNCTION__, this);
}
~DTimer()
{
printf("%x: %s<%p>\n", GetCurrentThreadId(), __FUNCTION__, this);
if (_M_hTimer)
{
timer_release(_M_hTimer);
}
PostThreadMessageW(_M_dwThreadId, WM_QUIT, 0, 0);
}
BOOL Start(_In_ DWORD DueTime, _In_ DWORD Period)
{
AddRef();
if (timer_create(&_M_hTimer, WaitOrTimerCallback, this, DueTime, Period))
{
return TRUE;
}
Release();
return FALSE;
}
void Stop()
{
if (!InterlockedExchangeNoFence(&_M_stopping, TRUE))
{
timer_cancel(_M_hTimer, timer_canceled_callback, this);
}
}
};
void t_test(ULONG n)
{
if (DTimer* timer = new DTimer(n))
{
if (timer->Start(0, 1000))
{
timer->Stop();
}
timer->Release();
}
MessageBox(0, 0, L"demo delay", MB_ICONWARNING);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment