don't increment the lock count twice in RtlTryEnterCriticalSection() and added some more comments

svn path=/trunk/; revision=13642
This commit is contained in:
Thomas Bluemel 2005-02-19 13:44:56 +00:00
parent c6a8c7496f
commit f66a4cec4d

View file

@ -305,27 +305,33 @@ STDCALL
RtlLeaveCriticalSection( RtlLeaveCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection) PRTL_CRITICAL_SECTION CriticalSection)
{ {
#ifndef NDEBUG
HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread; HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread;
/* In win this case isn't checked. However it's a valid check so it should only
be performed in debug builds! */
if (Thread != CriticalSection->OwningThread) if (Thread != CriticalSection->OwningThread)
{ {
DPRINT1("Releasing critical section not owned!\n"); DPRINT1("Releasing critical section not owned!\n");
/* FIXME: raise exception */
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
#endif
/* Decrease the Recursion Count */ /* Decrease the Recursion Count. No need to do this atomically because only
the thread who holds the lock can call this function (unless the program
is totally screwed... */
if (--CriticalSection->RecursionCount) { if (--CriticalSection->RecursionCount) {
/* Someone still owns us, but we are free */ /* Someone still owns us, but we are free. This needs to be done atomically. */
InterlockedDecrement(&CriticalSection->LockCount); InterlockedDecrement(&CriticalSection->LockCount);
} else { } else {
/* Nobody owns us anymore */ /* Nobody owns us anymore. No need to do this atomically. See comment
above. */
CriticalSection->OwningThread = 0; CriticalSection->OwningThread = 0;
/* Was someone wanting us? */ /* Was someone wanting us? This needs to be done atomically. */
if (InterlockedDecrement(&CriticalSection->LockCount) >= 0) { if (InterlockedDecrement(&CriticalSection->LockCount) >= 0) {
/* Let him have us */ /* Let him have us */
@ -360,19 +366,19 @@ RtlTryEnterCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection) PRTL_CRITICAL_SECTION CriticalSection)
{ {
/* Try to take control */ /* Try to take control */
if (InterlockedCompareExchange(&CriticalSection->LockCount, if (InterlockedCompareExchange(&CriticalSection->LockCount, 0, -1) == -1) {
0,
-1) == -1) {
/* It's ours */ /* It's ours. Changing this information does not have to be serialized
because we just obtained the lock. */
CriticalSection->OwningThread = NtCurrentTeb()->Cid.UniqueThread; CriticalSection->OwningThread = NtCurrentTeb()->Cid.UniqueThread;
CriticalSection->RecursionCount = 1; CriticalSection->RecursionCount = 1;
return TRUE; return TRUE;
} else if (CriticalSection->OwningThread == NtCurrentTeb()->Cid.UniqueThread) { } else if (CriticalSection->OwningThread == NtCurrentTeb()->Cid.UniqueThread) {
/* It's already ours */ /* It's already ours, just increment the recursion counter. This doesn't
InterlockedIncrement(&CriticalSection->LockCount); have to be serialized because only the thread who already holds the
lock can do this. */
CriticalSection->RecursionCount++; CriticalSection->RecursionCount++;
return TRUE; return TRUE;
} }