- Code formatting (homogeneisation of...).
- For "Deadlock" DPRINT, replace the DPRINT1 by a ERROR_DBGBREAK for (user) debugging purposes only (a priori this shouldn't be hit during our automated tests).

svn path=/trunk/; revision=62547
This commit is contained in:
Hermès Bélusca-Maïto 2014-03-23 00:23:54 +00:00
parent 055a4866c3
commit 918e8924e7

View file

@ -52,7 +52,6 @@ RtlpCreateCriticalSectionSem(PRTL_CRITICAL_SECTION CriticalSection)
/* Check if we have an event */ /* Check if we have an event */
if (!hEvent) if (!hEvent)
{ {
/* No, so create it */ /* No, so create it */
Status = NtCreateEvent(&hNewEvent, Status = NtCreateEvent(&hNewEvent,
EVENT_ALL_ACCESS, EVENT_ALL_ACCESS,
@ -63,8 +62,10 @@ RtlpCreateCriticalSectionSem(PRTL_CRITICAL_SECTION CriticalSection)
{ {
DPRINT1("Failed to Create Event!\n"); DPRINT1("Failed to Create Event!\n");
/* Use INVALID_HANDLE_VALUE (-1) to signal that the global /*
keyed event must be used */ * Use INVALID_HANDLE_VALUE (-1) to signal that
* the global keyed event must be used.
*/
hNewEvent = INVALID_HANDLE_VALUE; hNewEvent = INVALID_HANDLE_VALUE;
} }
@ -111,7 +112,8 @@ RtlpWaitForCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
BOOLEAN LastChance = FALSE; BOOLEAN LastChance = FALSE;
/* Do we have an Event yet? */ /* Do we have an Event yet? */
if (!CriticalSection->LockSemaphore) { if (!CriticalSection->LockSemaphore)
{
RtlpCreateCriticalSectionSem(CriticalSection); RtlpCreateCriticalSectionSem(CriticalSection);
} }
@ -123,8 +125,8 @@ RtlpWaitForCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
if (CriticalSection->DebugInfo) if (CriticalSection->DebugInfo)
CriticalSection->DebugInfo->EntryCount++; CriticalSection->DebugInfo->EntryCount++;
for (;;) { for (;;)
{
/* Increase the number of times we've had contention */ /* Increase the number of times we've had contention */
if (CriticalSection->DebugInfo) if (CriticalSection->DebugInfo)
CriticalSection->DebugInfo->ContentionCount++; CriticalSection->DebugInfo->ContentionCount++;
@ -147,12 +149,12 @@ RtlpWaitForCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
} }
/* We have Timed out */ /* We have Timed out */
if (Status == STATUS_TIMEOUT) { if (Status == STATUS_TIMEOUT)
{
/* Is this the 2nd time we've timed out? */ /* Is this the 2nd time we've timed out? */
if (LastChance) { if (LastChance)
{
DPRINT1("Deadlock: %p\n", CriticalSection); ERROR_DBGBREAK("Deadlock: 0x%p\n", CriticalSection);
/* Yes it is, we are raising an exception */ /* Yes it is, we are raising an exception */
ExceptionRecord.ExceptionCode = STATUS_POSSIBLE_DEADLOCK; ExceptionRecord.ExceptionCode = STATUS_POSSIBLE_DEADLOCK;
@ -162,14 +164,13 @@ RtlpWaitForCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
ExceptionRecord.NumberParameters = 1; ExceptionRecord.NumberParameters = 1;
ExceptionRecord.ExceptionInformation[0] = (ULONG_PTR)CriticalSection; ExceptionRecord.ExceptionInformation[0] = (ULONG_PTR)CriticalSection;
RtlRaiseException(&ExceptionRecord); RtlRaiseException(&ExceptionRecord);
} }
/* One more try */ /* One more try */
LastChance = TRUE; LastChance = TRUE;
}
} else { else
{
/* If we are here, everything went fine */ /* If we are here, everything went fine */
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -198,7 +199,8 @@ RtlpUnWaitCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
NTSTATUS Status; NTSTATUS Status;
/* Do we have an Event yet? */ /* Do we have an Event yet? */
if (!CriticalSection->LockSemaphore) { if (!CriticalSection->LockSemaphore)
{
RtlpCreateCriticalSectionSem(CriticalSection); RtlpCreateCriticalSectionSem(CriticalSection);
} }
@ -219,8 +221,8 @@ RtlpUnWaitCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Status = NtSetEvent(CriticalSection->LockSemaphore, NULL); Status = NtSetEvent(CriticalSection->LockSemaphore, NULL);
} }
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status))
{
/* We've failed */ /* We've failed */
DPRINT1("Signaling Failed for: %p, %p, 0x%08lx\n", DPRINT1("Signaling Failed for: %p, %p, 0x%08lx\n",
CriticalSection, CriticalSection,
@ -249,7 +251,6 @@ VOID
NTAPI NTAPI
RtlpInitDeferedCriticalSection(VOID) RtlpInitDeferedCriticalSection(VOID)
{ {
/* Initialize the Process Critical Section List */ /* Initialize the Process Critical Section List */
InitializeListHead(&RtlCriticalSectionList); InitializeListHead(&RtlCriticalSectionList);
@ -283,11 +284,11 @@ RtlpAllocateDebugInfo(VOID)
ULONG i; ULONG i;
/* Try to allocate from our buffer first */ /* Try to allocate from our buffer first */
for (i = 0; i < MAX_STATIC_CS_DEBUG_OBJECTS; i++) { for (i = 0; i < MAX_STATIC_CS_DEBUG_OBJECTS; i++)
{
/* Check if Entry is free */ /* Check if Entry is free */
if (!RtlpDebugInfoFreeList[i]) { if (!RtlpDebugInfoFreeList[i])
{
/* Mark entry in use */ /* Mark entry in use */
DPRINT("Using entry: %lu. Buffer: %p\n", i, &RtlpStaticDebugInfo[i]); DPRINT("Using entry: %lu. Buffer: %p\n", i, &RtlpStaticDebugInfo[i]);
RtlpDebugInfoFreeList[i] = TRUE; RtlpDebugInfoFreeList[i] = TRUE;
@ -295,7 +296,6 @@ RtlpAllocateDebugInfo(VOID)
/* Use free entry found */ /* Use free entry found */
return &RtlpStaticDebugInfo[i]; return &RtlpStaticDebugInfo[i];
} }
} }
/* We are out of static buffer, allocate dynamic */ /* We are out of static buffer, allocate dynamic */
@ -328,8 +328,8 @@ RtlpFreeDebugInfo(PRTL_CRITICAL_SECTION_DEBUG DebugInfo)
/* Is it part of our cached entries? */ /* Is it part of our cached entries? */
if ((DebugInfo >= RtlpStaticDebugInfo) && if ((DebugInfo >= RtlpStaticDebugInfo) &&
(DebugInfo <= &RtlpStaticDebugInfo[MAX_STATIC_CS_DEBUG_OBJECTS-1])) { (DebugInfo <= &RtlpStaticDebugInfo[MAX_STATIC_CS_DEBUG_OBJECTS-1]))
{
/* Yes. zero it out */ /* Yes. zero it out */
RtlZeroMemory(DebugInfo, sizeof(RTL_CRITICAL_SECTION_DEBUG)); RtlZeroMemory(DebugInfo, sizeof(RTL_CRITICAL_SECTION_DEBUG));
@ -341,21 +341,21 @@ RtlpFreeDebugInfo(PRTL_CRITICAL_SECTION_DEBUG DebugInfo)
NtCurrentTeb()->ClientId.UniqueProcess); NtCurrentTeb()->ClientId.UniqueProcess);
RtlpDebugInfoFreeList[EntryId] = FALSE; RtlpDebugInfoFreeList[EntryId] = FALSE;
} else if (!DebugInfo->Flags) { }
else if (!DebugInfo->Flags)
{
/* It's a dynamic one, so free from the heap */ /* It's a dynamic one, so free from the heap */
DPRINT("Freeing from Heap: %p inside Process: %p\n", DPRINT("Freeing from Heap: %p inside Process: %p\n",
DebugInfo, DebugInfo,
NtCurrentTeb()->ClientId.UniqueProcess); NtCurrentTeb()->ClientId.UniqueProcess);
RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, DebugInfo); RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, DebugInfo);
}
} else { else
{
/* Wine stores a section name pointer in the Flags member */ /* Wine stores a section name pointer in the Flags member */
DPRINT("Assuming static: %p inside Process: %p\n", DPRINT("Assuming static: %p inside Process: %p\n",
DebugInfo, DebugInfo,
NtCurrentTeb()->ClientId.UniqueProcess); NtCurrentTeb()->ClientId.UniqueProcess);
} }
} }
@ -382,12 +382,12 @@ RtlDeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
DPRINT("Deleting Critical Section: %p\n", CriticalSection); DPRINT("Deleting Critical Section: %p\n", CriticalSection);
/* Close the Event Object Handle if it exists */
if (CriticalSection->LockSemaphore) {
/* Close the Event Object Handle if it exists */
if (CriticalSection->LockSemaphore)
{
/* In case NtClose fails, return the status */ /* In case NtClose fails, return the status */
Status = NtClose(CriticalSection->LockSemaphore); Status = NtClose(CriticalSection->LockSemaphore);
} }
/* Protect List */ /* Protect List */
@ -397,7 +397,8 @@ RtlDeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
{ {
/* Remove it from the list */ /* Remove it from the list */
RemoveEntryList(&CriticalSection->DebugInfo->ProcessLocksList); RemoveEntryList(&CriticalSection->DebugInfo->ProcessLocksList);
#if 0 /* We need to preserve Flags for RtlpFreeDebugInfo */ #if 0
/* We need to preserve Flags for RtlpFreeDebugInfo */
RtlZeroMemory(CriticalSection->DebugInfo, sizeof(RTL_CRITICAL_SECTION_DEBUG)); RtlZeroMemory(CriticalSection->DebugInfo, sizeof(RTL_CRITICAL_SECTION_DEBUG));
#endif #endif
} }
@ -470,18 +471,17 @@ RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
{ {
HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread; HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread;
/* Try to Lock it */ /* Try to lock it */
if (InterlockedIncrement(&CriticalSection->LockCount) != 0) { if (InterlockedIncrement(&CriticalSection->LockCount) != 0)
{
/* We've failed to lock it! Does this thread actually own it? */
if (Thread == CriticalSection->OwningThread)
{
/* /*
* We've failed to lock it! Does this thread * You own it, so you'll get it when you're done with it! No need to
* actually own it? * use the interlocked functions as only the thread who already owns
* the lock can modify this data.
*/ */
if (Thread == CriticalSection->OwningThread) {
/* You own it, so you'll get it when you're done with it! No need to
use the interlocked functions as only the thread who already owns
the lock can modify this data. */
CriticalSection->RecursionCount++; CriticalSection->RecursionCount++;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -497,9 +497,11 @@ RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
RtlpWaitForCriticalSection(CriticalSection); RtlpWaitForCriticalSection(CriticalSection);
} }
/* Lock successful. Changing this information has not to be serialized because /*
only one thread at a time can actually change it (the one who acquired * Lock successful. Changing this information has not to be serialized
the lock)! */ * because only one thread at a time can actually change it (the one who
* acquired the lock)!
*/
CriticalSection->OwningThread = Thread; CriticalSection->OwningThread = Thread;
CriticalSection->RecursionCount = 1; CriticalSection->RecursionCount = 1;
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -568,8 +570,8 @@ RtlInitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection,
CritcalSectionDebugData, CritcalSectionDebugData,
NtCurrentTeb()->ClientId.UniqueProcess); NtCurrentTeb()->ClientId.UniqueProcess);
if (!CritcalSectionDebugData) { if (!CritcalSectionDebugData)
{
/* This is bad! */ /* This is bad! */
DPRINT1("Couldn't allocate Debug Data for: %p\n", CriticalSection); DPRINT1("Couldn't allocate Debug Data for: %p\n", CriticalSection);
return STATUS_NO_MEMORY; return STATUS_NO_MEMORY;
@ -588,8 +590,8 @@ RtlInitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection,
* If we've initialized the Lock, then use it. If not, then probably * If we've initialized the Lock, then use it. If not, then probably
* this is the lock initialization itself, so insert it directly. * this is the lock initialization itself, so insert it directly.
*/ */
if ((CriticalSection != &RtlCriticalSectionLock) && (RtlpCritSectInitialized)) { if ((CriticalSection != &RtlCriticalSectionLock) && (RtlpCritSectInitialized))
{
DPRINT("Securely Inserting into ProcessLocks: %p, %p, %p\n", DPRINT("Securely Inserting into ProcessLocks: %p, %p, %p\n",
&CritcalSectionDebugData->ProcessLocksList, &CritcalSectionDebugData->ProcessLocksList,
CriticalSection, CriticalSection,
@ -603,9 +605,9 @@ RtlInitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection,
/* Unprotect */ /* Unprotect */
RtlLeaveCriticalSection(&RtlCriticalSectionLock); RtlLeaveCriticalSection(&RtlCriticalSectionLock);
}
} else { else
{
DPRINT("Inserting into ProcessLocks: %p, %p, %p\n", DPRINT("Inserting into ProcessLocks: %p, %p, %p\n",
&CritcalSectionDebugData->ProcessLocksList, &CritcalSectionDebugData->ProcessLocksList,
CriticalSection, CriticalSection,
@ -680,8 +682,10 @@ RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
#if DBG #if DBG
HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread; HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread;
/* In win this case isn't checked. However it's a valid check so it should only /*
be performed in debug builds! */ * 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");
@ -689,23 +693,28 @@ RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
} }
#endif #endif
/* 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 * Decrease the Recursion Count. No need to do this atomically because only
is totally screwed... */ * the thread who holds the lock can call this function (unless the program
if (--CriticalSection->RecursionCount) { * is totally screwed...
*/
if (--CriticalSection->RecursionCount)
{
/* Someone still owns us, but we are free. This needs to be done atomically. */ /* 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. No need to do this atomically. See comment {
above. */ /*
* Nobody owns us anymore. No need to do this atomically.
* See comment above.
*/
CriticalSection->OwningThread = 0; CriticalSection->OwningThread = 0;
/* Was someone wanting us? This needs to be done atomically. */ /* Was someone wanting us? This needs to be done atomically. */
if (-1 != InterlockedDecrement(&CriticalSection->LockCount)) { if (-1 != InterlockedDecrement(&CriticalSection->LockCount))
{
/* Let him have us */ /* Let him have us */
RtlpUnWaitCriticalSection(CriticalSection); RtlpUnWaitCriticalSection(CriticalSection);
} }
@ -736,17 +745,15 @@ NTAPI
RtlTryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection) RtlTryEnterCriticalSection(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 */
CriticalSection->OwningThread = NtCurrentTeb()->ClientId.UniqueThread; CriticalSection->OwningThread = NtCurrentTeb()->ClientId.UniqueThread;
CriticalSection->RecursionCount = 1; CriticalSection->RecursionCount = 1;
return TRUE; return TRUE;
}
} else if (CriticalSection->OwningThread == NtCurrentTeb()->ClientId.UniqueThread) { else if (CriticalSection->OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
{
/* It's already ours */ /* It's already ours */
InterlockedIncrement(&CriticalSection->LockCount); InterlockedIncrement(&CriticalSection->LockCount);
CriticalSection->RecursionCount++; CriticalSection->RecursionCount++;
@ -759,8 +766,7 @@ RtlTryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
VOID VOID
NTAPI NTAPI
RtlCheckForOrphanedCriticalSections( RtlCheckForOrphanedCriticalSections(HANDLE ThreadHandle)
HANDLE ThreadHandle)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }