Skip to content

Commit

Permalink
Windows: fixing occasional crashes on Simulator relaunch (#414)
Browse files Browse the repository at this point in the history
  • Loading branch information
ggcrunchy authored Jun 23, 2022
1 parent 4543a8c commit 3e3e353
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
24 changes: 20 additions & 4 deletions platform/windows/Corona.Native.Library.Win32/Rtt/Rtt_WinTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
namespace Rtt
{

std::unordered_map<UINT_PTR, Rtt::WinTimer *> WinTimer::sTimerMap;
UINT_PTR WinTimer::sMostRecentTimerID;

#pragma region Constructors/Destructors
WinTimer::WinTimer(MCallback& callback, HWND windowHandle)
: PlatformTimer(callback)
Expand Down Expand Up @@ -46,7 +49,13 @@ void WinTimer::Start()
// We do this because Windows timers can invoke later than expected.
// To compensate, we'll schedule when to invoke the timer's callback using "fIntervalEndTimeInTicks".
fNextIntervalTimeInTicks = (S32)::GetTickCount() + (S32)fIntervalInMilliseconds;
fTimerPointer = ::SetTimer(fWindowHandle, (UINT_PTR)this, 10, WinTimer::OnTimerElapsed);
fTimerID = ++sMostRecentTimerID; // ID should be non-0, so pre-increment for first time
fTimerPointer = ::SetTimer(fWindowHandle, fTimerID, 10, WinTimer::OnTimerElapsed);

if (IsRunning())
{
sTimerMap[fTimerID] = this;
}
}

void WinTimer::Stop()
Expand All @@ -58,8 +67,12 @@ void WinTimer::Stop()
}

// Stop the timer.
::KillTimer(fWindowHandle, fTimerPointer);
::KillTimer(fWindowHandle, fTimerID);

sTimerMap.erase(fTimerID);

fTimerPointer = NULL;
fTimerID = 0;
}

void WinTimer::SetInterval(U32 milliseconds)
Expand Down Expand Up @@ -99,8 +112,11 @@ void WinTimer::Evaluate()
#pragma region Private Methods/Functions
VOID CALLBACK WinTimer::OnTimerElapsed(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
WinTimer *timer = (WinTimer*)idEvent;
timer->Evaluate();
auto timer = sTimerMap.find(idEvent);
if (sTimerMap.end() != timer)
{
timer->second->Evaluate();
}
}

S32 WinTimer::CompareTicks(S32 x, S32 y)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "Core\Rtt_Build.h"
#include "Rtt_PlatformTimer.h"
#include <Windows.h>
#include <unordered_map>


namespace Rtt
Expand Down Expand Up @@ -79,8 +80,12 @@ class WinTimer : public PlatformTimer

HWND fWindowHandle;
UINT_PTR fTimerPointer;
UINT_PTR fTimerID;
U32 fIntervalInMilliseconds;
S32 fNextIntervalTimeInTicks;

static std::unordered_map<UINT_PTR, WinTimer*> sTimerMap; // timer callback might be called after Stop(), so use this as a guard
static UINT_PTR sMostRecentTimerID; // use an incrementing index as key, to be robust against the rare case that a new timer is reallocated into the same memory
};

} // namespace Rtt

0 comments on commit 3e3e353

Please sign in to comment.