ReactOS 0.4.17-dev-683-g0dafdc5
critical.c File Reference
#include <rtl.h>
#include <debug.h>
#include <reactos/verifier.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)
 
LOGICAL NTAPI RtlTryEnterCriticalSection (PRTL_CRITICAL_SECTION CriticalSection)
 
VOID NTAPI RtlCheckForOrphanedCriticalSections (_In_ HANDLE ThreadHandle)
 RtlCheckForOrphanedCriticalSections.
 
LOGICAL NTAPI RtlIsCriticalSectionLocked (PRTL_CRITICAL_SECTION CriticalSection)
 
LOGICAL 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 RtlpCriticalSectionVerifier = FALSE
 
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:85
#define NULL
Definition: types.h:112
CRITICAL_SECTION CriticalSection
Definition: iprtprio.c:40

Definition at line 35 of file critical.c.

◆ MAX_STATIC_CS_DEBUG_OBJECTS

#define MAX_STATIC_CS_DEBUG_OBJECTS   64

Definition at line 18 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 54 of file critical.c.

58{
60 HANDLE hNewEvent;
62
63 /* Check if we have an event */
64 if (!hEvent)
65 {
66 /* No, so create it */
67 Status = NtCreateEvent(&hNewEvent,
69 NULL,
71 FALSE);
72 if (!NT_SUCCESS(Status))
73 {
74 DPRINT1("Failed to Create Event!\n");
75
76 /*
77 * Use INVALID_HANDLE_VALUE (-1) to signal that
78 * the global keyed event must be used.
79 */
80 hNewEvent = INVALID_HANDLE_VALUE;
81 }
82
83 DPRINT("Created Event: %p\n", hNewEvent);
84
85 /* Exchange the LockSemaphore field with the new handle, if it is still 0 */
87 (PVOID)hNewEvent,
88 NULL) != NULL)
89 {
90 /* Someone else just created an event */
91 if (hNewEvent != INVALID_HANDLE_VALUE)
92 {
93 DPRINT("Closing already created event: %p\n", hNewEvent);
94 NtClose(hNewEvent);
95 }
96 }
97 }
98
99 return;
100}
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:24
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
static HANDLE hEvent
Definition: comm.c:54
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3429
@ 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

◆ RtlCheckForOrphanedCriticalSections()

VOID NTAPI RtlCheckForOrphanedCriticalSections ( _In_ HANDLE  ThreadHandle)

RtlCheckForOrphanedCriticalSections.

Checks if the given thread owns any critical sections at the time of its exit, and emits a debug message for each orphaned section found.

Parameters
[in]ThreadHandleHandle to the thread to check.
Returns
Nothing
Remarks
This function is typically called by the loader during thread exit.

Definition at line 879 of file critical.c.

