Rewrite ROS Critical Section implementation, which was slow and broken (because it always created an event, which is the slow path). Note that coincidentally, Gunnar also fixed this code and committed a patch this morning, taken from WINE. This code is also based on WINE, but adds more features which WINE does not support/need yet (regarding Debug CS). Hence, this code was a re-write of the original ROS code, not of Gunnar's, and we've both discussed the accidental conflict.

svn path=/trunk/; revision=12766
This commit is contained in:
Alex Ionescu 2005-01-03 23:02:15 +00:00
parent a3e3b56cca
commit 352d524633
17 changed files with 542 additions and 370 deletions

View file

@ -2082,8 +2082,6 @@ VOID STDCALL WEP();
DWORD STDCALL RtlDeleteSecurityObject(DWORD x1); DWORD STDCALL RtlDeleteSecurityObject(DWORD x1);
DWORD STDCALL RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6); DWORD STDCALL RtlNewSecurityObject(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6);
NTSTATUS STDCALL RtlWalkHeap( HANDLE heap, PVOID entry_ptr ); NTSTATUS STDCALL RtlWalkHeap( HANDLE heap, PVOID entry_ptr );
NTSTATUS STDCALL RtlpUnWaitCriticalSection(RTL_CRITICAL_SECTION *crit);
NTSTATUS STDCALL RtlpWaitForCriticalSection(RTL_CRITICAL_SECTION *crit);
NTSTATUS STDCALL LdrLockLoaderLock(ULONG flags, ULONG *result, ULONG *magic); NTSTATUS STDCALL LdrLockLoaderLock(ULONG flags, ULONG *result, ULONG *magic);
NTSTATUS STDCALL LdrUnlockLoaderLock(ULONG flags, ULONG magic); NTSTATUS STDCALL LdrUnlockLoaderLock(ULONG flags, ULONG magic);

View file

@ -99,8 +99,8 @@ typedef struct _CRITICAL_SECTION_DEBUG
LIST_ENTRY ProcessLocksList; LIST_ENTRY ProcessLocksList;
ULONG EntryCount; ULONG EntryCount;
ULONG ContentionCount; ULONG ContentionCount;
ULONG Depth; PVOID OwnerBackTrace[2];
PVOID Spare[ 2 ]; PVOID Spare[2];
} CRITICAL_SECTION_DEBUG, *PCRITICAL_SECTION_DEBUG; } CRITICAL_SECTION_DEBUG, *PCRITICAL_SECTION_DEBUG;
@ -114,9 +114,13 @@ typedef struct _CRITICAL_SECTION
ULONG_PTR SpinCount; ULONG_PTR SpinCount;
} CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION; } CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
#define RTL_CRITSECT_TYPE 0
typedef CRITICAL_SECTION RTL_CRITICAL_SECTION; typedef CRITICAL_SECTION RTL_CRITICAL_SECTION;
typedef PCRITICAL_SECTION PRTL_CRITICAL_SECTION; typedef PCRITICAL_SECTION PRTL_CRITICAL_SECTION;
typedef LPCRITICAL_SECTION LPRTL_CRITICAL_SECTION; typedef LPCRITICAL_SECTION LPRTL_CRITICAL_SECTION;
typedef CRITICAL_SECTION_DEBUG RTL_CRITICAL_SECTION_DEBUG;
typedef PCRITICAL_SECTION_DEBUG PRTL_CRITICAL_SECTION_DEBUG;
#endif /* !__USE_W32API */ #endif /* !__USE_W32API */
@ -166,6 +170,29 @@ typedef struct _RTL_HANDLE_TABLE
#define PDI_HEAP_BLOCKS 0x10 /* The heap blocks */ #define PDI_HEAP_BLOCKS 0x10 /* The heap blocks */
#define PDI_LOCKS 0x20 /* The locks created by the process */ #define PDI_LOCKS 0x20 /* The locks created by the process */
NTSTATUS
STDCALL
RtlpWaitForCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection
);
VOID
STDCALL
RtlpUnWaitCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection
);
VOID
STDCALL
RtlpCreateCriticalSectionSem(
PRTL_CRITICAL_SECTION CriticalSection
);
VOID
STDCALL
RtlpInitDeferedCriticalSection(
VOID
);
NTSTATUS STDCALL NTSTATUS STDCALL
RtlAddAccessAllowedAceEx (IN OUT PACL Acl, RtlAddAccessAllowedAceEx (IN OUT PACL Acl,
@ -191,19 +218,19 @@ RtlAddAuditAccessAceEx(IN OUT PACL Acl,
IN BOOLEAN Failure); IN BOOLEAN Failure);
NTSTATUS STDCALL NTSTATUS STDCALL
RtlDeleteCriticalSection (PCRITICAL_SECTION CriticalSection); RtlDeleteCriticalSection (PRTL_CRITICAL_SECTION CriticalSection);
WCHAR STDCALL WCHAR STDCALL
RtlDowncaseUnicodeChar(IN WCHAR Source); RtlDowncaseUnicodeChar(IN WCHAR Source);
NTSTATUS STDCALL NTSTATUS STDCALL
RtlEnterCriticalSection (PCRITICAL_SECTION CriticalSection); RtlEnterCriticalSection (PRTL_CRITICAL_SECTION CriticalSection);
NTSTATUS STDCALL NTSTATUS STDCALL
RtlInitializeCriticalSection (PCRITICAL_SECTION CriticalSection); RtlInitializeCriticalSection (PRTL_CRITICAL_SECTION CriticalSection);
NTSTATUS STDCALL NTSTATUS STDCALL
RtlInitializeCriticalSectionAndSpinCount (PCRITICAL_SECTION CriticalSection, RtlInitializeCriticalSectionAndSpinCount (PRTL_CRITICAL_SECTION CriticalSection,
ULONG SpinCount); ULONG SpinCount);
NTSTATUS STDCALL NTSTATUS STDCALL
@ -212,10 +239,10 @@ RtlInt64ToUnicodeString (IN ULONGLONG Value,
PUNICODE_STRING String); PUNICODE_STRING String);
NTSTATUS STDCALL NTSTATUS STDCALL
RtlLeaveCriticalSection (PCRITICAL_SECTION CriticalSection); RtlLeaveCriticalSection (PRTL_CRITICAL_SECTION CriticalSection);
BOOLEAN STDCALL BOOLEAN STDCALL
RtlTryEnterCriticalSection (PCRITICAL_SECTION CriticalSection); RtlTryEnterCriticalSection (PRTL_CRITICAL_SECTION CriticalSection);
DWORD STDCALL DWORD STDCALL
RtlCompactHeap ( RtlCompactHeap (

View file

@ -1,4 +1,4 @@
/* $Id: reg.c,v 1.67 2004/12/26 23:09:51 gvg Exp $ /* $Id$
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -24,7 +24,7 @@
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
static CRITICAL_SECTION HandleTableCS; static RTL_CRITICAL_SECTION HandleTableCS;
static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES]; static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES];
static HANDLE ProcessHeap; static HANDLE ProcessHeap;

View file

@ -39,7 +39,7 @@ extern HANDLE hProcessHeap;
extern HANDLE hBaseDir; extern HANDLE hBaseDir;
extern HMODULE hCurrentModule; extern HMODULE hCurrentModule;
extern CRITICAL_SECTION DllLock; extern RTL_CRITICAL_SECTION DllLock;
extern UNICODE_STRING DllDirectory; extern UNICODE_STRING DllDirectory;

View file

@ -1,4 +1,4 @@
/* $Id: console.c,v 1.89 2004/12/24 17:45:57 weiden Exp $ /* $Id$
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -21,7 +21,7 @@
extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event); extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag); extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag);
extern CRITICAL_SECTION ConsoleLock; extern RTL_CRITICAL_SECTION ConsoleLock;
extern BOOL WINAPI IsDebuggerPresent(VOID); extern BOOL WINAPI IsDebuggerPresent(VOID);

View file

@ -1,4 +1,4 @@
/* $Id: dllmain.c,v 1.38 2004/11/29 00:08:59 gdalsnes Exp $ /* $Id$
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -33,8 +33,8 @@ DllMain(HANDLE hInst,
LPVOID lpReserved); LPVOID lpReserved);
/* Critical section for various kernel32 data structures */ /* Critical section for various kernel32 data structures */
CRITICAL_SECTION DllLock; RTL_CRITICAL_SECTION DllLock;
CRITICAL_SECTION ConsoleLock; RTL_CRITICAL_SECTION ConsoleLock;
extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event); extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);

View file

@ -82,15 +82,15 @@ typedef struct _NLS_FORMAT_NODE
#define GetShortMonth(fmt,mth) fmt->lppszStrings[30 + mth] #define GetShortMonth(fmt,mth) fmt->lppszStrings[30 + mth]
/* Write access to the cache is protected by this critical section */ /* Write access to the cache is protected by this critical section */
static CRITICAL_SECTION NLS_FormatsCS; static RTL_CRITICAL_SECTION NLS_FormatsCS;
static CRITICAL_SECTION_DEBUG NLS_FormatsCS_debug = static RTL_CRITICAL_SECTION_DEBUG NLS_FormatsCS_debug =
{ {
0, 0, &NLS_FormatsCS, 0, 0, &NLS_FormatsCS,
{ &NLS_FormatsCS_debug.ProcessLocksList, { &NLS_FormatsCS_debug.ProcessLocksList,
&NLS_FormatsCS_debug.ProcessLocksList }, &NLS_FormatsCS_debug.ProcessLocksList },
0, 0, { 0, (DWORD)(__FILE__ ": NLS_Formats") } 0, 0, { 0, (DWORD)(__FILE__ ": NLS_Formats") }
}; };
static CRITICAL_SECTION NLS_FormatsCS = { &NLS_FormatsCS_debug, -1, 0, 0, 0, 0 }; static RTL_CRITICAL_SECTION NLS_FormatsCS = { &NLS_FormatsCS_debug, -1, 0, 0, 0, 0 };
/************************************************************************** /**************************************************************************
* NLS_GetLocaleNumber <internal> * NLS_GetLocaleNumber <internal>

View file

@ -58,7 +58,7 @@ static const unsigned char UTF8Mask[6] = {0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
static LIST_ENTRY CodePageListHead; static LIST_ENTRY CodePageListHead;
static CODEPAGE_ENTRY AnsiCodePage; static CODEPAGE_ENTRY AnsiCodePage;
static CODEPAGE_ENTRY OemCodePage; static CODEPAGE_ENTRY OemCodePage;
static CRITICAL_SECTION CodePageListLock; static RTL_CRITICAL_SECTION CodePageListLock;
/* FORWARD DECLARATIONS *******************************************************/ /* FORWARD DECLARATIONS *******************************************************/

View file

