ReactOS 0.4.17-dev-683-g0dafdc5
critical.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/rtl/critical.c
5 * PURPOSE: Critical sections
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Gunnar Dalsnes
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include <rtl.h>
13
14#define NDEBUG
15#include <debug.h>
16#include <reactos/verifier.h>
17
18#define MAX_STATIC_CS_DEBUG_OBJECTS 64
19
25
29
32
33/* FUNCTIONS *****************************************************************/
34
35#define CRITSECT_HAS_DEBUG_INFO(CriticalSection) \
36 (((CriticalSection)->DebugInfo != NULL) && \
37 ((CriticalSection)->DebugInfo != LongToPtr(-1)))
38
39/*++
40 * RtlpCreateCriticalSectionSem
41 *
42 * Checks if an Event has been created for the critical section.
43 *
44 * Params:
45 * None
46 *
47 * Returns:
48 * None. Raises an exception if the system call failed.
49 *
50 * Remarks:
51 * None
52 *
53 *--*/
55VOID
57RtlpCreateCriticalSectionSem(PRTL_CRITICAL_SECTION CriticalSection)
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}
101
102/*++
103 * RtlpWaitForCriticalSection
104 *
105 * Slow path of RtlEnterCriticalSection. Waits on an Event Object.
106 *
107 * Params:
108 * CriticalSection - Critical section to acquire.
109 *
110 * Returns:
111 * STATUS_SUCCESS, or raises an exception if a deadlock is occuring.
112 *
113 * Remarks:
114 * None
115 *
116 *--*/
118NTAPI
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}
201
202/*++
203 * RtlpUnWaitCriticalSection
204 *
205 * Slow path of RtlLeaveCriticalSection. Fires an Event Object.
206 *
207 * Params:
208 * CriticalSection - Critical section to release.
209 *
210 * Returns:
211 * None. Raises an exception if the system call failed.
212 *
213 * Remarks:
214 * None
215 *
216 *--*/
217VOID
218NTAPI
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}
256
257/*++
258 * RtlpInitDeferredCriticalSection
259 *
260 * Initializes the Critical Section implementation.
261 *
262 * Params:
263 * None
264 *
265 * Returns:
266 * None.
267 *
268 * Remarks:
269 * After this call, the Process Critical Section list is protected.
270 *
271 *--*/
272VOID
273NTAPI
275{
276 /* Initialize the CS Protecting the List */
278
279 /* It's now safe to enter it */
281}
282
283/*++
284 * RtlpAllocateDebugInfo
285 *
286 * Finds or allocates memory for a Critical Section Debug Object
287 *
288 * Params:
289 * None
290 *
291 * Returns:
292 * A pointer to an empty Critical Section Debug Object.
293 *
294 * Remarks:
295 * For optimization purposes, the first 64 entries can be cached. From
296 * then on, future Critical Sections will allocate memory from the heap.
297 *
298 *--*/
300NTAPI
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}
325
326/*++
327 * RtlpFreeDebugInfo
328 *
329 * Frees the memory for a Critical Section Debug Object
330 *
331 * Params:
332 * DebugInfo - Pointer to Critical Section Debug Object to free.
333 *
334 * Returns:
335 * None.
336 *
337 * Remarks:
338 * If the pointer is part of the static buffer, then the entry is made
339 * free again. If not, the object is de-allocated from the heap.
340 *
341 *--*/
342VOID
343NTAPI
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}
380
381/*++
382 * RtlDeleteCriticalSection
383 * @implemented NT4
384 *
385 * Deletes a Critical Section
386 *
387 * Params:
388 * CriticalSection - Critical section to delete.
389 *
390 * Returns:
391 * STATUS_SUCCESS, or error value returned by NtClose.
392 *
393 * Remarks:
394 * The critical section members should not be read after this call.
395 *
396 *--*/
398NTAPI
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}
440
441/*++
442 * RtlSetCriticalSectionSpinCount
443 * @implemented NT4
444 *
445 * Sets the spin count for a critical section.
446 *
447 * Params:
448 * CriticalSection - Critical section to set the spin count for.
449 *
450 * SpinCount - Spin count for the critical section.
451 *
452 * Returns:
453 * STATUS_SUCCESS.
454 *
455 * Remarks:
456 * SpinCount is ignored on single-processor systems.
457 *
458 *--*/
459ULONG
460NTAPI
462 ULONG SpinCount)
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}
470
471/*++
472 * RtlEnterCriticalSection
473 * @implemented NT4
474 *
475 * Waits to gain ownership of the critical section.
476 *
477 * Params:
478 * CriticalSection - Critical section to wait for.
479 *
480 * Returns:
481 * STATUS_SUCCESS.
482 *
483 * Remarks:
484 * Uses a fast-path unless contention happens.
485 *
486 *--*/
488NTAPI
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}
529
530/*++
531 * RtlInitializeCriticalSection
532 * @implemented NT4
533 *
534 * Initialises a new critical section.
535 *
536 * Params:
537 * CriticalSection - Critical section to initialise
538 *
539 * Returns:
540 * STATUS_SUCCESS.
541 *
542 * Remarks:
543 * Simply calls RtlInitializeCriticalSectionAndSpinCount
544 *
545 *--*/
547NTAPI
549{
550 /* Call the Main Function */
552}
553
554/*++
555 * RtlInitializeCriticalSectionEx
556 * @implemented NT6.0
557 *
558 * Initialises a new critical section.
559 *
560 * Params:
561 * CriticalSection - Critical section to initialise
562 *
563 * SpinCount - Spin count for the critical section.
564 *
565 * Flags - Flags for initialization.
566 *
567 * Returns:
568 * STATUS_SUCCESS.
569 *
570 * Remarks:
571 * SpinCount is ignored on single-processor systems.
572 *
573 *--*/
575NTAPI
578 _In_ ULONG SpinCount,
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}
682
683/*++
684 * RtlInitializeCriticalSectionAndSpinCount
685 * @implemented NT4
686 *
687 * Initialises a new critical section.
688 *
689 * Params:
690 * CriticalSection - Critical section to initialise
691 *
692 * SpinCount - Spin count for the critical section.
693 *
694 * Returns:
695 * STATUS_SUCCESS.
696 *
697 * Remarks:
698 * SpinCount is ignored on single-processor systems.
699 *
700 *--*/
702NTAPI
705 _In_ ULONG SpinCount)
706{
707 SpinCount &= ~RTL_CRITICAL_SECTION_ALL_FLAG_BITS;
709}
710
711/*++
712 * RtlGetCriticalSectionRecursionCount
713 * @implemented NT5.2 SP1
714 *
715 * Retrieves the recursion count of a given critical section.
716 *
717 * Params:
718 * CriticalSection - Critical section to retrieve its recursion count.
719 *
720 * Returns:
721 * The recursion count.
722 *
723 * Remarks:
724 * We return the recursion count of the critical section if it is owned
725 * by the current thread, and otherwise we return zero.
726 *
727 *--*/
728LONG
729NTAPI
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}
749
750/*++
751 * RtlLeaveCriticalSection
752 * @implemented NT4
753 *
754 * Releases a critical section and makes if available for new owners.
755 *
756 * Params:
757 * CriticalSection - Critical section to release.
758 *
759 * Returns:
760 * STATUS_SUCCESS.
761 *
762 * Remarks:
763 * If another thread was waiting, the slow path is entered.
764 *
765 *--*/
767NTAPI
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}
819
820/*++
821 * RtlTryEnterCriticalSection
822 * @implemented NT4
823 *
824 * Attempts to gain ownership of the critical section without waiting.
825 *
826 * Params:
827 * CriticalSection - Critical section to attempt acquiring.
828 *
829 * Returns:
830 * TRUE if the critical section has been acquired, FALSE otherwise.
831 *
832 * Remarks:
833 * None
834 *
835 *--*/
837NTAPI
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}
860
877VOID
878NTAPI
880 _In_ HANDLE ThreadHandle)
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}
958
960NTAPI
962{
963 return CriticalSection->RecursionCount != 0;
964}
965
967NTAPI
969{
970 return CriticalSection->OwningThread == NtCurrentTeb()->ClientId.UniqueThread &&
972}
973
974VOID
975NTAPI
977{
979}
980
981/* EOF */
#define NtCurrentPeb()
Definition: FLS.c:22
unsigned char BOOLEAN
Definition: actypes.h:127
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
HANDLE ProcessHeap
Definition: servman.c:15
#define DPRINT1
Definition: precomp.h:8
#define LongToPtr(l)
Definition: basetsd.h:85
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
NTSTATUS NTAPI RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:768
static BOOLEAN RtlpDebugInfoFreeList[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:24
NTSTATUS NTAPI RtlpWaitForCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:119
VOID NTAPI RtlpInitDeferredCriticalSection(VOID)
Definition: critical.c:274
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
VOID NTAPI RtlpUnWaitCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:219
#define CRITSECT_HAS_DEBUG_INFO(CriticalSection)
Definition: critical.c:35
NTSTATUS NTAPI RtlDeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:399
LONG NTAPI RtlGetCriticalSectionRecursionCount(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:730
LARGE_INTEGER RtlpTimeout
Definition: critical.c:26
NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount(_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount)
Definition: critical.c:703
#define MAX_STATIC_CS_DEBUG_OBJECTS
Definition: critical.c:18
LOGICAL NTAPI RtlTryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:838
NTSTATUS NTAPI RtlInitializeCriticalSectionEx(_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount, _In_ ULONG Flags)
Definition: critical.c:576
VOID NTAPI RtlpNotOwnerCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:976
NTSTATUS NTAPI RtlInitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:548
static BOOLEAN RtlpCritSectInitialized
Definition: critical.c:22
static RTL_CRITICAL_SECTION RtlCriticalSectionLock
Definition: critical.c:20
static RTL_CRITICAL_SECTION_DEBUG RtlpStaticDebugInfo[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:23
ULONG NTAPI RtlSetCriticalSectionSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount)
Definition: critical.c:461
VOID NTAPI RtlCheckForOrphanedCriticalSections(_In_ HANDLE ThreadHandle)
RtlCheckForOrphanedCriticalSections.
Definition: critical.c:879
LOGICAL NTAPI RtlIsCriticalSectionLockedByThread(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:968
PRTL_CRITICAL_SECTION_DEBUG NTAPI RtlpAllocateDebugInfo(VOID)
Definition: critical.c:301
BOOLEAN RtlpCriticalSectionVerifier
Definition: critical.c:28
VOID NTAPI RtlpFreeDebugInfo(PRTL_CRITICAL_SECTION_DEBUG DebugInfo)
Definition: critical.c:344
LOGICAL NTAPI RtlIsCriticalSectionLocked(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:961
BOOLEAN RtlpTimeoutDisable
Definition: critical.c:27
static LIST_ENTRY RtlCriticalSectionList
Definition: critical.c:21
NTSTATUS NTAPI RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:489
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
@ ThreadBasicInformation
Definition: compat.h:935
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
Status
Definition: gdiplustypes.h:24
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
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
#define InterlockedCompareExchange
Definition: interlocked.h:119
#define NtCurrentTeb
CRITICAL_SECTION CriticalSection
Definition: iprtprio.c:40
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
struct _ThreadInfo ThreadInfo
static ULONG OsVersion
static HANDLE hEvent
Definition: comm.c:54
#define _Post_notnull_
Definition: ms_sal.h:701
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSYSAPI VOID NTAPI RtlRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord)
#define RTL_CRITSECT_TYPE
Definition: rtltypes.h:272
#define _At_(t, a)
Definition: no_sal2.h:40
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3429
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
@ SynchronizationEvent
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:463
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
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
#define STATUS_POSSIBLE_DEADLOCK
Definition: ntstatus.h:731
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:570
#define STATUS_RESOURCE_NOT_OWNED
Definition: ntstatus.h:859
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:571
long LONG
Definition: pedump.c:60
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
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
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
struct _RTL_CRITICAL_SECTION * CriticalSection
Definition: rtltypes.h:1433
PRTL_CRITICAL_SECTION_DEBUG DebugInfo
Definition: rtltypes.h:1458
#define NTAPI
Definition: typedefs.h:36
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
ULONG LOGICAL
Definition: umtypes.h:135
#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
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
#define NtCurrentThread()
Definition: winternl.h:5372
NTSYSAPI NTSTATUS WINAPI NtReleaseKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
#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
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151