Fix a bug reported by EDK940 "The main thread has not LeaveCriticalSection when be Suspended, and the child thread will try to EnterCriticalSection, there is the confliction".

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4745 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qwang12 2008-02-22 09:43:59 +00:00
parent 34d675a0c9
commit 1710eeb85e
1 changed files with 9 additions and 4 deletions

View File

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