mirror of
https://github.com/reactos/reactos.git
synced 2026-05-30 05:51:26 +08:00
[RTL] Update CountOfOwnedCriticalSections in the TEB
Useful for debugging.
Motivation: With SMP on x64 I found a number of instances where critical sections would be left abandoned, causing lockups. From what I can tell it was exceptions inside rpcrt4, which leave the process in a blocked state. Might or might not be related to x64 / SMP.
For real value, you still need to put checks at certain places manually, but this is not super straight forward, because there can be false positives, e.g. when a process is terminated due to an exception, where the abandoned lock is acceptable, and we have this during testing. It's difficult to 100% distinguish this from silent and very bad lock leaks.
Problematic code:
__try
{
SomeFunction(); // throws an exception with a CS held, e.g. heap code
}
__except(1)
{
DPRINT1("Oops. let's just pretend it's all ok!\n");
}
This commit is contained in:
@@ -521,6 +521,7 @@ RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
|
||||
*/
|
||||
CriticalSection->OwningThread = Thread;
|
||||
CriticalSection->RecursionCount = 1;
|
||||
NtCurrentTeb()->CountOfOwnedCriticalSections++;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -800,6 +801,7 @@ RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
|
||||
* See comment above.
|
||||
*/
|
||||
CriticalSection->OwningThread = 0;
|
||||
NtCurrentTeb()->CountOfOwnedCriticalSections--;
|
||||
|
||||
/* Was someone wanting us? This needs to be done atomically. */
|
||||
if (-1 != InterlockedDecrement(&CriticalSection->LockCount))
|
||||
@@ -837,8 +839,9 @@ RtlTryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
|
||||
if (InterlockedCompareExchange(&CriticalSection->LockCount, 0, -1) == -1)
|
||||
{
|
||||
/* It's ours */
|
||||
CriticalSection->OwningThread = NtCurrentTeb()->ClientId.UniqueThread;
|
||||
CriticalSection->OwningThread = NtCurrentTeb()->ClientId.UniqueThread;
|
||||
CriticalSection->RecursionCount = 1;
|
||||
NtCurrentTeb()->CountOfOwnedCriticalSections++;
|
||||
return TRUE;
|
||||
}
|
||||
else if (CriticalSection->OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
|
||||
|
||||
Reference in New Issue
Block a user