@ -72,14 +72,14 @@ static PROFILE *MRUProfile[N_CACHED_PROFILES]={NULL};
static const WCHAR emptystringW[] = {0}; static const WCHAR emptystringW[] = {0};
static CRITICAL_SECTION PROFILE_CritSect; static RTL_CRITICAL_SECTION PROFILE_CritSect;
static CRITICAL_SECTION_DEBUG critsect_debug = static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
{ {
0, 0, &PROFILE_CritSect, 0, 0, &PROFILE_CritSect,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { 0, (DWORD)(__FILE__ ": PROFILE_CritSect") } 0, 0, { 0, (DWORD)(__FILE__ ": PROFILE_CritSect") }
}; };
static CRITICAL_SECTION PROFILE_CritSect = { &critsect_debug, -1, 0, 0, 0, 0 }; static RTL_CRITICAL_SECTION PROFILE_CritSect = { &critsect_debug, -1, 0, 0, 0, 0 };
static const char hex[16] = "0123456789ABCDEF"; static const char hex[16] = "0123456789ABCDEF";

View file

@ -1,4 +1,4 @@
/* $Id: critical.c,v 1.16 2004/01/29 23:41:36 navaraf Exp $ /* $Id$
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -26,7 +26,7 @@ InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{ {
NTSTATUS Status; NTSTATUS Status;
Status = RtlInitializeCriticalSection(lpCriticalSection); Status = RtlInitializeCriticalSection((PRTL_CRITICAL_SECTION)lpCriticalSection);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
RtlRaiseStatus(Status); RtlRaiseStatus(Status);
@ -45,7 +45,7 @@ InitializeCriticalSectionAndSpinCount(
{ {
NTSTATUS Status; NTSTATUS Status;
Status = RtlInitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount); Status = RtlInitializeCriticalSectionAndSpinCount((PRTL_CRITICAL_SECTION)lpCriticalSection, dwSpinCount);
if (Status) if (Status)
{ {
RtlRaiseStatus(Status); RtlRaiseStatus(Status);

View file

@ -1,4 +1,4 @@
/* $Id: startup.c,v 1.60 2004/12/15 03:00:33 royce Exp $ /* $Id$
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -259,6 +259,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
/* If MZ header exists */ /* If MZ header exists */
PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase; PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
DPRINT("PEDosHeader %x\n", PEDosHeader); DPRINT("PEDosHeader %x\n", PEDosHeader);
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
PEDosHeader->e_lfanew == 0L || PEDosHeader->e_lfanew == 0L ||
*(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_PE_MAGIC) *(PULONG)((PUCHAR)ImageBase + PEDosHeader->e_lfanew) != IMAGE_PE_MAGIC)
@ -279,6 +280,9 @@ __true_LdrInitializeThunk (ULONG Unknown1,
NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew); NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew);
/* Initialize Critical Section Data */
RtlpInitDeferedCriticalSection();
/* create process heap */ /* create process heap */
RtlInitializeHeapManager(); RtlInitializeHeapManager();
Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE, Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE,
@ -292,7 +296,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
DPRINT1("Failed to create process heap\n"); DPRINT1("Failed to create process heap\n");
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL); ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
} }
/* initalize peb lock support */ /* initalize peb lock support */
RtlInitializeCriticalSection (&PebLock); RtlInitializeCriticalSection (&PebLock);
Peb->FastPebLock = &PebLock; Peb->FastPebLock = &PebLock;
@ -311,7 +315,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
RtlAllocateHeap(RtlGetProcessHeap(), RtlAllocateHeap(RtlGetProcessHeap(),
0, 0,
sizeof(PVOID) * (USER32_CALLBACK_MAXIMUM + 1)); sizeof(PVOID) * (USER32_CALLBACK_MAXIMUM + 1));
/* initalize loader lock */ /* initalize loader lock */
RtlInitializeCriticalSection (&LoaderLock); RtlInitializeCriticalSection (&LoaderLock);
Peb->LoaderLock = &LoaderLock; Peb->LoaderLock = &LoaderLock;

View file

