-/*++\r
+/**@file\r
\r
Copyright (c) 2006, Intel Corporation \r
All rights reserved. This program and the accompanying materials \r
timer service. In the future, the Thread creation should possibly be \r
abstracted by the CPU architectural protocol\r
\r
---*/\r
+**/\r
\r
#include "Timer.h"\r
\r
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
mCpu->GetInterruptState (mCpu, &InterruptState);\r
while (!InterruptState) {\r
- gWinNt->Sleep (0);\r
+ gWinNt->Sleep (1);\r
mCpu->GetInterruptState (mCpu, &InterruptState);\r
}\r
\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
EFI_STATUS Status;\r
UINTN Result;\r
EFI_HANDLE Handle;\r
-\r
+ EFI_HANDLE hSourceProcessHandle;\r
+ EFI_HANDLE hSourceHandle;\r
+ EFI_HANDLE hTargetProcessHandle;\r
//\r
// Make sure the Timer Architectural Protocol is not already installed in the system\r
//\r
//\r
// Get the CPU Architectural Protocol instance\r
//\r
- Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, &mCpu);\r
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID**)&mCpu);\r
ASSERT_EFI_ERROR (Status);\r
\r
//\r
// Get our handle so the timer tick thread can suspend\r
//\r
+ hSourceProcessHandle = gWinNt->GetCurrentProcess ();\r
+ hSourceHandle = gWinNt->GetCurrentThread ();\r
+ hTargetProcessHandle = gWinNt->GetCurrentProcess ();\r
Result = gWinNt->DuplicateHandle (\r
- gWinNt->GetCurrentProcess (),\r
- gWinNt->GetCurrentThread (),\r
- gWinNt->GetCurrentProcess (),\r
+ hSourceProcessHandle,\r
+ hSourceHandle,\r
+ hTargetProcessHandle,\r
&mNtMainThreadHandle,\r
0,\r
FALSE,\r