mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
don't increment the lock count twice in RtlTryEnterCriticalSection() and added some more comments
svn path=/trunk/; revision=13642
This commit is contained in:
parent
c6a8c7496f
commit
f66a4cec4d
1 changed files with 17 additions and 11 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue