summaryrefslogtreecommitdiff
path: root/Nt32Pkg/TimerDxe
diff options
context:
space:
mode:
authorqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>2008-02-22 09:43:59 +0000
committerqwang12 <qwang12@6f19259b-4bc3-4df7-8a09-765794883524>2008-02-22 09:43:59 +0000
commit1710eeb85ea79ae91c9e23abc448bee553226f59 (patch)
tree4ceb1d92a2c6d22b8397a061301f2db0c40ec28b /Nt32Pkg/TimerDxe
parent34d675a0c982341256c426813355776b9f13aa7d (diff)
downloadedk2-platforms-1710eeb85ea79ae91c9e23abc448bee553226f59.tar.xz
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
Diffstat (limited to 'Nt32Pkg/TimerDxe')
-rw-r--r--Nt32Pkg/TimerDxe/Timer.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/Nt32Pkg/TimerDxe/Timer.c b/Nt32Pkg/TimerDxe/Timer.c
index 97ea73345b..d9944414cf 100644
--- a/Nt32Pkg/TimerDxe/Timer.c
+++ b/Nt32Pkg/TimerDxe/Timer.c
@@ -115,9 +115,12 @@ Returns:
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);
//
@@ -127,6 +130,7 @@ Returns:
//
if (mCancelTimerThread) {
gWinNt->ResumeThread (mNtMainThreadHandle);
+ gWinNt->LeaveCriticalSection (&mNtCriticalSection);
gWinNt->timeKillEvent (wTimerID);
mMMTimerThreadID = 0;
return ;
@@ -138,6 +142,7 @@ Returns:
// Resume the main thread
//
gWinNt->ResumeThread (mNtMainThreadHandle);
+ gWinNt->LeaveCriticalSection (&mNtCriticalSection);
//
// Wait for interrupts to be enabled.
@@ -151,6 +156,7 @@ Returns:
//
// Suspend the main thread until we are done
//
+ gWinNt->EnterCriticalSection (&mNtCriticalSection);
gWinNt->SuspendThread (mNtMainThreadHandle);
mCpu->GetInterruptState (mCpu, &InterruptState);
}
@@ -174,9 +180,7 @@ Returns:
// expired since the last call is 10,000 times the number
// of ms. (or 100ns units)
//
- gWinNt->EnterCriticalSection (&mNtCriticalSection);
CallbackFunction = mTimerNotifyFunction;
- gWinNt->LeaveCriticalSection (&mNtCriticalSection);
//
// Only invoke the callback function if a Non-NULL handler has been
@@ -194,6 +198,7 @@ Returns:
// Resume the main thread
//
gWinNt->ResumeThread (mNtMainThreadHandle);
+ gWinNt->LeaveCriticalSection (&mNtCriticalSection);
} else {
gWinNt->timeKillEvent (wTimerID);
mMMTimerThreadID = 0;