mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
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:
parent
a3e3b56cca
commit
352d524633
17 changed files with 542 additions and 370 deletions
|
@ -2082,8 +2082,6 @@ VOID STDCALL WEP();
|
|||
DWORD STDCALL RtlDeleteSecurityObject(DWORD x1);
|
||||
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 RtlpUnWaitCriticalSection(RTL_CRITICAL_SECTION *crit);
|
||||
NTSTATUS STDCALL RtlpWaitForCriticalSection(RTL_CRITICAL_SECTION *crit);
|
||||
NTSTATUS STDCALL LdrLockLoaderLock(ULONG flags, ULONG *result, ULONG *magic);
|
||||
NTSTATUS STDCALL LdrUnlockLoaderLock(ULONG flags, ULONG magic);
|
||||
|
||||
|
|
|
@ -99,8 +99,8 @@ typedef struct _CRITICAL_SECTION_DEBUG
|
|||
LIST_ENTRY ProcessLocksList;
|
||||
ULONG EntryCount;
|
||||
ULONG ContentionCount;
|
||||
ULONG Depth;
|
||||
PVOID Spare[ 2 ];
|
||||
PVOID OwnerBackTrace[2];
|
||||
PVOID Spare[2];
|
||||
} CRITICAL_SECTION_DEBUG, *PCRITICAL_SECTION_DEBUG;
|
||||
|
||||
|
||||
|
@ -114,9 +114,13 @@ typedef struct _CRITICAL_SECTION
|
|||
ULONG_PTR SpinCount;
|
||||
} CRITICAL_SECTION, *PCRITICAL_SECTION, *LPCRITICAL_SECTION;
|
||||
|
||||
#define RTL_CRITSECT_TYPE 0
|
||||
|
||||
typedef CRITICAL_SECTION RTL_CRITICAL_SECTION;
|
||||
typedef PCRITICAL_SECTION PRTL_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 */
|
||||
|
||||
|
@ -166,6 +170,29 @@ typedef struct _RTL_HANDLE_TABLE
|
|||
#define PDI_HEAP_BLOCKS 0x10 /* The heap blocks */
|
||||
#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
|
||||
RtlAddAccessAllowedAceEx (IN OUT PACL Acl,
|
||||
|
@ -191,19 +218,19 @@ RtlAddAuditAccessAceEx(IN OUT PACL Acl,
|
|||
IN BOOLEAN Failure);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlDeleteCriticalSection (PCRITICAL_SECTION CriticalSection);
|
||||
RtlDeleteCriticalSection (PRTL_CRITICAL_SECTION CriticalSection);
|
||||
|
||||
WCHAR STDCALL
|
||||
RtlDowncaseUnicodeChar(IN WCHAR Source);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlEnterCriticalSection (PCRITICAL_SECTION CriticalSection);
|
||||
RtlEnterCriticalSection (PRTL_CRITICAL_SECTION CriticalSection);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlInitializeCriticalSection (PCRITICAL_SECTION CriticalSection);
|
||||
RtlInitializeCriticalSection (PRTL_CRITICAL_SECTION CriticalSection);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlInitializeCriticalSectionAndSpinCount (PCRITICAL_SECTION CriticalSection,
|
||||
RtlInitializeCriticalSectionAndSpinCount (PRTL_CRITICAL_SECTION CriticalSection,
|
||||
ULONG SpinCount);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
|
@ -212,10 +239,10 @@ RtlInt64ToUnicodeString (IN ULONGLONG Value,
|
|||
PUNICODE_STRING String);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
RtlLeaveCriticalSection (PCRITICAL_SECTION CriticalSection);
|
||||
RtlLeaveCriticalSection (PRTL_CRITICAL_SECTION CriticalSection);
|
||||
|
||||
BOOLEAN STDCALL
|
||||
RtlTryEnterCriticalSection (PCRITICAL_SECTION CriticalSection);
|
||||
RtlTryEnterCriticalSection (PRTL_CRITICAL_SECTION CriticalSection);
|
||||
|
||||
DWORD STDCALL
|
||||
RtlCompactHeap (
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -24,7 +24,7 @@
|
|||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
static CRITICAL_SECTION HandleTableCS;
|
||||
static RTL_CRITICAL_SECTION HandleTableCS;
|
||||
static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES];
|
||||
static HANDLE ProcessHeap;
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ extern HANDLE hProcessHeap;
|
|||
extern HANDLE hBaseDir;
|
||||
extern HMODULE hCurrentModule;
|
||||
|
||||
extern CRITICAL_SECTION DllLock;
|
||||
extern RTL_CRITICAL_SECTION DllLock;
|
||||
|
||||
extern UNICODE_STRING DllDirectory;
|
||||
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -21,7 +21,7 @@
|
|||
|
||||
extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
|
||||
extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag);
|
||||
extern CRITICAL_SECTION ConsoleLock;
|
||||
extern RTL_CRITICAL_SECTION ConsoleLock;
|
||||
extern BOOL WINAPI IsDebuggerPresent(VOID);
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -33,8 +33,8 @@ DllMain(HANDLE hInst,
|
|||
LPVOID lpReserved);
|
||||
|
||||
/* Critical section for various kernel32 data structures */
|
||||
CRITICAL_SECTION DllLock;
|
||||
CRITICAL_SECTION ConsoleLock;
|
||||
RTL_CRITICAL_SECTION DllLock;
|
||||
RTL_CRITICAL_SECTION ConsoleLock;
|
||||
|
||||
extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
|
||||
|
||||
|
|
|
@ -82,15 +82,15 @@ typedef struct _NLS_FORMAT_NODE
|
|||
#define GetShortMonth(fmt,mth) fmt->lppszStrings[30 + mth]
|
||||
|
||||
/* Write access to the cache is protected by this critical section */
|
||||
static CRITICAL_SECTION NLS_FormatsCS;
|
||||
static CRITICAL_SECTION_DEBUG NLS_FormatsCS_debug =
|
||||
static RTL_CRITICAL_SECTION NLS_FormatsCS;
|
||||
static RTL_CRITICAL_SECTION_DEBUG NLS_FormatsCS_debug =
|
||||
{
|
||||
0, 0, &NLS_FormatsCS,
|
||||
{ &NLS_FormatsCS_debug.ProcessLocksList,
|
||||
&NLS_FormatsCS_debug.ProcessLocksList },
|
||||
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>
|
||||
|
|
|
@ -58,7 +58,7 @@ static const unsigned char UTF8Mask[6] = {0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01};
|
|||
static LIST_ENTRY CodePageListHead;
|
||||
static CODEPAGE_ENTRY AnsiCodePage;
|
||||
static CODEPAGE_ENTRY OemCodePage;
|
||||
static CRITICAL_SECTION CodePageListLock;
|
||||
static RTL_CRITICAL_SECTION CodePageListLock;
|
||||
|
||||
/* FORWARD DECLARATIONS *******************************************************/
|
||||
|
||||
|
|
|
@ -72,14 +72,14 @@ static PROFILE *MRUProfile[N_CACHED_PROFILES]={NULL};
|
|||
|
||||
static const WCHAR emptystringW[] = {0};
|
||||
|
||||
static CRITICAL_SECTION PROFILE_CritSect;
|
||||
static CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
static RTL_CRITICAL_SECTION PROFILE_CritSect;
|
||||
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
|
||||
{
|
||||
0, 0, &PROFILE_CritSect,
|
||||
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
|
||||
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";
|
||||
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -26,7 +26,7 @@ InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
|
|||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = RtlInitializeCriticalSection(lpCriticalSection);
|
||||
Status = RtlInitializeCriticalSection((PRTL_CRITICAL_SECTION)lpCriticalSection);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlRaiseStatus(Status);
|
||||
|
@ -45,7 +45,7 @@ InitializeCriticalSectionAndSpinCount(
|
|||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = RtlInitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount);
|
||||
Status = RtlInitializeCriticalSectionAndSpinCount((PRTL_CRITICAL_SECTION)lpCriticalSection, dwSpinCount);
|
||||
if (Status)
|
||||
{
|
||||
RtlRaiseStatus(Status);
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -259,6 +259,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
|
|||
/* If MZ header exists */
|
||||
PEDosHeader = (PIMAGE_DOS_HEADER) ImageBase;
|
||||
DPRINT("PEDosHeader %x\n", PEDosHeader);
|
||||
|
||||
if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC ||
|
||||
PEDosHeader->e_lfanew == 0L ||
|
||||
*(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);
|
||||
|
||||
/* Initialize Critical Section Data */
|
||||
RtlpInitDeferedCriticalSection();
|
||||
|
||||
/* create process heap */
|
||||
RtlInitializeHeapManager();
|
||||
Peb->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE,
|
||||
|
@ -292,7 +296,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
|
|||
DPRINT1("Failed to create process heap\n");
|
||||
ZwTerminateProcess(NtCurrentProcess(),STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
|
||||
/* initalize peb lock support */
|
||||
RtlInitializeCriticalSection (&PebLock);
|
||||
Peb->FastPebLock = &PebLock;
|
||||
|
@ -311,7 +315,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
|
|||
RtlAllocateHeap(RtlGetProcessHeap(),
|
||||
0,
|
||||
sizeof(PVOID) * (USER32_CALLBACK_MAXIMUM + 1));
|
||||
|
||||
|
||||
/* initalize loader lock */
|
||||
RtlInitializeCriticalSection (&LoaderLock);
|
||||
Peb->LoaderLock = &LoaderLock;
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
* PURPOSE: Critical sections
|
||||
* UPDATE HISTORY:
|
||||
* Created 30/09/98
|
||||
* Rewritten ROS version, based on WINE code plus
|
||||
* some fixes useful only for ROS right now - 03/01/05
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
@ -19,391 +21,532 @@
|
|||
|
||||
/* 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)
|
||||
{
|
||||
#ifdef __i386__
|
||||
__asm__ __volatile__( "rep;nop" : : : "memory" );
|
||||
#else
|
||||
__asm__ __volatile__( "" : : : "memory" );
|
||||
#endif
|
||||
/*++
|
||||
* RtlSetCriticalSectionSpinCount
|
||||
* @implemented NT4
|
||||
*
|
||||
* Sets the spin count for a critical section.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
static inline HANDLE get_semaphore( PCRITICAL_SECTION crit )
|
||||
/*++
|
||||
* RtlEnterCriticalSection
|
||||
* @implemented NT4
|
||||
*
|
||||
* 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;
|
||||
if (!ret)
|
||||
{
|
||||
HANDLE sem;
|
||||
if (!NT_SUCCESS(NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 ))) return 0;
|
||||
if (!(ret = (HANDLE)InterlockedCompareExchangePointer( (PVOID *)&crit->LockSemaphore,
|
||||
(PVOID)sem, 0 )))
|
||||
ret = sem;
|
||||
else
|
||||
NtClose(sem); /* somebody beat us to it */
|
||||
}
|
||||
return ret;
|
||||
HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread;
|
||||
|
||||
/* Try to Lock it */
|
||||
if (InterlockedIncrement(&CriticalSection->LockCount)) {
|
||||
|
||||
/*
|
||||
* We've failed to lock it! Does this thread
|
||||
* actually own it?
|
||||
*/
|
||||
if (Thread == CriticalSection->OwningThread) {
|
||||
|
||||
/* 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
|
||||
* crit [O] Critical section to initialise
|
||||
* Params:
|
||||
* CriticalSection - Critical section to initialise
|
||||
*
|
||||
* RETURNS
|
||||
* STATUS_SUCCESS.
|
||||
* Returns:
|
||||
* STATUS_SUCCESS.
|
||||
*
|
||||
* SEE
|
||||
* RtlInitializeCriticalSectionAndSpinCount(), RtlDeleteCriticalSection(),
|
||||
* RtlEnterCriticalSection(), RtlLeaveCriticalSection(),
|
||||
* RtlTryEnterCriticalSection(), RtlSetCriticalSectionSpinCount()
|
||||
*/
|
||||
NTSTATUS STDCALL RtlInitializeCriticalSection( PCRITICAL_SECTION crit )
|
||||
{
|
||||
return RtlInitializeCriticalSectionAndSpinCount( crit, 0 );
|
||||
* Remarks:
|
||||
* Simply calls RtlInitializeCriticalSectionAndSpinCount
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlInitializeCriticalSection(
|
||||
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
|
||||
* crit [O] Critical section to initialise
|
||||
* spincount [I] Spin count for crit
|
||||
*
|
||||
* RETURNS
|
||||
* STATUS_SUCCESS.
|
||||
* Params:
|
||||
* CriticalSection - Critical section to initialise
|
||||
*
|
||||
* NOTES
|
||||
* Available on NT4 SP3 or later.
|
||||
* SpinCount - Spin count for the critical section.
|
||||
*
|
||||
* SEE
|
||||
* RtlInitializeCriticalSection(), RtlDeleteCriticalSection(),
|
||||
* RtlEnterCriticalSection(), RtlLeaveCriticalSection(),
|
||||
* RtlTryEnterCriticalSection(), RtlSetCriticalSectionSpinCount()
|
||||
*/
|
||||
NTSTATUS STDCALL RtlInitializeCriticalSectionAndSpinCount( PCRITICAL_SECTION crit, ULONG spincount )
|
||||
* Returns:
|
||||
* STATUS_SUCCESS.
|
||||
*
|
||||
* Remarks:
|
||||
* SpinCount is ignored on single-processor systems.
|
||||
*
|
||||
*--*/
|
||||
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
|
||||
it be enabled in the release build? -Gunnar */
|
||||
if (RtlGetProcessHeap()) crit->DebugInfo = NULL;
|
||||
else
|
||||
{
|
||||
crit->DebugInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(CRITICAL_SECTION_DEBUG));
|
||||
if (crit->DebugInfo)
|
||||
{
|
||||
crit->DebugInfo->Type = 0;
|
||||
crit->DebugInfo->CreatorBackTraceIndex = 0;
|
||||
crit->DebugInfo->CriticalSection = crit;
|
||||
crit->DebugInfo->ProcessLocksList.Blink = &(crit->DebugInfo->ProcessLocksList);
|
||||
crit->DebugInfo->ProcessLocksList.Flink = &(crit->DebugInfo->ProcessLocksList);
|
||||
crit->DebugInfo->EntryCount = 0;
|
||||
crit->DebugInfo->ContentionCount = 0;
|
||||
crit->DebugInfo->Spare[0] = 0;
|
||||
crit->DebugInfo->Spare[1] = 0;
|
||||
}
|
||||
}
|
||||
crit->LockCount = -1;
|
||||
crit->RecursionCount = 0;
|
||||
crit->OwningThread = 0;
|
||||
crit->LockSemaphore = 0;
|
||||
crit->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? spincount : 0;
|
||||
return STATUS_SUCCESS;
|
||||
PRTL_CRITICAL_SECTION_DEBUG CritcalSectionDebugData;
|
||||
PVOID Heap;
|
||||
|
||||
/* First things first, set up the Object */
|
||||
CriticalSection->LockCount = -1;
|
||||
CriticalSection->RecursionCount = 0;
|
||||
CriticalSection->OwningThread = 0;
|
||||
CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
|
||||
|
||||
/*
|
||||
* Now set up the Debug Data
|
||||
* Think of a better way to allocate it, because the Heap Manager won't
|
||||
* have any debug data since the Heap isn't initalized!
|
||||
*/
|
||||
if ((Heap = RtlGetProcessHeap())) {
|
||||
|
||||
CritcalSectionDebugData = RtlAllocateHeap(Heap, 0, sizeof(RTL_CRITICAL_SECTION_DEBUG));
|
||||
CritcalSectionDebugData->Type = RTL_CRITSECT_TYPE;
|
||||
CritcalSectionDebugData->ContentionCount = 0;
|
||||
CritcalSectionDebugData->EntryCount = 0;
|
||||
CritcalSectionDebugData->CriticalSection = CriticalSection;
|
||||
CriticalSection->DebugInfo = CritcalSectionDebugData;
|
||||
|
||||
/*
|
||||
* 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
|
||||
* crit [I/O] Critical section
|
||||
* spincount [I] Spin count for crit
|
||||
* Params:
|
||||
* CriticalSection - Critical section to release.
|
||||
*
|
||||
* RETURNS
|
||||
* The previous spin count.
|
||||
* Returns:
|
||||
* STATUS_SUCCESS.
|
||||
*
|
||||
* NOTES
|
||||
* If the system is not SMP, spincount is ignored and set to 0.
|
||||
* Remarks:
|
||||
* If another thread was waiting, the slow path is entered.
|
||||
*
|
||||
* SEE
|
||||
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(),
|
||||
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(),
|
||||
* RtlLeaveCriticalSection(), RtlTryEnterCriticalSection()
|
||||
*/
|
||||
ULONG STDCALL RtlSetCriticalSectionSpinCount( PCRITICAL_SECTION crit, ULONG spincount )
|
||||
{
|
||||
ULONG oldspincount = crit->SpinCount;
|
||||
crit->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? spincount : 0;
|
||||
return oldspincount;
|
||||
*--*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlLeaveCriticalSection(
|
||||
PRTL_CRITICAL_SECTION CriticalSection)
|
||||
{
|
||||
/* Decrease the Recursion Count */
|
||||
if (--CriticalSection->RecursionCount) {
|
||||
|
||||
/* 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
|
||||
* crit [I/O] Critical section to free
|
||||
* Params:
|
||||
* CriticalSection - Critical section to attempt acquiring.
|
||||
*
|
||||
* RETURNS
|
||||
* STATUS_SUCCESS.
|
||||
* Returns:
|
||||
* TRUE if the critical section has been acquired, FALSE otherwise.
|
||||
*
|
||||
* SEE
|
||||
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(),
|
||||
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(),
|
||||
* RtlLeaveCriticalSection(), RtlTryEnterCriticalSection()
|
||||
*/
|
||||
NTSTATUS STDCALL RtlDeleteCriticalSection( PCRITICAL_SECTION crit )
|
||||
{
|
||||
crit->LockCount = -1;
|
||||
crit->RecursionCount = 0;
|
||||
crit->OwningThread = (HANDLE)0;
|
||||
if (crit->LockSemaphore)
|
||||
NtClose( crit->LockSemaphore );
|
||||
crit->LockSemaphore = 0;
|
||||
if (crit->DebugInfo)
|
||||
{
|
||||
/* only free the ones we made in here */
|
||||
if (!crit->DebugInfo->Spare[1])
|
||||
{
|
||||
RtlFreeHeap( RtlGetProcessHeap(), 0, crit->DebugInfo );
|
||||
crit->DebugInfo = NULL;
|
||||
}
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
* Remarks:
|
||||
* None
|
||||
*
|
||||
*--*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
RtlTryEnterCriticalSection(
|
||||
PRTL_CRITICAL_SECTION CriticalSection)
|
||||
{
|
||||
/* Try to take control */
|
||||
if (InterlockedCompareExchange(&CriticalSection->LockCount,
|
||||
0,
|
||||
-1) == -1) {
|
||||
|
||||
/* It's ours */
|
||||
CriticalSection->OwningThread = NtCurrentTeb()->Cid.UniqueThread;
|
||||
CriticalSection->RecursionCount = 1;
|
||||
return TRUE;
|
||||
|
||||
} else if (CriticalSection->OwningThread == NtCurrentTeb()->Cid.UniqueThread) {
|
||||
|
||||
/* It's already ours */
|
||||
InterlockedIncrement(&CriticalSection->LockCount);
|
||||
CriticalSection->RecursionCount++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* It's not ours */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RtlpWaitForCriticalSection (NTDLL.@)
|
||||
/*++
|
||||
* RtlpWaitForCriticalSection
|
||||
*
|
||||
* Waits for a busy critical section to become free.
|
||||
*
|
||||
* PARAMS
|
||||
* crit [I/O] Critical section to wait for
|
||||
* Slow path of RtlEnterCriticalSection. Waits on an Event Object.
|
||||
*
|
||||
* RETURNS
|
||||
* STATUS_SUCCESS.
|
||||
* Params:
|
||||
* CriticalSection - Critical section to acquire.
|
||||
*
|
||||
* NOTES
|
||||
* Use RtlEnterCriticalSection() instead of this function as it is often much
|
||||
* faster.
|
||||
* Returns:
|
||||
* STATUS_SUCCESS, or raises an exception if a deadlock is occuring.
|
||||
*
|
||||
* SEE
|
||||
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(),
|
||||
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(),
|
||||
* RtlLeaveCriticalSection(), RtlTryEnterCriticalSection()
|
||||
*/
|
||||
NTSTATUS STDCALL RtlpWaitForCriticalSection( PCRITICAL_SECTION crit )
|
||||
* Remarks:
|
||||
* None
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
RtlpWaitForCriticalSection(
|
||||
PRTL_CRITICAL_SECTION CriticalSection)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
EXCEPTION_RECORD rec;
|
||||
HANDLE sem = get_semaphore( crit );
|
||||
LARGE_INTEGER time;
|
||||
NTSTATUS status;
|
||||
|
||||
time.QuadPart = -5000 * 10000; /* 5 seconds */
|
||||
status = NtWaitForSingleObject( sem, FALSE, &time );
|
||||
if ( status == STATUS_TIMEOUT )
|
||||
{
|
||||
const char *name = NULL;
|
||||
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",
|
||||
crit, name, RtlGetCurrentThreadId(), (DWORD)crit->OwningThread );
|
||||
time.QuadPart = -60000 * 10000;
|
||||
status = NtWaitForSingleObject( sem, FALSE, &time );
|
||||
if ( status == STATUS_TIMEOUT /*&& TRACE_ON(relay)*/ )
|
||||
{
|
||||
DPRINT1( "section %p %s wait timed out in thread %04lx, blocked by %04lx, retrying (5 min)\n",
|
||||
crit, name, RtlGetCurrentThreadId(), (DWORD) crit->OwningThread );
|
||||
time.QuadPart = -300000 * (ULONGLONG)10000;
|
||||
status = NtWaitForSingleObject( sem, FALSE, &time );
|
||||
}
|
||||
}
|
||||
if (status == STATUS_WAIT_0) return STATUS_SUCCESS;
|
||||
|
||||
/* Throw exception only for Wine internal locks */
|
||||
if ((!crit->DebugInfo) || (!crit->DebugInfo->Spare[1])) continue;
|
||||
|
||||
rec.ExceptionCode = STATUS_POSSIBLE_DEADLOCK;
|
||||
rec.ExceptionFlags = 0;
|
||||
rec.ExceptionRecord = NULL;
|
||||
rec.ExceptionAddress = RtlRaiseException; /* sic */
|
||||
rec.NumberParameters = 1;
|
||||
rec.ExceptionInformation[0] = (DWORD)crit;
|
||||
RtlRaiseException( &rec );
|
||||
}
|
||||
NTSTATUS Status;
|
||||
EXCEPTION_RECORD ExceptionRecord;
|
||||
BOOLEAN LastChance = FALSE;
|
||||
LARGE_INTEGER Timeout;
|
||||
|
||||
Timeout = RtlConvertLongToLargeInteger(150000);
|
||||
/* ^^ HACK HACK HACK. Good way:
|
||||
Timeout = &NtCurrentPeb()->CriticalSectionTimeout */
|
||||
|
||||
/* Do we have an Event yet? */
|
||||
if (!CriticalSection->LockSemaphore) {
|
||||
RtlpCreateCriticalSectionSem(CriticalSection);
|
||||
}
|
||||
|
||||
/* Increase the Debug Entry count */
|
||||
CriticalSection->DebugInfo->EntryCount++;
|
||||
|
||||
for (;;) {
|
||||
|
||||
/* Increase the number of times we've had contention */
|
||||
CriticalSection->DebugInfo->ContentionCount++;
|
||||
|
||||
/* Wait on the Event */
|
||||
Status = NtWaitForSingleObject(CriticalSection->LockSemaphore,
|
||||
FALSE,
|
||||
&Timeout);
|
||||
|
||||
/* We have Timed out */
|
||||
if (Status == STATUS_TIMEOUT) {
|
||||
|
||||
/* Is this the 2nd time we've timed out? */
|
||||
if (LastChance) {
|
||||
|
||||
/* Yes it is, we are raising an exception */
|
||||
ExceptionRecord.ExceptionCode = STATUS_POSSIBLE_DEADLOCK;
|
||||
ExceptionRecord.ExceptionFlags = 0;
|
||||
ExceptionRecord.ExceptionRecord = NULL;
|
||||
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 (NTDLL.@)
|
||||
/*++
|
||||
* RtlpUnWaitCriticalSection
|
||||
*
|
||||
* Notifies other threads waiting on the busy critical section that it has
|
||||
* become free.
|
||||
*
|
||||
* PARAMS
|
||||
* crit [I/O] Critical section
|
||||
* Slow path of RtlLeaveCriticalSection. Fires an Event Object.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: STATUS_SUCCESS.
|
||||
* Failure: Any error returned by NtReleaseSemaphore()
|
||||
* Params:
|
||||
* CriticalSection - Critical section to release.
|
||||
*
|
||||
* NOTES
|
||||
* Use RtlLeaveCriticalSection() instead of this function as it is often much
|
||||
* faster.
|
||||
* Returns:
|
||||
* None. Raises an exception if the system call failed.
|
||||
*
|
||||
* SEE
|
||||
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(),
|
||||
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(),
|
||||
* RtlLeaveCriticalSection(), RtlTryEnterCriticalSection()
|
||||
*/
|
||||
NTSTATUS STDCALL RtlpUnWaitCriticalSection( PCRITICAL_SECTION crit )
|
||||
* Remarks:
|
||||
* None
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
STDCALL
|
||||
RtlpUnWaitCriticalSection(
|
||||
PRTL_CRITICAL_SECTION CriticalSection)
|
||||
|
||||
{
|
||||
HANDLE sem = get_semaphore( crit );
|
||||
NTSTATUS res = NtReleaseSemaphore( sem, 1, NULL );
|
||||
if (!NT_SUCCESS(res)) RtlRaiseStatus( res );
|
||||
return res;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Do we have an Event yet? */
|
||||
if (!CriticalSection->LockSemaphore) {
|
||||
RtlpCreateCriticalSectionSem(CriticalSection);
|
||||
}
|
||||
|
||||
/* Signal the Event */
|
||||
Status = NtSetEvent(CriticalSection->LockSemaphore, NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
|
||||
/* We've failed */
|
||||
RtlRaiseStatus(Status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RtlEnterCriticalSection (NTDLL.@)
|
||||
/*++
|
||||
* RtlpCreateCriticalSectionSem
|
||||
*
|
||||
* Enters a critical section, waiting for it to become available if necessary.
|
||||
* Checks if an Event has been created for the critical section.
|
||||
*
|
||||
* PARAMS
|
||||
* crit [I/O] Critical section to enter
|
||||
* Params:
|
||||
* None
|
||||
*
|
||||
* RETURNS
|
||||
* STATUS_SUCCESS. The critical section is held by the caller.
|
||||
*
|
||||
* SEE
|
||||
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(),
|
||||
* RtlDeleteCriticalSection(), RtlSetCriticalSectionSpinCount(),
|
||||
* RtlLeaveCriticalSection(), RtlTryEnterCriticalSection()
|
||||
*/
|
||||
NTSTATUS STDCALL RtlEnterCriticalSection( PCRITICAL_SECTION crit )
|
||||
* Returns:
|
||||
* None. Raises an exception if the system call failed.
|
||||
*
|
||||
* Remarks:
|
||||
* None
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
STDCALL
|
||||
RtlpCreateCriticalSectionSem(
|
||||
PRTL_CRITICAL_SECTION CriticalSection)
|
||||
{
|
||||
if (crit->SpinCount)
|
||||
{
|
||||
ULONG count;
|
||||
|
||||
if (RtlTryEnterCriticalSection( crit )) return STATUS_SUCCESS;
|
||||
for (count = crit->SpinCount; count > 0; count--)
|
||||
{
|
||||
if (crit->LockCount > 0) break; /* more than one waiter, don't bother spinning */
|
||||
if (crit->LockCount == -1) /* try again */
|
||||
{
|
||||
if (InterlockedCompareExchange(&crit->LockCount, 0,-1 ) == -1) goto done;
|
||||
}
|
||||
small_pause();
|
||||
}
|
||||
}
|
||||
|
||||
if (InterlockedIncrement( &crit->LockCount ))
|
||||
{
|
||||
if (crit->OwningThread == (HANDLE)RtlGetCurrentThreadId())
|
||||
{
|
||||
crit->RecursionCount++;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Now wait for it */
|
||||
RtlpWaitForCriticalSection( crit );
|
||||
}
|
||||
done:
|
||||
crit->OwningThread = (HANDLE)RtlGetCurrentThreadId();
|
||||
crit->RecursionCount = 1;
|
||||
return STATUS_SUCCESS;
|
||||
HANDLE hEvent = CriticalSection->LockSemaphore;
|
||||
HANDLE hNewEvent;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Chevk if we have an event */
|
||||
if (!hEvent) {
|
||||
|
||||
/* No, so create it */
|
||||
if (NT_SUCCESS(Status = NtCreateEvent(hNewEvent,
|
||||
EVENT_ALL_ACCESS,
|
||||
NULL,
|
||||
SynchronizationEvent,
|
||||
FALSE))) {
|
||||
|
||||
/* We failed, this is bad... */
|
||||
InterlockedDecrement(&CriticalSection->LockCount);
|
||||
RtlRaiseStatus(Status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(hEvent = InterlockedCompareExchangePointer((PVOID*)&CriticalSection->LockSemaphore,
|
||||
(PVOID)hNewEvent,
|
||||
0))) {
|
||||
|
||||
/* We created a new event succesffuly */
|
||||
hEvent = hNewEvent;
|
||||
} else {
|
||||
|
||||
/* Some just created an event */
|
||||
NtClose(hNewEvent);
|
||||
}
|
||||
|
||||
/* Set either the new or the old */
|
||||
CriticalSection->LockSemaphore = hEvent;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* RtlTryEnterCriticalSection (NTDLL.@)
|
||||
/*++
|
||||
* RtlpInitDeferedCriticalSection
|
||||
*
|
||||
* Tries to enter a critical section without waiting.
|
||||
* Initializes the Critical Section implementation.
|
||||
*
|
||||
* PARAMS
|
||||
* crit [I/O] Critical section to enter
|
||||
* Params:
|
||||
* None
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE. The critical section is held by the caller.
|
||||
* Failure: FALSE. The critical section is currently held by another thread.
|
||||
* Returns:
|
||||
* None.
|
||||
*
|
||||
* SEE
|
||||
* RtlInitializeCriticalSection(), RtlInitializeCriticalSectionAndSpinCount(),
|
||||
* RtlDeleteCriticalSection(), RtlEnterCriticalSection(),
|
||||
* RtlLeaveCriticalSection(), RtlSetCriticalSectionSpinCount()
|
||||
*/
|
||||
BOOLEAN STDCALL RtlTryEnterCriticalSection( PCRITICAL_SECTION crit )
|
||||
* Remarks:
|
||||
* After this call, the Process Critical Section list is protected.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
STDCALL
|
||||
RtlpInitDeferedCriticalSection(
|
||||
VOID)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
if (InterlockedCompareExchange(&crit->LockCount, 0L, -1 ) == -1)
|
||||
{
|
||||
crit->OwningThread = (HANDLE)RtlGetCurrentThreadId();
|
||||
crit->RecursionCount = 1;
|
||||
ret = TRUE;
|
||||
}
|
||||
else if (crit->OwningThread == (HANDLE)RtlGetCurrentThreadId())
|
||||
{
|
||||
InterlockedIncrement( &crit->LockCount );
|
||||
crit->RecursionCount++;
|
||||
ret = TRUE;
|
||||
}
|
||||
return ret;
|
||||
|
||||
/* Initialize the Process Critical Section List */
|
||||
InitializeListHead(&RtlCriticalSectionList);
|
||||
|
||||
/* Initialize the CS Protecting the List */
|
||||
RtlInitializeCriticalSection(&RtlCriticalSectionLock);
|
||||
|
||||
/* It's now safe to enter it */
|
||||
RtlpCritSectInitialized = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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 */
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
@ -25,7 +25,7 @@
|
|||
|
||||
static ULONG NrProcess;
|
||||
static PCSRSS_PROCESS_DATA ProcessData[256];
|
||||
CRITICAL_SECTION ProcessDataLock;
|
||||
RTL_CRITICAL_SECTION ProcessDataLock;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
@ -139,7 +139,7 @@ CsrInitConsoleScreenBuffer(PCSRSS_CONSOLE Console,
|
|||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
RtlInitializeCriticalSection(&Buffer->Header.Lock);
|
||||
InitializeCriticalSection(&Buffer->Header.Lock);
|
||||
ConioInitScreenBuffer(Console, Buffer);
|
||||
/* initialize buffer to be empty with default attributes */
|
||||
for (Buffer->CurrentY = 0 ; Buffer->CurrentY < Buffer->MaxY; Buffer->CurrentY++)
|
||||
|
@ -193,7 +193,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
Console->PrivateData = NULL;
|
||||
RtlInitializeCriticalSection(&Console->Header.Lock);
|
||||
InitializeCriticalSection(&Console->Header.Lock);
|
||||
GuiMode = DtbgIsDesktopVisible();
|
||||
if (! GuiMode)
|
||||
{
|
||||
|
@ -210,7 +210,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
|
|||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
RtlFreeUnicodeString(&Console->Title);
|
||||
RtlDeleteCriticalSection(&Console->Header.Lock);
|
||||
DeleteCriticalSection(&Console->Header.Lock);
|
||||
CloseHandle(Console->ActiveEvent);
|
||||
return Status;
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
|
|||
{
|
||||
ConioCleanupConsole(Console);
|
||||
RtlFreeUnicodeString(&Console->Title);
|
||||
RtlDeleteCriticalSection(&Console->Header.Lock);
|
||||
DeleteCriticalSection(&Console->Header.Lock);
|
||||
CloseHandle(Console->ActiveEvent);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
@ -230,7 +230,7 @@ CsrInitConsole(PCSRSS_CONSOLE Console)
|
|||
{
|
||||
ConioCleanupConsole(Console);
|
||||
RtlFreeUnicodeString(&Console->Title);
|
||||
RtlDeleteCriticalSection(&Console->Header.Lock);
|
||||
DeleteCriticalSection(&Console->Header.Lock);
|
||||
CloseHandle(Console->ActiveEvent);
|
||||
HeapFree(Win32CsrApiHeap, 0, NewBuffer);
|
||||
return Status;
|
||||
|
@ -956,7 +956,7 @@ VOID STDCALL
|
|||
ConioDeleteScreenBuffer(Object_t *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);
|
||||
}
|
||||
|
@ -998,7 +998,7 @@ ConioDeleteConsole(Object_t *Object)
|
|||
ConioCleanupConsole(Console);
|
||||
|
||||
CloseHandle(Console->ActiveEvent);
|
||||
RtlDeleteCriticalSection(&Console->Header.Lock);
|
||||
DeleteCriticalSection(&Console->Header.Lock);
|
||||
RtlFreeUnicodeString(&Console->Title);
|
||||
HeapFree(Win32CsrApiHeap, 0, Console);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
|
Loading…
Reference in a new issue