ReactOS 0.4.16-dev-752-g47bae01
critical.c File Reference
#include <rtl.h>
#include <debug.h>
Include dependency graph for critical.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MAX_STATIC_CS_DEBUG_OBJECTS   64
 
#define CRITSECT_HAS_DEBUG_INFO(CriticalSection)
 

Functions

 _At_ (CriticalSection->LockSemaphore, _Post_notnull_) VOID NTAPI RtlpCreateCriticalSectionSem(PRTL_CRITICAL_SECTION CriticalSection)
 
NTSTATUS NTAPI RtlpWaitForCriticalSection (PRTL_CRITICAL_SECTION CriticalSection)
 
VOID NTAPI RtlpUnWaitCriticalSection (PRTL_CRITICAL_SECTION CriticalSection)
 
VOID NTAPI RtlpInitDeferredCriticalSection (VOID)
 
PRTL_CRITICAL_SECTION_DEBUG NTAPI RtlpAllocateDebugInfo (VOID)
 
VOID NTAPI RtlpFreeDebugInfo (PRTL_CRITICAL_SECTION_DEBUG DebugInfo)
 
NTSTATUS NTAPI RtlDeleteCriticalSection (PRTL_CRITICAL_SECTION CriticalSection)
 
ULONG NTAPI RtlSetCriticalSectionSpinCount (PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount)
 
NTSTATUS NTAPI RtlEnterCriticalSection (PRTL_CRITICAL_SECTION CriticalSection)
 
NTSTATUS NTAPI RtlInitializeCriticalSection (PRTL_CRITICAL_SECTION CriticalSection)
 
NTSTATUS NTAPI RtlInitializeCriticalSectionEx (_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount, _In_ ULONG Flags)
 
NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount (_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount)
 
LONG NTAPI RtlGetCriticalSectionRecursionCount (PRTL_CRITICAL_SECTION CriticalSection)
 
NTSTATUS NTAPI RtlLeaveCriticalSection (PRTL_CRITICAL_SECTION CriticalSection)
 
BOOLEAN NTAPI RtlTryEnterCriticalSection (PRTL_CRITICAL_SECTION CriticalSection)
 
VOID NTAPI RtlCheckForOrphanedCriticalSections (HANDLE ThreadHandle)
 
ULONG NTAPI RtlIsCriticalSectionLocked (PRTL_CRITICAL_SECTION CriticalSection)
 
ULONG NTAPI RtlIsCriticalSectionLockedByThread (PRTL_CRITICAL_SECTION CriticalSection)
 
VOID NTAPI RtlpNotOwnerCriticalSection (PRTL_CRITICAL_SECTION CriticalSection)
 

Variables

static RTL_CRITICAL_SECTION RtlCriticalSectionLock
 
static LIST_ENTRY RtlCriticalSectionList = {&RtlCriticalSectionList, &RtlCriticalSectionList}
 
static BOOLEAN RtlpCritSectInitialized = FALSE
 
static RTL_CRITICAL_SECTION_DEBUG RtlpStaticDebugInfo [MAX_STATIC_CS_DEBUG_OBJECTS]
 
static BOOLEAN RtlpDebugInfoFreeList [MAX_STATIC_CS_DEBUG_OBJECTS]
 
LARGE_INTEGER RtlpTimeout
 
BOOLEAN RtlpTimeoutDisable
 
BOOLEAN LdrpShutdownInProgress
 
HANDLE LdrpShutdownThreadId
 

Macro Definition Documentation

◆ CRITSECT_HAS_DEBUG_INFO

#define CRITSECT_HAS_DEBUG_INFO (   CriticalSection)
Value:
(((CriticalSection)->DebugInfo != NULL) && \
((CriticalSection)->DebugInfo != LongToPtr(-1)))
#define LongToPtr(l)
Definition: basetsd.h:91
#define NULL
Definition: types.h:112
CRITICAL_SECTION CriticalSection
Definition: iprtprio.c:40

Definition at line 33 of file critical.c.

◆ MAX_STATIC_CS_DEBUG_OBJECTS

#define MAX_STATIC_CS_DEBUG_OBJECTS   64

Definition at line 17 of file critical.c.

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file critical.c.

Function Documentation

◆ _At_()

_At_ ( CriticalSection->  LockSemaphore,
_Post_notnull_   
)

Definition at line 52 of file critical.c.

56{
58 HANDLE hNewEvent;
60
61 /* Check if we have an event */
62 if (!hEvent)
63 {
64 /* No, so create it */
65 Status = NtCreateEvent(&hNewEvent,
67 NULL,
69 FALSE);
70 if (!NT_SUCCESS(Status))
71 {
72 DPRINT1("Failed to Create Event!\n");
73
74 /*
75 * Use INVALID_HANDLE_VALUE (-1) to signal that
76 * the global keyed event must be used.
77 */
78 hNewEvent = INVALID_HANDLE_VALUE;
79 }
80
81 DPRINT("Created Event: %p\n", hNewEvent);
82
83 /* Exchange the LockSemaphore field with the new handle, if it is still 0 */
85 (PVOID)hNewEvent,
86 NULL) != NULL)
87 {
88 /* Someone else just created an event */
89 if (hNewEvent != INVALID_HANDLE_VALUE)
90 {
91 DPRINT("Closing already created event: %p\n", hNewEvent);
92 NtClose(hNewEvent);
93 }
94 }
95 }
96
97 return;
98}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
Status
Definition: gdiplustypes.h:25
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
static HANDLE hEvent
Definition: comm.c:54
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
@ SynchronizationEvent
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
#define DPRINT
Definition: sndvol32.h:73
HANDLE LockSemaphore
Definition: winbase.h:923

◆ RtlCheckForOrphanedCriticalSections()

VOID NTAPI RtlCheckForOrphanedCriticalSections ( HANDLE  ThreadHandle)

Definition at line 861 of file critical.c.

862{
864}
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15

◆ RtlDeleteCriticalSection()

NTSTATUS NTAPI RtlDeleteCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 397 of file critical.c.

398{
400
401 DPRINT("Deleting Critical Section: %p\n", CriticalSection);
402
403 /* Close the Event Object Handle if it exists */
405 {
406 /* In case NtClose fails, return the status */
408 }
409
410 /* Protect List */
412
414 {
415 /* Remove it from the list */
417#if 0
418 /* We need to preserve Flags for RtlpFreeDebugInfo */
420#endif
421 }
422
423 /* Unprotect */
425
427 {
428 /* Free it */
430 }
431
432 /* Wipe it out */
434
435 /* Return */
436 return Status;
437}
NTSTATUS NTAPI RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:766
#define CRITSECT_HAS_DEBUG_INFO(CriticalSection)
Definition: critical.c:33
static RTL_CRITICAL_SECTION RtlCriticalSectionLock
Definition: critical.c:19
VOID NTAPI RtlpFreeDebugInfo(PRTL_CRITICAL_SECTION_DEBUG DebugInfo)
Definition: critical.c:342
NTSTATUS NTAPI RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:487
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define STATUS_SUCCESS
Definition: shellext.h:65
LIST_ENTRY ProcessLocksList
Definition: winbase.h:908
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:919
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

◆ RtlEnterCriticalSection()

NTSTATUS NTAPI RtlEnterCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 487 of file critical.c.

488{
489 HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread;
490
491 /* Try to lock it */
493 {
494 /* We've failed to lock it! Does this thread actually own it? */
496 {
497 /*
498 * You own it, so you'll get it when you're done with it! No need to
499 * use the interlocked functions as only the thread who already owns
500 * the lock can modify this data.
501 */
503 return STATUS_SUCCESS;
504 }
505
506 /* NOTE - CriticalSection->OwningThread can be NULL here because changing
507 this information is not serialized. This happens when thread a
508 acquires the lock (LockCount == 0) and thread b tries to
509 acquire it as well (LockCount == 1) but thread a hasn't had a
510 chance to set the OwningThread! So it's not an error when
511 OwningThread is NULL here! */
512
513 /* We don't own it, so we must wait for it */
515 }
516
517 /*
518 * Lock successful. Changing this information has not to be serialized
519 * because only one thread at a time can actually change it (the one who
520 * acquired the lock)!
521 */
524 NtCurrentTeb()->CountOfOwnedCriticalSections++;
525 return STATUS_SUCCESS;
526}
#define InterlockedIncrement
Definition: armddk.h:53
NTSTATUS NTAPI RtlpWaitForCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:117
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define NtCurrentTeb
LONG RecursionCount
Definition: winbase.h:921
HANDLE OwningThread
Definition: winbase.h:922
PVOID HANDLE
Definition: typedefs.h:73

Referenced by RtlDeleteCriticalSection(), and RtlInitializeCriticalSectionEx().

◆ RtlGetCriticalSectionRecursionCount()

LONG NTAPI RtlGetCriticalSectionRecursionCount ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 728 of file critical.c.

729{
731 {
732 /*
733 * The critical section is owned by the current thread,
734 * therefore retrieve its actual recursion count.
735 */
737 }
738 else
739 {
740 /*
741 * It is not owned by the current thread, so
742 * for this thread there is no recursion.
743 */
744 return 0;
745 }
746}
HANDLE UniqueThread
Definition: compat.h:826
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151

◆ RtlInitializeCriticalSection()

NTSTATUS NTAPI RtlInitializeCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 546 of file critical.c.

547{
548 /* Call the Main Function */
550}
NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount(_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount)
Definition: critical.c:701

Referenced by RtlpInitDeferredCriticalSection().

◆ RtlInitializeCriticalSectionAndSpinCount()

NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount ( _Out_ PRTL_CRITICAL_SECTION  CriticalSection,
_In_ ULONG  SpinCount 
)

Definition at line 701 of file critical.c.

704{
705 SpinCount &= ~RTL_CRITICAL_SECTION_ALL_FLAG_BITS;
707}
NTSTATUS NTAPI RtlInitializeCriticalSectionEx(_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount, _In_ ULONG Flags)
Definition: critical.c:574

Referenced by RtlInitializeCriticalSection().

◆ RtlInitializeCriticalSectionEx()

NTSTATUS NTAPI RtlInitializeCriticalSectionEx ( _Out_ PRTL_CRITICAL_SECTION  CriticalSection,
_In_ ULONG  SpinCount,
_In_ ULONG  Flags 
)

Definition at line 574 of file critical.c.

578{
579 PRTL_CRITICAL_SECTION_DEBUG CritcalSectionDebugData;
580 ULONG AllowedFlags;
582
583 /* Remove lower bits from flags */
585
586 /* These flags generally allowed */
590
591 /* Flags for Windows 7+ (CHECKME) */
592 OsVersion = NtCurrentPeb()->OSMajorVersion << 8 |
593 NtCurrentPeb()->OSMinorVersion;
595 {
598 }
599
600 if (Flags & ~AllowedFlags)
601 {
603 }
604
606 {
608 }
609
610 /* First things first, set up the Object */
611 DPRINT("Initializing Critical Section: %p\n", CriticalSection);
615 CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
617
619 {
621 }
622 else
623 {
624 /* Allocate the Debug Data */
625 CritcalSectionDebugData = RtlpAllocateDebugInfo();
626 DPRINT("Allocated Debug Data: %p inside Process: %p\n",
627 CritcalSectionDebugData,
629
630 if (!CritcalSectionDebugData)
631 {
632 /* This is bad! */
633 DPRINT1("Couldn't allocate Debug Data for: %p\n", CriticalSection);
634 return STATUS_NO_MEMORY;
635 }
636
637 /* Set it up */
638 CritcalSectionDebugData->Type = RTL_CRITSECT_TYPE;
639 CritcalSectionDebugData->ContentionCount = 0;
640 CritcalSectionDebugData->EntryCount = 0;
641 CritcalSectionDebugData->CriticalSection = CriticalSection;
642 CritcalSectionDebugData->Flags = 0;
643 CriticalSection->DebugInfo = CritcalSectionDebugData;
644
645 /*
646 * Add it to the List of Critical Sections owned by the process.
647 * If we've initialized the Lock, then use it. If not, then probably
648 * this is the lock initialization itself, so insert it directly.
649 */
651 {
652 DPRINT("Securely Inserting into ProcessLocks: %p, %p, %p\n",
653 &CritcalSectionDebugData->ProcessLocksList,
656
657 /* Protect List */
659
660 /* Add this one */
661 InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
662
663 /* Unprotect */
665 }
666 else
667 {
668 DPRINT("Inserting into ProcessLocks: %p, %p, %p\n",
669 &CritcalSectionDebugData->ProcessLocksList,
672
673 /* Add it directly */
674 InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
675 }
676 }
677
678 return STATUS_SUCCESS;
679}
#define NtCurrentPeb()
Definition: FLS.c:22
static BOOLEAN RtlpCritSectInitialized
Definition: critical.c:21
PRTL_CRITICAL_SECTION_DEBUG NTAPI RtlpAllocateDebugInfo(VOID)
Definition: critical.c:299
static LIST_ENTRY RtlCriticalSectionList
Definition: critical.c:20
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define InsertTailList(ListHead, Entry)
static ULONG OsVersion
#define RTL_CRITSECT_TYPE
Definition: rtltypes.h:264
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
HANDLE UniqueProcess
Definition: compat.h:825
ULONG_PTR SpinCount
Definition: winbase.h:924
struct _RTL_CRITICAL_SECTION * CriticalSection
Definition: rtltypes.h:1422
uint32_t ULONG
Definition: typedefs.h:59
#define RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN
Definition: winnt_old.h:1115
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1118
#define RTL_CRITICAL_SECTION_FLAG_STATIC_INIT
Definition: winnt_old.h:1116
#define RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO
Definition: winnt_old.h:1114
#define RTL_CRITICAL_SECTION_FLAG_RESOURCE_TYPE
Definition: winnt_old.h:1117
#define RTL_CRITICAL_SECTION_ALL_FLAG_BITS
Definition: winnt_old.h:1119
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by RtlInitializeCriticalSectionAndSpinCount().

◆ RtlIsCriticalSectionLocked()

ULONG NTAPI RtlIsCriticalSectionLocked ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 868 of file critical.c.

869{
870 return CriticalSection->RecursionCount != 0;
871}

◆ RtlIsCriticalSectionLockedByThread()

ULONG NTAPI RtlIsCriticalSectionLockedByThread ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 875 of file critical.c.

876{
877 return CriticalSection->OwningThread == NtCurrentTeb()->ClientId.UniqueThread &&
879}

◆ RtlLeaveCriticalSection()

NTSTATUS NTAPI RtlLeaveCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 766 of file critical.c.

767{
768#if DBG
769 HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread;
770
771 /*
772 * In win this case isn't checked. However it's a valid check so it should
773 * only be performed in debug builds!
774 */
776 {
777 DPRINT1("Releasing critical section not owned!\n");
779 }
780#endif
781
782 /*
783 * Decrease the Recursion Count. No need to do this atomically because only
784 * the thread who holds the lock can call this function (unless the program
785 * is totally screwed...
786 */
788 {
790 {
791 DPRINT1("CRITICAL SECTION MESS: Section %p is not acquired!\n", CriticalSection);
792 return STATUS_UNSUCCESSFUL;
793 }
794 /* Someone still owns us, but we are free. This needs to be done atomically. */
796 }
797 else
798 {
799 /*
800 * Nobody owns us anymore. No need to do this atomically.
801 * See comment above.
802 */
804 NtCurrentTeb()->CountOfOwnedCriticalSections--;
805
806 /* Was someone wanting us? This needs to be done atomically. */
808 {
809 /* Let him have us */
811 }
812 }
813
814 /* Sucessful! */
815 return STATUS_SUCCESS;
816}
#define InterlockedDecrement
Definition: armddk.h:52
VOID NTAPI RtlpUnWaitCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:217
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by RtlDeleteCriticalSection(), and RtlInitializeCriticalSectionEx().

◆ RtlpAllocateDebugInfo()

PRTL_CRITICAL_SECTION_DEBUG NTAPI RtlpAllocateDebugInfo ( VOID  )

Definition at line 299 of file critical.c.

300{
301 ULONG i;
302
303 /* Try to allocate from our buffer first */
304 for (i = 0; i < MAX_STATIC_CS_DEBUG_OBJECTS; i++)
305 {
306 /* Check if Entry is free */
308 {
309 /* Mark entry in use */
310 DPRINT("Using entry: %lu. Buffer: %p\n", i, &RtlpStaticDebugInfo[i]);
312
313 /* Use free entry found */
314 return &RtlpStaticDebugInfo[i];
315 }
316 }
317
318 /* We are out of static buffer, allocate dynamic */
319 return RtlAllocateHeap(RtlGetProcessHeap(),
320 0,
322}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
static BOOLEAN RtlpDebugInfoFreeList[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:23
#define MAX_STATIC_CS_DEBUG_OBJECTS
Definition: critical.c:17
static RTL_CRITICAL_SECTION_DEBUG RtlpStaticDebugInfo[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:22
#define TRUE
Definition: types.h:120
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248

Referenced by RtlInitializeCriticalSectionEx().

◆ RtlpFreeDebugInfo()

VOID NTAPI RtlpFreeDebugInfo ( PRTL_CRITICAL_SECTION_DEBUG  DebugInfo)

Definition at line 342 of file critical.c.

343{
344 SIZE_T EntryId;
345
346 /* Is it part of our cached entries? */
347 if ((DebugInfo >= RtlpStaticDebugInfo) &&
349 {
350 /* Yes. zero it out */
351 RtlZeroMemory(DebugInfo, sizeof(RTL_CRITICAL_SECTION_DEBUG));
352
353 /* Mark as free */
354 EntryId = (DebugInfo - RtlpStaticDebugInfo);
355 DPRINT("Freeing from Buffer: %p. Entry: %Iu inside Process: %p\n",
356 DebugInfo,
357 EntryId,
359 RtlpDebugInfoFreeList[EntryId] = FALSE;
360
361 }
362 else if (!DebugInfo->Flags)
363 {
364 /* It's a dynamic one, so free from the heap */
365 DPRINT("Freeing from Heap: %p inside Process: %p\n",
366 DebugInfo,
368 RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, DebugInfo);
369 }
370 else
371 {
372 /* Wine stores a section name pointer in the Flags member */
373 DPRINT("Assuming static: %p inside Process: %p\n",
374 DebugInfo,
376 }
377}
HANDLE ProcessHeap
Definition: servman.c:15
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by RtlDeleteCriticalSection().

◆ RtlpInitDeferredCriticalSection()

VOID NTAPI RtlpInitDeferredCriticalSection ( VOID  )

Definition at line 272 of file critical.c.

273{
274 /* Initialize the CS Protecting the List */
276
277 /* It's now safe to enter it */
279}
NTSTATUS NTAPI RtlInitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:546

Referenced by LdrpInitializeProcess().

◆ RtlpNotOwnerCriticalSection()

VOID NTAPI RtlpNotOwnerCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 883 of file critical.c.

884{
886}
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
#define STATUS_RESOURCE_NOT_OWNED
Definition: ntstatus.h:737

◆ RtlpUnWaitCriticalSection()

VOID NTAPI RtlpUnWaitCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 217 of file critical.c.

218{
220
221 /* Do we have an Event yet? */
223 {
224 RtlpCreateCriticalSectionSem(CriticalSection);
225 }
226
227 /* Signal the Event */
228 DPRINT("Signaling Critical Section Event: %p, %p\n",
231
232 /* Check if this critical section needs to use the keyed event */
234 {
235 /* Release keyed event */
237 }
238 else
239 {
240 /* Set the event */
242 }
243
244 if (!NT_SUCCESS(Status))
245 {
246 /* We've failed */
247 DPRINT1("Signaling Failed for: %p, %p, 0x%08lx\n",
250 Status);
252 }
253}
LARGE_INTEGER RtlpTimeout
Definition: critical.c:25
NTSYSAPI NTSTATUS WINAPI NtReleaseKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455

Referenced by RtlLeaveCriticalSection().

◆ RtlpWaitForCriticalSection()

NTSTATUS NTAPI RtlpWaitForCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 117 of file critical.c.

118{
120 EXCEPTION_RECORD ExceptionRecord;
121 BOOLEAN LastChance = FALSE;
122
123 /* Increase the Debug Entry count */
124 DPRINT("Waiting on Critical Section Event: %p %p\n",
127
130
131 /*
132 * If we're shutting down the process, we're allowed to acquire any
133 * critical sections by force (the loader lock in particular)
134 */
136 LdrpShutdownThreadId == NtCurrentTeb()->RealClientId.UniqueThread)
137 {
138 DPRINT("Forcing ownership of critical section %p\n", CriticalSection);
139 return STATUS_SUCCESS;
140 }
141
142 /* Do we have an Event yet? */
144 {
145 RtlpCreateCriticalSectionSem(CriticalSection);
146 }
147
148 for (;;)
149 {
150 /* Increase the number of times we've had contention */
153
154 /* Check if allocating the event failed */
156 {
157 /* Use the global keyed event (NULL as keyed event handle) */
160 FALSE,
162 }
163 else
164 {
165 /* Wait on the Event */
167 FALSE,
169 }
170
171 /* We have Timed out */
172 if (Status == STATUS_TIMEOUT)
173 {
174 /* Is this the 2nd time we've timed out? */
175 if (LastChance)
176 {
177 ERROR_DBGBREAK("Deadlock: 0x%p\n", CriticalSection);
178
179 /* Yes it is, we are raising an exception */
180 ExceptionRecord.ExceptionCode = STATUS_POSSIBLE_DEADLOCK;
181 ExceptionRecord.ExceptionFlags = 0;
182 ExceptionRecord.ExceptionRecord = NULL;
183 ExceptionRecord.ExceptionAddress = RtlRaiseException;
184 ExceptionRecord.NumberParameters = 1;
185 ExceptionRecord.ExceptionInformation[0] = (ULONG_PTR)CriticalSection;
186 RtlRaiseException(&ExceptionRecord);
187 }
188
189 /* One more try */
190 LastChance = TRUE;
191 }
192 else
193 {
194 /* If we are here, everything went fine */
195 return STATUS_SUCCESS;
196 }
197 }
198}
unsigned char BOOLEAN
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
BOOLEAN RtlpTimeoutDisable
Definition: critical.c:26
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define ULONG_PTR
Definition: config.h:101
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
NTSYSAPI VOID NTAPI RtlRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord)
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
#define STATUS_POSSIBLE_DEADLOCK
Definition: ntstatus.h:637
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
DWORD ExceptionFlags
Definition: compat.h:209
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
PVOID ExceptionAddress
Definition: compat.h:211

Referenced by RtlEnterCriticalSection().

◆ RtlSetCriticalSectionSpinCount()

ULONG NTAPI RtlSetCriticalSectionSpinCount ( PRTL_CRITICAL_SECTION  CriticalSection,
ULONG  SpinCount 
)

Definition at line 459 of file critical.c.

461{
463
464 /* Set to parameter if MP, or to 0 if this is Uniprocessor */
465 CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
466 return OldCount;
467}

◆ RtlTryEnterCriticalSection()

BOOLEAN NTAPI RtlTryEnterCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 836 of file critical.c.

837{
838 /* Try to take control */
840 {
841 /* It's ours */
842 CriticalSection->OwningThread = NtCurrentTeb()->ClientId.UniqueThread;
844 NtCurrentTeb()->CountOfOwnedCriticalSections++;
845 return TRUE;
846 }
848 {
849 /* It's already ours */
852 return TRUE;
853 }
854
855 /* It's not ours */
856 return FALSE;
857}
#define InterlockedCompareExchange
Definition: interlocked.h:104

Variable Documentation

◆ LdrpShutdownInProgress

BOOLEAN LdrpShutdownInProgress
extern

◆ LdrpShutdownThreadId

HANDLE LdrpShutdownThreadId
extern

Definition at line 35 of file ldrinit.c.

Referenced by LdrShutdownProcess(), and RtlpWaitForCriticalSection().

◆ RtlCriticalSectionList

LIST_ENTRY RtlCriticalSectionList = {&RtlCriticalSectionList, &RtlCriticalSectionList}
static

Definition at line 20 of file critical.c.

Referenced by RtlInitializeCriticalSectionEx().

◆ RtlCriticalSectionLock

RTL_CRITICAL_SECTION RtlCriticalSectionLock
static

◆ RtlpCritSectInitialized

BOOLEAN RtlpCritSectInitialized = FALSE
static

Definition at line 21 of file critical.c.

Referenced by RtlInitializeCriticalSectionEx(), and RtlpInitDeferredCriticalSection().

◆ RtlpDebugInfoFreeList

BOOLEAN RtlpDebugInfoFreeList[MAX_STATIC_CS_DEBUG_OBJECTS]
static

Definition at line 23 of file critical.c.

Referenced by RtlpAllocateDebugInfo(), and RtlpFreeDebugInfo().

◆ RtlpStaticDebugInfo

Definition at line 22 of file critical.c.

Referenced by RtlpAllocateDebugInfo(), and RtlpFreeDebugInfo().

◆ RtlpTimeout

◆ RtlpTimeoutDisable

BOOLEAN RtlpTimeoutDisable

Definition at line 26 of file critical.c.

Referenced by LdrpInitializeProcess(), and RtlpWaitForCriticalSection().