ReactOS 0.4.15-dev-8116-gf69e256
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:32
#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:898

◆ RtlCheckForOrphanedCriticalSections()

VOID NTAPI RtlCheckForOrphanedCriticalSections ( HANDLE  ThreadHandle)

Definition at line 858 of file critical.c.

859{
861}
#define UNIMPLEMENTED
Definition: debug.h:118

◆ 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:765
#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:883
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:894
#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 return STATUS_SUCCESS;
525}
#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:896
HANDLE OwningThread
Definition: winbase.h:897
PVOID HANDLE
Definition: typedefs.h:73

Referenced by RtlDeleteCriticalSection(), and RtlInitializeCriticalSectionEx().

◆ RtlGetCriticalSectionRecursionCount()

LONG NTAPI RtlGetCriticalSectionRecursionCount ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 727 of file critical.c.

728{
730 {
731 /*
732 * The critical section is owned by the current thread,
733 * therefore retrieve its actual recursion count.
734 */
736 }
737 else
738 {
739 /*
740 * It is not owned by the current thread, so
741 * for this thread there is no recursion.
742 */
743 return 0;
744 }
745}
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 545 of file critical.c.

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

Referenced by RtlpInitDeferredCriticalSection().

◆ RtlInitializeCriticalSectionAndSpinCount()

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

Definition at line 700 of file critical.c.

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

Referenced by RtlInitializeCriticalSection().

◆ RtlInitializeCriticalSectionEx()

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

Definition at line 573 of file critical.c.

577{
578 PRTL_CRITICAL_SECTION_DEBUG CritcalSectionDebugData;
579 ULONG AllowedFlags;
581
582 /* Remove lower bits from flags */
584
585 /* These flags generally allowed */
589
590 /* Flags for Windows 7+ (CHECKME) */
591 OsVersion = NtCurrentPeb()->OSMajorVersion << 8 |
592 NtCurrentPeb()->OSMinorVersion;
594 {
597 }
598
599 if (Flags & ~AllowedFlags)
600 {
602 }
603
605 {
607 }
608
609 /* First things first, set up the Object */
610 DPRINT("Initializing Critical Section: %p\n", CriticalSection);
614 CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
616
618 {
620 }
621 else
622 {
623 /* Allocate the Debug Data */
624 CritcalSectionDebugData = RtlpAllocateDebugInfo();
625 DPRINT("Allocated Debug Data: %p inside Process: %p\n",
626 CritcalSectionDebugData,
628
629 if (!CritcalSectionDebugData)
630 {
631 /* This is bad! */
632 DPRINT1("Couldn't allocate Debug Data for: %p\n", CriticalSection);
633 return STATUS_NO_MEMORY;
634 }
635
636 /* Set it up */
637 CritcalSectionDebugData->Type = RTL_CRITSECT_TYPE;
638 CritcalSectionDebugData->ContentionCount = 0;
639 CritcalSectionDebugData->EntryCount = 0;
640 CritcalSectionDebugData->CriticalSection = CriticalSection;
641 CritcalSectionDebugData->Flags = 0;
642 CriticalSection->DebugInfo = CritcalSectionDebugData;
643
644 /*
645 * Add it to the List of Critical Sections owned by the process.
646 * If we've initialized the Lock, then use it. If not, then probably
647 * this is the lock initialization itself, so insert it directly.
648 */
650 {
651 DPRINT("Securely Inserting into ProcessLocks: %p, %p, %p\n",
652 &CritcalSectionDebugData->ProcessLocksList,
655
656 /* Protect List */
658
659 /* Add this one */
660 InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
661
662 /* Unprotect */
664 }
665 else
666 {
667 DPRINT("Inserting into ProcessLocks: %p, %p, %p\n",
668 &CritcalSectionDebugData->ProcessLocksList,
671
672 /* Add it directly */
673 InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
674 }
675 }
676
677 return STATUS_SUCCESS;
678}
#define NtCurrentPeb()
Definition: FLS.c:22
static ULONG OsVersion
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 InsertTailList(ListHead, Entry)
#define RTL_CRITSECT_TYPE
Definition: rtltypes.h:264
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#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:899
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:1086
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1089
#define RTL_CRITICAL_SECTION_FLAG_STATIC_INIT
Definition: winnt_old.h:1087
#define RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO
Definition: winnt_old.h:1085
#define RTL_CRITICAL_SECTION_FLAG_RESOURCE_TYPE
Definition: winnt_old.h:1088
#define RTL_CRITICAL_SECTION_ALL_FLAG_BITS
Definition: winnt_old.h:1090
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by RtlInitializeCriticalSectionAndSpinCount().

◆ RtlIsCriticalSectionLocked()

ULONG NTAPI RtlIsCriticalSectionLocked ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 865 of file critical.c.

866{
867 return CriticalSection->RecursionCount != 0;
868}

◆ RtlIsCriticalSectionLockedByThread()

ULONG NTAPI RtlIsCriticalSectionLockedByThread ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 872 of file critical.c.

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

◆ RtlLeaveCriticalSection()

NTSTATUS NTAPI RtlLeaveCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 765 of file critical.c.

766{
767#if DBG
768 HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread;
769
770 /*
771 * In win this case isn't checked. However it's a valid check so it should
772 * only be performed in debug builds!
773 */
775 {
776 DPRINT1("Releasing critical section not owned!\n");
778 }
779#endif
780
781 /*
782 * Decrease the Recursion Count. No need to do this atomically because only
783 * the thread who holds the lock can call this function (unless the program
784 * is totally screwed...
785 */
787 {
789 {
790 DPRINT1("CRITICAL SECTION MESS: Section %p is not acquired!\n", CriticalSection);
791 return STATUS_UNSUCCESSFUL;
792 }
793 /* Someone still owns us, but we are free. This needs to be done atomically. */
795 }
796 else
797 {
798 /*
799 * Nobody owns us anymore. No need to do this atomically.
800 * See comment above.
801 */
803
804 /* Was someone wanting us? This needs to be done atomically. */
806 {
807 /* Let him have us */
809 }
810 }
811
812 /* Sucessful! */
813 return STATUS_SUCCESS;
814}
#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:590
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:608
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:545

Referenced by LdrpInitializeProcess().

◆ RtlpNotOwnerCriticalSection()

VOID NTAPI RtlpNotOwnerCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 880 of file critical.c.

881{
883}
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 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_TIMEOUT
Definition: ntstatus.h:81
#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 834 of file critical.c.

835{
836 /* Try to take control */
838 {
839 /* It's ours */
840 CriticalSection->OwningThread = NtCurrentTeb()->ClientId.UniqueThread;
842 return TRUE;
843 }
845 {
846 /* It's already ours */
849 return TRUE;
850 }
851
852 /* It's not ours */
853 return FALSE;
854}
#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().