881{
884 PLIST_ENTRY ListEntry;
885
886 /* Early exit if verifier is not active */
888 return;
889
890 /* Get current thread ID first */
891 if (ThreadHandle == NtCurrentThread())
892 {
893 /* Using current thread */
894 ThreadInfo.ClientId.UniqueThread = NtCurrentTeb()->ClientId.UniqueThread;
895 }
896 else
897 {
898 /* Query thread info from the handle */
900 ThreadHandle,
902 &ThreadInfo,
903 sizeof(ThreadInfo),
904 NULL);
905
906 if (!NT_SUCCESS(Status))
907 return;
908 }
909
910 /* Lock the critical section list */
912
913 /* Walk the global critical section list */
914 ListEntry = RtlCriticalSectionList.Flink;
915 while (ListEntry != &RtlCriticalSectionList)
916 {
919
920 /* Get the debug info from the list entry */
921 DebugInfo = CONTAINING_RECORD(
922 ListEntry,
924 ProcessLocksList);
925 CriticalSection = DebugInfo->CriticalSection;
926
927 /* Skip our own lock since we own it right now */
929 {
930 ListEntry = ListEntry->Flink;
931 continue;
932 }
933
934 /* Check if this critical section is owned by the target thread */
935 if (CriticalSection &&
936 CriticalSection->OwningThread == ThreadInfo.ClientId.UniqueThread)
937 {
938 /* Thread is exiting while owning a critical section! */
941 "Thread is exiting while owning a critical section",
943 "Critical section object",
944 ThreadInfo.ClientId.UniqueThread,
945 "Thread ID",
946 DebugInfo,
947 "Critical section debug info",
948 NULL,
949 NULL);
950 /* TODO: Add stack trace information here (CORE-16870) */
951 }
952
953 ListEntry = ListEntry->Flink;
954 }
955
957}
NTSTATUS NTAPI RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:768
static RTL_CRITICAL_SECTION RtlCriticalSectionLock
Definition: critical.c:20
BOOLEAN RtlpCriticalSectionVerifier
Definition: critical.c:28
static LIST_ENTRY RtlCriticalSectionList
Definition: critical.c:21
NTSTATUS NTAPI RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:489
@ ThreadBasicInformation
Definition: compat.h:935
#define NtCurrentTeb
struct _ThreadInfo ThreadInfo
NTSTATUS NTAPI NtQueryInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _Out_writes_bytes_to_opt_(ThreadInformationLength, *ReturnLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:3017
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _RTL_CRITICAL_SECTION * CriticalSection
Definition: rtltypes.h:1433
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define VERIFIER_STOP(Code, Msg, Val1, Desc1, Val2, Desc2, Val3, Desc3, Val4, Desc4)
Definition: verifier.h:171
#define APPLICATION_VERIFIER_EXIT_THREAD_OWNS_LOCK
Definition: verifier.h:119
#define NtCurrentThread()
Definition: winternl.h:5372

◆ RtlDeleteCriticalSection()

NTSTATUS NTAPI RtlDeleteCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 399 of file critical.c.

400{
402
403 DPRINT("Deleting Critical Section: %p\n", CriticalSection);
404
405 /* Close the Event Object Handle if it exists */
407 {
408 /* In case NtClose fails, return the status */
410 }
411
412 /* Protect List */
414
416 {
417 /* Remove it from the list */
419#if 0
420 /* HACK for Wine: We need to preserve Flags for RtlpFreeDebugInfo */
422#endif
423 }
424
425 /* Unprotect */
427
429 {
430 /* Free it */
432 }
433
434 /* Wipe it out */
436
437 /* Return */
438 return Status;
439}
#define CRITSECT_HAS_DEBUG_INFO(CriticalSection)
Definition: critical.c:35
VOID NTAPI RtlpFreeDebugInfo(PRTL_CRITICAL_SECTION_DEBUG DebugInfo)
Definition: critical.c:344
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define STATUS_SUCCESS
Definition: shellext.h:65
PRTL_CRITICAL_SECTION_DEBUG DebugInfo
Definition: rtltypes.h:1458
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

◆ RtlEnterCriticalSection()

NTSTATUS NTAPI RtlEnterCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 489 of file critical.c.

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

Referenced by RtlCheckForOrphanedCriticalSections(), RtlDeleteCriticalSection(), and RtlInitializeCriticalSectionEx().

◆ RtlGetCriticalSectionRecursionCount()

LONG NTAPI RtlGetCriticalSectionRecursionCount ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 730 of file critical.c.

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

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

Referenced by RtlpInitDeferredCriticalSection().

◆ RtlInitializeCriticalSectionAndSpinCount()

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

Definition at line 703 of file critical.c.

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

Referenced by RtlInitializeCriticalSection().

◆ RtlInitializeCriticalSectionEx()

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

Definition at line 576 of file critical.c.

580{
581 PRTL_CRITICAL_SECTION_DEBUG CritcalSectionDebugData;
582 ULONG AllowedFlags;
584
585 /* Remove lower bits from flags */
587
588 /* These flags generally allowed */
592
593 /* Flags for Windows 7+ (CHECKME) */
594 OsVersion = NtCurrentPeb()->OSMajorVersion << 8 |
595 NtCurrentPeb()->OSMinorVersion;
597 {
600 }
601
602 if (Flags & ~AllowedFlags)
603 {
605 }
606
608 {
610 }
611
612 /* First things first, set up the Object */
613 DPRINT("Initializing Critical Section: %p\n", CriticalSection);
617 CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
619
621 {
623 }
624 else
625 {
626 /* Allocate the Debug Data */
627 CritcalSectionDebugData = RtlpAllocateDebugInfo();
628 DPRINT("Allocated Debug Data: %p inside Process: %p\n",
629 CritcalSectionDebugData,
631
632 if (!CritcalSectionDebugData)
633 {
634 /* This is bad! */
635 DPRINT1("Couldn't allocate Debug Data for: %p\n", CriticalSection);
636 return STATUS_NO_MEMORY;
637 }
638
639 /* Set it up */
640 CritcalSectionDebugData->Type = RTL_CRITSECT_TYPE;
641 CritcalSectionDebugData->ContentionCount = 0;
642 CritcalSectionDebugData->EntryCount = 0;
643 CritcalSectionDebugData->CriticalSection = CriticalSection;
644 CritcalSectionDebugData->Flags = 0;
645 CriticalSection->DebugInfo = CritcalSectionDebugData;
646
647 /*
648 * Add it to the List of Critical Sections owned by the process.
649 * If we've initialized the Lock, then use it. If not, then probably
650 * this is the lock initialization itself, so insert it directly.
651 */
653 {
654 DPRINT("Securely Inserting into ProcessLocks: %p, %p, %p\n",
655 &CritcalSectionDebugData->ProcessLocksList,
658
659 /* Protect List */
661
662 /* Add this one */
663 InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
664
665 /* Unprotect */
667 }
668 else
669 {
670 DPRINT("Inserting into ProcessLocks: %p, %p, %p\n",
671 &CritcalSectionDebugData->ProcessLocksList,
674
675 /* Add it directly */
676 InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
677 }
678 }
679
680 return STATUS_SUCCESS;
681}
#define NtCurrentPeb()
Definition: FLS.c:22
static BOOLEAN RtlpCritSectInitialized
Definition: critical.c:22
PRTL_CRITICAL_SECTION_DEBUG NTAPI RtlpAllocateDebugInfo(VOID)
Definition: critical.c:301
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define InsertTailList(ListHead, Entry)
static ULONG OsVersion
#define RTL_CRITSECT_TYPE
Definition: rtltypes.h:272
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:570
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:571
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
HANDLE UniqueProcess
Definition: compat.h:825
uint32_t ULONG
Definition: typedefs.h:59
#define RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN
Definition: winnt_old.h:1153
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156
#define RTL_CRITICAL_SECTION_FLAG_STATIC_INIT
Definition: winnt_old.h:1154
#define RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO
Definition: winnt_old.h:1152
#define RTL_CRITICAL_SECTION_FLAG_RESOURCE_TYPE
Definition: winnt_old.h:1155
#define RTL_CRITICAL_SECTION_ALL_FLAG_BITS
Definition: winnt_old.h:1157
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by RtlInitializeCriticalSectionAndSpinCount().

◆ RtlIsCriticalSectionLocked()

LOGICAL NTAPI RtlIsCriticalSectionLocked ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 961 of file critical.c.

962{
963 return CriticalSection->RecursionCount != 0;
964}

◆ RtlIsCriticalSectionLockedByThread()

LOGICAL NTAPI RtlIsCriticalSectionLockedByThread ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 968 of file critical.c.

969{
970 return CriticalSection->OwningThread == NtCurrentTeb()->ClientId.UniqueThread &&
972}

◆ RtlLeaveCriticalSection()

NTSTATUS NTAPI RtlLeaveCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 768 of file critical.c.

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

Referenced by RtlCheckForOrphanedCriticalSections(), RtlDeleteCriticalSection(), and RtlInitializeCriticalSectionEx().

◆ RtlpAllocateDebugInfo()

PRTL_CRITICAL_SECTION_DEBUG NTAPI RtlpAllocateDebugInfo ( VOID  )

Definition at line 301 of file critical.c.

302{
303 ULONG i;
304
305 /* Try to allocate from our buffer first */
306 for (i = 0; i < MAX_STATIC_CS_DEBUG_OBJECTS; i++)
307 {
308 /* Check if Entry is free */
310 {
311 /* Mark entry in use */
312 DPRINT("Using entry: %lu. Buffer: %p\n", i, &RtlpStaticDebugInfo[i]);
314
315 /* Use free entry found */
316 return &RtlpStaticDebugInfo[i];
317 }
318 }
319
320 /* We are out of static buffer, allocate dynamic */
321 return RtlAllocateHeap(RtlGetProcessHeap(),
322 0,
324}
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:24
#define MAX_STATIC_CS_DEBUG_OBJECTS
Definition: critical.c:18
static RTL_CRITICAL_SECTION_DEBUG RtlpStaticDebugInfo[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:23
#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 344 of file critical.c.

345{
346 SIZE_T EntryId;
347
348 /* Is it part of our cached entries? */
349 if ((DebugInfo >= RtlpStaticDebugInfo) &&
351 {
352 /* Yes. zero it out */
353 RtlZeroMemory(DebugInfo, sizeof(RTL_CRITICAL_SECTION_DEBUG));
354
355 /* Mark as free */
356 EntryId = (DebugInfo - RtlpStaticDebugInfo);
357 DPRINT("Freeing from Buffer: %p. Entry: %Iu inside Process: %p\n",
358 DebugInfo,
359 EntryId,
361 RtlpDebugInfoFreeList[EntryId] = FALSE;
362
363 }
364 else if (!DebugInfo->Flags)
365 {
366 /* It's a dynamic one, so free from the heap */
367 DPRINT("Freeing from Heap: %p inside Process: %p\n",
368 DebugInfo,
370 RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, DebugInfo);
371 }
372 else
373 {
374 /* HACK for Wine: stores a section name pointer in the Flags member */
375 DPRINT("Assuming static: %p inside Process: %p\n",
376 DebugInfo,
378 }
379}
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 274 of file critical.c.

275{
276 /* Initialize the CS Protecting the List */
278
279 /* It's now safe to enter it */
281}
NTSTATUS NTAPI RtlInitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:548

Referenced by LdrpInitializeProcess().

◆ RtlpNotOwnerCriticalSection()

VOID NTAPI RtlpNotOwnerCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 976 of file critical.c.

977{
979}
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
#define STATUS_RESOURCE_NOT_OWNED
Definition: ntstatus.h:859

◆ RtlpUnWaitCriticalSection()

VOID NTAPI RtlpUnWaitCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 219 of file critical.c.

220{
222
223 /* Do we have an Event yet? */
225 {
226 RtlpCreateCriticalSectionSem(CriticalSection);
227 }
228
229 /* Signal the Event */
230 DPRINT("Signaling Critical Section Event: %p, %p\n",
233
234 /* Check if this critical section needs to use the keyed event */
236 {
237 /* Release keyed event */
239 }
240 else
241 {
242 /* Set the event */
244 }
245
246 if (!NT_SUCCESS(Status))
247 {
248 /* We've failed */
249 DPRINT1("Signaling Failed for: %p, %p, 0x%08lx\n",
252 Status);
254 }
255}
LARGE_INTEGER RtlpTimeout
Definition: critical.c:26
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:463
NTSYSAPI NTSTATUS WINAPI NtReleaseKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)

Referenced by RtlLeaveCriticalSection().

◆ RtlpWaitForCriticalSection()

NTSTATUS NTAPI RtlpWaitForCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 119 of file critical.c.

120{
122 EXCEPTION_RECORD ExceptionRecord;
123 BOOLEAN LastChance = FALSE;
124
125 /* Increase the Debug Entry count */
126 DPRINT("Waiting on Critical Section Event: %p %p\n",
129
132
133 /*
134 * If we're shutting down the process, we're allowed to acquire any
135 * critical sections by force (the loader lock in particular)
136 */
138 LdrpShutdownThreadId == NtCurrentTeb()->RealClientId.UniqueThread)
139 {
140 DPRINT("Forcing ownership of critical section %p\n", CriticalSection);
141 return STATUS_SUCCESS;
142 }
143
144 /* Do we have an Event yet? */
146 {
147 RtlpCreateCriticalSectionSem(CriticalSection);
148 }
149
150 for (;;)
151 {
152 /* Increase the number of times we've had contention */
155
156 /* Check if allocating the event failed */
158 {
159 /* Use the global keyed event (NULL as keyed event handle) */
162 FALSE,
164 }
165 else
166 {
167 /* Wait on the Event */
169 FALSE,
171 }
172
173 /* We have Timed out */
174 if (Status == STATUS_TIMEOUT)
175 {
176 /* Is this the 2nd time we've timed out? */
177 if (LastChance)
178 {
179 ERROR_DBGBREAK("Deadlock: 0x%p\n", CriticalSection);
180
181 /* Yes it is, we are raising an exception */
182 ExceptionRecord.ExceptionCode = STATUS_POSSIBLE_DEADLOCK;
183 ExceptionRecord.ExceptionFlags = 0;
184 ExceptionRecord.ExceptionRecord = NULL;
185 ExceptionRecord.ExceptionAddress = RtlRaiseException;
186 ExceptionRecord.NumberParameters = 1;
187 ExceptionRecord.ExceptionInformation[0] = (ULONG_PTR)CriticalSection;
188 RtlRaiseException(&ExceptionRecord);
189 }
190
191 /* One more try */
192 LastChance = TRUE;
193 }
194 else
195 {
196 /* If we are here, everything went fine */
197 return STATUS_SUCCESS;
198 }
199 }
200}
unsigned char BOOLEAN
Definition: actypes.h:127
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
BOOLEAN RtlpTimeoutDisable
Definition: critical.c:27
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define ULONG_PTR
Definition: config.h:101
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:731
#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
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)

Referenced by RtlEnterCriticalSection().

◆ RtlSetCriticalSectionSpinCount()

ULONG NTAPI RtlSetCriticalSectionSpinCount ( PRTL_CRITICAL_SECTION  CriticalSection,
ULONG  SpinCount 
)

Definition at line 461 of file critical.c.

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

◆ RtlTryEnterCriticalSection()

LOGICAL NTAPI RtlTryEnterCriticalSection ( PRTL_CRITICAL_SECTION  CriticalSection)

Definition at line 838 of file critical.c.

839{
840 /* Try to take control */
842 {
843 /* It's ours */
844 CriticalSection->OwningThread = NtCurrentTeb()->ClientId.UniqueThread;
846 NtCurrentTeb()->CountOfOwnedCriticalSections++;
847 return TRUE;
848 }
850 {
851 /* It's already ours */
854 return TRUE;
855 }
856
857 /* It's not ours */
858 return FALSE;
859}
#define InterlockedCompareExchange
Definition: interlocked.h:119

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

◆ RtlCriticalSectionLock

◆ RtlpCriticalSectionVerifier

BOOLEAN RtlpCriticalSectionVerifier = FALSE

Definition at line 28 of file critical.c.

Referenced by RtlCheckForOrphanedCriticalSections().

◆ RtlpCritSectInitialized

BOOLEAN RtlpCritSectInitialized = FALSE
static

Definition at line 22 of file critical.c.

Referenced by RtlInitializeCriticalSectionEx(), and RtlpInitDeferredCriticalSection().

◆ RtlpDebugInfoFreeList

BOOLEAN RtlpDebugInfoFreeList[MAX_STATIC_CS_DEBUG_OBJECTS]
static

Definition at line 24 of file critical.c.

Referenced by RtlpAllocateDebugInfo(), and RtlpFreeDebugInfo().

◆ RtlpStaticDebugInfo

Definition at line 23 of file critical.c.

Referenced by RtlpAllocateDebugInfo(), and RtlpFreeDebugInfo().

◆ RtlpTimeout

◆ RtlpTimeoutDisable

BOOLEAN RtlpTimeoutDisable

Definition at line 27 of file critical.c.

Referenced by LdrpInitializeProcess(), and RtlpWaitForCriticalSection().