if (!mCancelTimerThread) {\r
\r
//\r
- // Suspend the main thread until we are done\r
+ // Suspend the main thread until we are done.\r
+ // Enter the critical section before suspending\r
+ // and leave the critical section after resuming\r
+ // to avoid deadlock between main and timer thread.\r
//\r
-\r
+ gWinNt->EnterCriticalSection (&mNtCriticalSection);\r
gWinNt->SuspendThread (mNtMainThreadHandle);\r
\r
//\r
//\r
if (mCancelTimerThread) {\r
gWinNt->ResumeThread (mNtMainThreadHandle);\r
+ gWinNt->LeaveCriticalSection (&mNtCriticalSection);\r
gWinNt->timeKillEvent (wTimerID);\r
mMMTimerThreadID = 0;\r
return ;\r
// Resume the main thread\r
//\r
gWinNt->ResumeThread (mNtMainThreadHandle);\r
+ gWinNt->LeaveCriticalSection (&mNtCriticalSection);\r
\r
//\r
// Wait for interrupts to be enabled.\r
//\r
// Suspend the main thread until we are done\r
//\r
+ gWinNt->EnterCriticalSection (&mNtCriticalSection);\r
gWinNt->SuspendThread (mNtMainThreadHandle);\r
mCpu->GetInterruptState (mCpu, &InterruptState);\r
}\r
// expired since the last call is 10,000 times the number\r
// of ms. (or 100ns units)\r
//\r
- gWinNt->EnterCriticalSection (&mNtCriticalSection);\r
CallbackFunction = mTimerNotifyFunction;\r
- gWinNt->LeaveCriticalSection (&mNtCriticalSection);\r
\r
//\r
// Only invoke the callback function if a Non-NULL handler has been\r
// Resume the main thread\r
//\r
gWinNt->ResumeThread (mNtMainThreadHandle);\r
+ gWinNt->LeaveCriticalSection (&mNtCriticalSection);\r
} else {\r
gWinNt->timeKillEvent (wTimerID);\r
mMMTimerThreadID = 0;\r