@ -6,6 +6,8 @@
* PURPOSE: Critical sections * PURPOSE: Critical sections
* UPDATE HISTORY: * UPDATE HISTORY:
* Created 30/09/98 * Created 30/09/98
* Rewritten ROS version, based on WINE code plus
* some fixes useful only for ROS right now - 03/01/05
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES ******************************************************************/
@ -19,391 +21,532 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
inline static HANDLE RtlGetCurrentThreadId() static RTL_CRITICAL_SECTION RtlCriticalSectionLock;
static LIST_ENTRY RtlCriticalSectionList;
static BOOLEAN RtlpCritSectInitialized = FALSE;
/*++
* RtlDeleteCriticalSection
* @implemented NT4
*
* Deletes a Critical Section
*
* Params:
* CriticalSection - Critical section to delete.
*
* Returns:
* STATUS_SUCCESS, or error value returned by NtClose.
*
* Remarks:
* The critical section members should not be read after this call.
*
*--*/
NTSTATUS
STDCALL
RtlDeleteCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection)
{ {
return (HANDLE)NtCurrentTeb()->Cid.UniqueThread; NTSTATUS Status = STATUS_SUCCESS;
/* Close the Event Object Handle if it exists */
if (CriticalSection->LockSemaphore) {
Status = NtClose(CriticalSection->LockSemaphore);
}
/* Protect List */
RtlEnterCriticalSection(&RtlCriticalSectionLock);
/* Delete the Debug Data, if it exists */
if (CriticalSection->DebugInfo) {
/* Remove it from the list */
RemoveEntryList(&CriticalSection->DebugInfo->ProcessLocksList);
/* Free it */
RtlFreeHeap(RtlGetProcessHeap(), 0, CriticalSection->DebugInfo);
}
/* Unprotect */
RtlLeaveCriticalSection(&RtlCriticalSectionLock);
/* Wipe it out */
RtlZeroMemory(CriticalSection, sizeof(RTL_CRITICAL_SECTION));
/* Return */
return Status;
} }
inline static void small_pause(void) /*++
{ * RtlSetCriticalSectionSpinCount
#ifdef __i386__ * @implemented NT4
__asm__ __volatile__( "rep;nop" : : : "memory" ); *
#else * Sets the spin count for a critical section.
__asm__ __volatile__( "" : : : "memory" ); *
#endif * Params:
* CriticalSection - Critical section to set the spin count for.
*
* SpinCount - Spin count for the critical section.
*
* Returns:
* STATUS_SUCCESS.
*
* Remarks:
* SpinCount is ignored on single-processor systems.
*
*--*/
DWORD
STDCALL
RtlSetCriticalSectionSpinCount(
PRTL_CRITICAL_SECTION CriticalSection,
DWORD SpinCount
)
{
DWORD OldCount = CriticalSection->SpinCount;
/* Set to parameter if MP, or to 0 if this is Uniprocessor */
CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
return OldCount;
} }
/*********************************************************************** /*++
* get_semaphore * RtlEnterCriticalSection
*/ * @implemented NT4
static inline HANDLE get_semaphore( PCRITICAL_SECTION crit ) *
* Waits to gain ownership of the critical section.
*
* Params:
* CriticalSection - Critical section to wait for.
*
* Returns:
* STATUS_SUCCESS.
*
* Remarks:
* Uses a fast-path unless contention happens.
*
*--*/
NTSTATUS
STDCALL
RtlEnterCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection)
{ {
HANDLE ret = crit->LockSemaphore; HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread;
if (!ret)
{ /* Try to Lock it */
HANDLE sem; if (InterlockedIncrement(&CriticalSection->LockCount)) {
if (!NT_SUCCESS(NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 ))) return 0;
if (!(ret = (HANDLE)InterlockedCompareExchangePointer( (PVOID *)&crit->LockSemaphore, /*
(PVOID)sem, 0 ))) * We've failed to lock it! Does this thread
ret = sem; * actually own it?
else */
NtClose(sem); /* somebody beat us to it */ if (Thread == CriticalSection->OwningThread) {
}
return ret; /* You own it, so you'll get it when you're done with it! */
CriticalSection->RecursionCount++;
return STATUS_SUCCESS;
}
/* We don't own it, so we must wait for it */
RtlpWaitForCriticalSection(CriticalSection);
}
/* Lock successful */
CriticalSection->OwningThread = Thread;
CriticalSection->RecursionCount = 1;
return STATUS_SUCCESS;
} }
/*********************************************************************** /*++
* RtlInitializeCriticalSection (NTDLL.@) * RtlInitializeCriticalSection
* @implemented NT4
* *
* Initialises a new critical section. * Initialises a new critical section.
* *
* PARAMS * Params:
* crit [O] Critical section to initialise * CriticalSection - Critical section to initialise
* *
* RETURNS * Returns:
* STATUS_SUCCESS. * STATUS_SUCCESS.
* *
* SEE * Remarks:
* RtlInitializeCriticalSectionAndSpinCount(), RtlDeleteCriticalSection(), * Simply calls RtlInitializeCriticalSectionAndSpinCount
* RtlEnterCriticalSection(), RtlLeaveCriticalSection(), *
* RtlTryEnterCriticalSection(), RtlSetCriticalSectionSpinCount() *--*/
*/ NTSTATUS
NTSTATUS STDCALL RtlInitializeCriticalSection( PCRITICAL_SECTION crit ) STDCALL
{ RtlInitializeCriticalSection(
return RtlInitializeCriticalSectionAndSpinCount( crit, 0 ); PRTL_CRITICAL_SECTION CriticalSection)
{
/* Call the Main Function */
return RtlInitializeCriticalSectionAndSpinCount(CriticalSection, 0);
} }
/*********************************************************************** /*++
* RtlInitializeCriticalSectionAndSpinCount (NTDLL.@) * RtlInitializeCriticalSectionAndSpinCount
* @implemented NT4
* *
* Initialises a new critical section with a given spin count. * Initialises a new critical section.
* *
* PARAMS * Params:
* crit [O] Critical section to initialise * CriticalSection - Critical section to initialise
* spincount [I] Spin count for crit
*
* RETURNS
* STATUS_SUCCESS.
* *
* NOTES * SpinCount - Spin count for the critical section.
* Available on NT4 SP3 or later.
* *
* SEE * Returns:
* RtlInitializeCriticalSection(), RtlDeleteCriticalSection(), * STATUS_SUCCESS.
* RtlEnterCriticalSection(), RtlLeaveCriticalSection(), *
* RtlTryEnterCriticalSection(), RtlSetCriticalSectionSpinCount() * Remarks:
*/ * SpinCount is ignored on single-processor systems.
NTSTATUS STDCALL RtlInitializeCriticalSectionAndSpinCount( PCRITICAL_SECTION crit, ULONG spincount ) *
*--*/
NTSTATUS
STDCALL
RtlInitializeCriticalSectionAndSpinCount (
PRTL_CRITICAL_SECTION CriticalSection,
DWORD SpinCount)
{ {
/* Does ROS need this, or is this special to Wine? And if ros need it, should PRTL_CRITICAL_SECTION_DEBUG CritcalSectionDebugData;
it be enabled in the release build? -Gunnar */ PVOID Heap;
if (RtlGetProcessHeap()) crit->DebugInfo = NULL;
else /* First things first, set up the Object */
{ CriticalSection->LockCount = -1;
crit->DebugInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(CRITICAL_SECTION_DEBUG)); CriticalSection->RecursionCount = 0;
if (crit->DebugInfo) CriticalSection->OwningThread = 0;
{ CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
crit->DebugInfo->Type = 0;
crit->DebugInfo->CreatorBackTraceIndex = 0; /*
crit->DebugInfo->CriticalSection = crit; * Now set up the Debug Data
crit->DebugInfo->ProcessLocksList.Blink = &(crit->DebugInfo->ProcessLocksList); * Think of a better way to allocate it, because the Heap Manager won't
crit->DebugInfo->ProcessLocksList.Flink = &(crit->DebugInfo->ProcessLocksList); * have any debug data since the Heap isn't initalized!
crit->DebugInfo->EntryCount = 0; */
crit->DebugInfo->ContentionCount = 0; if ((Heap = RtlGetProcessHeap())) {
crit->DebugInfo->Spare[0] = 0;
crit->DebugInfo->Spare[1] = 0; CritcalSectionDebugData = RtlAllocateHeap(Heap, 0, sizeof(RTL_CRITICAL_SECTION_DEBUG));
} CritcalSectionDebugData->Type = RTL_CRITSECT_TYPE;
} CritcalSectionDebugData->ContentionCount = 0;
crit->LockCount = -1; CritcalSectionDebugData->EntryCount = 0;
crit->RecursionCount = 0; CritcalSectionDebugData->CriticalSection = CriticalSection;
crit->OwningThread = 0; CriticalSection->DebugInfo = CritcalSectionDebugData;
crit->LockSemaphore = 0;
crit->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? spincount : 0; /*
return STATUS_SUCCESS; * Add it to the List of Critical Sections owned by the process.
* If we've initialized the Lock, then use it. If not, then probably
* this is the lock initialization itself, so insert it directly.
*/
if ((CriticalSection != &RtlCriticalSectionLock) && (RtlpCritSectInitialized)) {
/* Protect List */
RtlEnterCriticalSection(&RtlCriticalSectionLock);
/* Add this one */
InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
/* Unprotect */
RtlLeaveCriticalSection(&RtlCriticalSectionLock);
} else {
/* Add it directly */
InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
}
} else {
/* This shouldn't happen... */
CritcalSectionDebugData = NULL;
}
return STATUS_SUCCESS;
} }
/*********************************************************************** /*++
* RtlSetCriticalSectionSpinCount (NTDLL.@) * RtlLeaveCriticalSection
* @implemented NT4
* *
* Sets the spin count of a critical section. * Releases a critical section and makes if available for new owners.
* *
* PARAMS * Params:
* crit [I/O] Critical section * CriticalSection - Critical section to release.
* spincount [I] Spin count for crit
* *
* RETURNS * Returns:
* The previous spin count. * STATUS_SUCCESS.
* *
* NOTES * Remarks:
* If the system is not SMP, spincount is ignored and set to 0. * If another thread was waiting, the slow path is entered.
* *
* SEE *--*/
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), NTSTATUS
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(), STDCALL
* RtlLeaveCriticalSection(), RtlTryEnterCriticalSection() RtlLeaveCriticalSection(
*/ PRTL_CRITICAL_SECTION CriticalSection)
ULONG STDCALL RtlSetCriticalSectionSpinCount( PCRITICAL_SECTION crit, ULONG spincount ) {
{ /* Decrease the Recursion Count */
ULONG oldspincount = crit->SpinCount; if (--CriticalSection->RecursionCount) {
crit->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? spincount : 0;
return oldspincount; /* Someone still owns us, but we are free */
InterlockedDecrement(&CriticalSection->LockCount);
} else {
/* Nobody owns us anymore */
CriticalSection->OwningThread = 0;
/* Was someone wanting us? */
if (InterlockedDecrement(&CriticalSection->LockCount) >= 0) {
/* Let him have us */
RtlpUnWaitCriticalSection(CriticalSection);
}
}
/* Sucessful! */
return STATUS_SUCCESS;
} }
/*********************************************************************** /*++
* RtlDeleteCriticalSection (NTDLL.@) * RtlTryEnterCriticalSection
* @implemented NT4
* *
* Frees the resources used by a critical section. * Attemps to gain ownership of the critical section without waiting.
* *
* PARAMS * Params:
* crit [I/O] Critical section to free * CriticalSection - Critical section to attempt acquiring.
* *
* RETURNS * Returns:
* STATUS_SUCCESS. * TRUE if the critical section has been acquired, FALSE otherwise.
* *
* SEE * Remarks:
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * None
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(), *
* RtlLeaveCriticalSection(), RtlTryEnterCriticalSection() *--*/
*/ BOOLEAN
NTSTATUS STDCALL RtlDeleteCriticalSection( PCRITICAL_SECTION crit ) STDCALL
{ RtlTryEnterCriticalSection(
crit->LockCount = -1; PRTL_CRITICAL_SECTION CriticalSection)
crit->RecursionCount = 0; {
crit->OwningThread = (HANDLE)0; /* Try to take control */
if (crit->LockSemaphore) if (InterlockedCompareExchange(&CriticalSection->LockCount,
NtClose( crit->LockSemaphore ); 0,
crit->LockSemaphore = 0; -1) == -1) {
if (crit->DebugInfo)
{ /* It's ours */
/* only free the ones we made in here */ CriticalSection->OwningThread = NtCurrentTeb()->Cid.UniqueThread;
if (!crit->DebugInfo->Spare[1]) CriticalSection->RecursionCount = 1;
{ return TRUE;
RtlFreeHeap( RtlGetProcessHeap(), 0, crit->DebugInfo );
crit->DebugInfo = NULL; } else if (CriticalSection->OwningThread == NtCurrentTeb()->Cid.UniqueThread) {
}
} /* It's already ours */
return STATUS_SUCCESS; InterlockedIncrement(&CriticalSection->LockCount);
CriticalSection->RecursionCount++;
return TRUE;
}
/* It's not ours */
return FALSE;
} }
/*++
/*********************************************************************** * RtlpWaitForCriticalSection
* RtlpWaitForCriticalSection (NTDLL.@)
* *
* Waits for a busy critical section to become free. * Slow path of RtlEnterCriticalSection. Waits on an Event Object.
*
* PARAMS
* crit [I/O] Critical section to wait for
* *
* RETURNS * Params:
* STATUS_SUCCESS. * CriticalSection - Critical section to acquire.
* *
* NOTES * Returns:
* Use RtlEnterCriticalSection() instead of this function as it is often much * STATUS_SUCCESS, or raises an exception if a deadlock is occuring.
* faster.
* *
* SEE * Remarks:
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * None
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(), *
* RtlLeaveCriticalSection(), RtlTryEnterCriticalSection() *--*/
*/ NTSTATUS
NTSTATUS STDCALL RtlpWaitForCriticalSection( PCRITICAL_SECTION crit ) STDCALL
RtlpWaitForCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection)
{ {
for (;;) NTSTATUS Status;
{ EXCEPTION_RECORD ExceptionRecord;
EXCEPTION_RECORD rec; BOOLEAN LastChance = FALSE;
HANDLE sem = get_semaphore( crit ); LARGE_INTEGER Timeout;
LARGE_INTEGER time;
NTSTATUS status; Timeout = RtlConvertLongToLargeInteger(150000);
/* ^^ HACK HACK HACK. Good way:
time.QuadPart = -5000 * 10000; /* 5 seconds */ Timeout = &NtCurrentPeb()->CriticalSectionTimeout */
status = NtWaitForSingleObject( sem, FALSE, &time );
if ( status == STATUS_TIMEOUT ) /* Do we have an Event yet? */
{ if (!CriticalSection->LockSemaphore) {
const char *name = NULL; RtlpCreateCriticalSectionSem(CriticalSection);
if (crit->DebugInfo) name = (char *)crit->DebugInfo->Spare[1]; }
if (!name) name = "?";
DPRINT1( "section %p %s wait timed out in thread %04lx, blocked by %04lx, retrying (60 sec)\n", /* Increase the Debug Entry count */
crit, name, RtlGetCurrentThreadId(), (DWORD)crit->OwningThread ); CriticalSection->DebugInfo->EntryCount++;
time.QuadPart = -60000 * 10000;
status = NtWaitForSingleObject( sem, FALSE, &time ); for (;;) {
if ( status == STATUS_TIMEOUT /*&& TRACE_ON(relay)*/ )
{ /* Increase the number of times we've had contention */
DPRINT1( "section %p %s wait timed out in thread %04lx, blocked by %04lx, retrying (5 min)\n", CriticalSection->DebugInfo->ContentionCount++;
crit, name, RtlGetCurrentThreadId(), (DWORD) crit->OwningThread );
time.QuadPart = -300000 * (ULONGLONG)10000; /* Wait on the Event */
status = NtWaitForSingleObject( sem, FALSE, &time ); Status = NtWaitForSingleObject(CriticalSection->LockSemaphore,
} FALSE,
} &Timeout);
if (status == STATUS_WAIT_0) return STATUS_SUCCESS;
/* We have Timed out */
/* Throw exception only for Wine internal locks */ if (Status == STATUS_TIMEOUT) {
if ((!crit->DebugInfo) || (!crit->DebugInfo->Spare[1])) continue;
/* Is this the 2nd time we've timed out? */
rec.ExceptionCode = STATUS_POSSIBLE_DEADLOCK; if (LastChance) {
rec.ExceptionFlags = 0;
rec.ExceptionRecord = NULL; /* Yes it is, we are raising an exception */
rec.ExceptionAddress = RtlRaiseException; /* sic */ ExceptionRecord.ExceptionCode = STATUS_POSSIBLE_DEADLOCK;
rec.NumberParameters = 1; ExceptionRecord.ExceptionFlags = 0;
rec.ExceptionInformation[0] = (DWORD)crit; ExceptionRecord.ExceptionRecord = NULL;
RtlRaiseException( &rec ); ExceptionRecord.ExceptionAddress = RtlRaiseException;
} ExceptionRecord.NumberParameters = 1;
ExceptionRecord.ExceptionInformation[0] = (ULONG_PTR)CriticalSection;
RtlRaiseException(&ExceptionRecord);
}
/* One more try */
LastChance = TRUE;
} else {
/* If we are here, everything went fine */
return STATUS_SUCCESS;
}
}
} }
/*++
/*********************************************************************** * RtlpUnWaitCriticalSection
* RtlpUnWaitCriticalSection (NTDLL.@)
* *
* Notifies other threads waiting on the busy critical section that it has * Slow path of RtlLeaveCriticalSection. Fires an Event Object.
* become free.
*
* PARAMS
* crit [I/O] Critical section
* *
* RETURNS * Params:
* Success: STATUS_SUCCESS. * CriticalSection - Critical section to release.
* Failure: Any error returned by NtReleaseSemaphore()
* *
* NOTES * Returns:
* Use RtlLeaveCriticalSection() instead of this function as it is often much * None. Raises an exception if the system call failed.
* faster.
* *
* SEE * Remarks:
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * None
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(), *
* RtlLeaveCriticalSection(), RtlTryEnterCriticalSection() *--*/
*/ VOID
NTSTATUS STDCALL RtlpUnWaitCriticalSection( PCRITICAL_SECTION crit ) STDCALL
RtlpUnWaitCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection)
{ {
HANDLE sem = get_semaphore( crit ); NTSTATUS Status;
NTSTATUS res = NtReleaseSemaphore( sem, 1, NULL );
if (!NT_SUCCESS(res)) RtlRaiseStatus( res ); /* Do we have an Event yet? */
return res; if (!CriticalSection->LockSemaphore) {
RtlpCreateCriticalSectionSem(CriticalSection);
}
/* Signal the Event */
Status = NtSetEvent(CriticalSection->LockSemaphore, NULL);
if (!NT_SUCCESS(Status)) {
/* We've failed */
RtlRaiseStatus(Status);
}
} }
/*++
/*********************************************************************** * RtlpCreateCriticalSectionSem
* RtlEnterCriticalSection (NTDLL.@)
* *
* Enters a critical section, waiting for it to become available if necessary. * Checks if an Event has been created for the critical section.
* *
* PARAMS * Params:
* crit [I/O] Critical section to enter * None
* *
* RETURNS * Returns:
* STATUS_SUCCESS. The critical section is held by the caller. * None. Raises an exception if the system call failed.
* *
* SEE * Remarks:
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * None
* RtlDeleteCriticalSection(), RtlSetCriticalSectionSpinCount(), *
* RtlLeaveCriticalSection(), RtlTryEnterCriticalSection() *--*/
*/ VOID
NTSTATUS STDCALL RtlEnterCriticalSection( PCRITICAL_SECTION crit ) STDCALL
RtlpCreateCriticalSectionSem(
PRTL_CRITICAL_SECTION CriticalSection)
{ {
if (crit->SpinCount) HANDLE hEvent = CriticalSection->LockSemaphore;
{ HANDLE hNewEvent;
ULONG count; NTSTATUS Status;
if (RtlTryEnterCriticalSection( crit )) return STATUS_SUCCESS; /* Chevk if we have an event */
for (count = crit->SpinCount; count > 0; count--) if (!hEvent) {
{
if (crit->LockCount > 0) break; /* more than one waiter, don't bother spinning */ /* No, so create it */
if (crit->LockCount == -1) /* try again */ if (NT_SUCCESS(Status = NtCreateEvent(hNewEvent,
{ EVENT_ALL_ACCESS,
if (InterlockedCompareExchange(&crit->LockCount, 0,-1 ) == -1) goto done; NULL,
} SynchronizationEvent,
small_pause(); FALSE))) {
}
} /* We failed, this is bad... */
InterlockedDecrement(&CriticalSection->LockCount);
if (InterlockedIncrement( &crit->LockCount )) RtlRaiseStatus(Status);
{ return;
if (crit->OwningThread == (HANDLE)RtlGetCurrentThreadId()) }
{
crit->RecursionCount++; if (!(hEvent = InterlockedCompareExchangePointer((PVOID*)&CriticalSection->LockSemaphore,
return STATUS_SUCCESS; (PVOID)hNewEvent,
} 0))) {
/* Now wait for it */ /* We created a new event succesffuly */
RtlpWaitForCriticalSection( crit ); hEvent = hNewEvent;
} } else {
done:
crit->OwningThread = (HANDLE)RtlGetCurrentThreadId(); /* Some just created an event */
crit->RecursionCount = 1; NtClose(hNewEvent);
return STATUS_SUCCESS; }
/* Set either the new or the old */
CriticalSection->LockSemaphore = hEvent;
}
return;
} }
/*++
/*********************************************************************** * RtlpInitDeferedCriticalSection
* RtlTryEnterCriticalSection (NTDLL.@)
* *
* Tries to enter a critical section without waiting. * Initializes the Critical Section implementation.
* *
* PARAMS * Params:
* crit [I/O] Critical section to enter * None
* *
* RETURNS * Returns:
* Success: TRUE. The critical section is held by the caller. * None.
* Failure: FALSE. The critical section is currently held by another thread.
* *
* SEE * Remarks:
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(), * After this call, the Process Critical Section list is protected.
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(), *
* RtlLeaveCriticalSection(), RtlSetCriticalSectionSpinCount() *--*/
*/ VOID
BOOLEAN STDCALL RtlTryEnterCriticalSection( PCRITICAL_SECTION crit ) STDCALL
RtlpInitDeferedCriticalSection(
VOID)
{ {
BOOL ret = FALSE;
if (InterlockedCompareExchange(&crit->LockCount, 0L, -1 ) == -1) /* Initialize the Process Critical Section List */
{ InitializeListHead(&RtlCriticalSectionList);
crit->OwningThread = (HANDLE)RtlGetCurrentThreadId();
crit->RecursionCount = 1; /* Initialize the CS Protecting the List */
ret = TRUE; RtlInitializeCriticalSection(&RtlCriticalSectionLock);
}
else if (crit->OwningThread == (HANDLE)RtlGetCurrentThreadId()) /* It's now safe to enter it */
{ RtlpCritSectInitialized = TRUE;
InterlockedIncrement( &crit->LockCount );
crit->RecursionCount++;
ret = TRUE;
}
return ret;
} }
/***********************************************************************
* RtlLeaveCriticalSection (NTDLL.@)
*
* Leaves a critical section.
*
* PARAMS
* crit [I/O] Critical section to leave.
*
* RETURNS
* STATUS_SUCCESS.
*
* SEE
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(),
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(),
* RtlSetCriticalSectionSpinCount(), RtlTryEnterCriticalSection()
*/
NTSTATUS STDCALL RtlLeaveCriticalSection( PCRITICAL_SECTION crit )
{
if (crit->OwningThread != RtlGetCurrentThreadId())
{
DPRINT1("Freeing critical section not owned\n");
}
if (--crit->RecursionCount) InterlockedDecrement( &crit->LockCount );
else
{
crit->OwningThread = 0;
if (InterlockedDecrement( &crit->LockCount ) >= 0)
{
/* someone is waiting */
RtlpUnWaitCriticalSection( crit );
}
}
return STATUS_SUCCESS;
}
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: process.c,v 1.39 2004/12/25 22:58:59 gvg Exp $ /* $Id$
* *
* reactos/subsys/csrss/api/process.c * reactos/subsys/csrss/api/process.c
* *
@ -25,7 +25,7 @@
static ULONG NrProcess; static ULONG NrProcess;
static PCSRSS_PROCESS_DATA ProcessData[256]; static PCSRSS_PROCESS_DATA ProcessData[256];
CRITICAL_SECTION ProcessDataLock; RTL_CRITICAL_SECTION ProcessDataLock;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/

View file

@ -1,4 +1,4 @@
/* $Id: api.h,v 1.7 2004/11/14 18:47:10 hbirr Exp $ /* $Id$
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries

View file

@ -1,4 +1,4 @@
/* $Id: conio.c,v 1.19 2004/12/25 11:22:37 navaraf Exp $ /* $Id$
* *
* reactos/subsys/csrss/win32csr/conio.c * reactos/subsys/csrss/win32csr/conio.c
* *
@ -139,7 +139,7 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
{ {
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
RtlInitializeCriticalSection(&Buffer->Header.Lock); InitializeCriticalSection(&Buffer->Header.Lock);
ConioInitScreenBuffer(Console, Buffer); ConioInitScreenBuffer(Console, Buffer);
/* initialize buffer to be empty with default attributes */ /* initialize buffer to be empty with default attributes */
for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++) for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
@ -193,7 +193,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
Console->PrivateData = NULL; Console->PrivateData = NULL;
RtlInitializeCriticalSection(&Console->Header.Lock); InitializeCriticalSection(&Console->Header.Lock);
GuiMode = DtbgIsDesktopVisible(); GuiMode = DtbgIsDesktopVisible();
if (! GuiMode) if (! GuiMode)
{ {
@ -210,7 +210,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
if (! NT_SUCCESS(Status)) if (! NT_SUCCESS(Status))
{ {
RtlFreeUnicodeString(&Console->Title); RtlFreeUnicodeString(&Console->Title);
RtlDeleteCriticalSection(&Console->Header.Lock); DeleteCriticalSection(&Console->Header.Lock);
CloseHandle(Console->ActiveEvent); CloseHandle(Console->ActiveEvent);
return Status; return Status;
} }
@ -221,7 +221,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
{ {
ConioCleanupConsole(Console); ConioCleanupConsole(Console);
RtlFreeUnicodeString(&Console->Title); RtlFreeUnicodeString(&Console->Title);
RtlDeleteCriticalSection(&Console->Header.Lock); DeleteCriticalSection(&Console->Header.Lock);
CloseHandle(Console->ActiveEvent); CloseHandle(Console->ActiveEvent);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
@ -230,7 +230,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
{ {
ConioCleanupConsole(Console); ConioCleanupConsole(Console);
RtlFreeUnicodeString(&Console->Title); RtlFreeUnicodeString(&Console->Title);
RtlDeleteCriticalSection(&Console->Header.Lock); DeleteCriticalSection(&Console->Header.Lock);
CloseHandle(Console->ActiveEvent); CloseHandle(Console->ActiveEvent);
HeapFree(Win32CsrApiHeap, 0, NewBuffer); HeapFree(Win32CsrApiHeap, 0, NewBuffer);
return Status; return Status;
@ -956,7 +956,7 @@ VOID STDCALL
ConioDeleteScreenBuffer(Object_t *Object) ConioDeleteScreenBuffer(Object_t *Object)
{ {
PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object; PCSRSS_SCREEN_BUFFER Buffer = (PCSRSS_SCREEN_BUFFER) Object;
RtlDeleteCriticalSection(&Buffer->Header.Lock); DeleteCriticalSection(&Buffer->Header.Lock);
HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer); HeapFree(Win32CsrApiHeap, 0, Buffer->Buffer);
HeapFree(Win32CsrApiHeap, 0, Buffer); HeapFree(Win32CsrApiHeap, 0, Buffer);
} }
@ -998,7 +998,7 @@ ConioDeleteConsole(Object_t *Object)
ConioCleanupConsole(Console); ConioCleanupConsole(Console);
CloseHandle(Console->ActiveEvent); CloseHandle(Console->ActiveEvent);
RtlDeleteCriticalSection(&Console->Header.Lock); DeleteCriticalSection(&Console->Header.Lock);
RtlFreeUnicodeString(&Console->Title); RtlFreeUnicodeString(&Console->Title);
HeapFree(Win32CsrApiHeap, 0, Console); HeapFree(Win32CsrApiHeap, 0, Console);
} }

View file

@ -1,4 +1,4 @@
/* $Id: dllmain.c,v 1.9 2004/12/24 17:45:58 weiden Exp $ /* $Id$
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries

View file

@ -1,4 +1,4 @@
/* $Id: guiconsole.c,v 1.26 2004/12/25 11:22:37 navaraf Exp $ /* $Id$
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries