ReactOS 0.4.15-dev-7712-gbbbcd8e
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
17#define MAX_STATIC_CS_DEBUG_OBJECTS 64
18
24
27
30
31/* FUNCTIONS *****************************************************************/
32
33#define CRITSECT_HAS_DEBUG_INFO(CriticalSection) \
34 (((CriticalSection)->DebugInfo != NULL) && \
35 ((CriticalSection)->DebugInfo != LongToPtr(-1)))
36
37/*++
38 * RtlpCreateCriticalSectionSem
39 *
40 * Checks if an Event has been created for the critical section.
41 *
42 * Params:
43 * None
44 *
45 * Returns:
46 * None. Raises an exception if the system call failed.
47 *
48 * Remarks:
49 * None
50 *
51 *--*/
53VOID
55RtlpCreateCriticalSectionSem(PRTL_CRITICAL_SECTION CriticalSection)
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}
99
100/*++
101 * RtlpWaitForCriticalSection
102 *
103 * Slow path of RtlEnterCriticalSection. Waits on an Event Object.
104 *
105 * Params:
106 * CriticalSection - Critical section to acquire.
107 *
108 * Returns:
109 * STATUS_SUCCESS, or raises an exception if a deadlock is occuring.
110 *
111 * Remarks:
112 * None
113 *
114 *--*/
116NTAPI
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}
199
200/*++
201 * RtlpUnWaitCriticalSection
202 *
203 * Slow path of RtlLeaveCriticalSection. Fires an Event Object.
204 *
205 * Params:
206 * CriticalSection - Critical section to release.
207 *
208 * Returns:
209 * None. Raises an exception if the system call failed.
210 *
211 * Remarks:
212 * None
213 *
214 *--*/
215VOID
216NTAPI
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}
254
255/*++
256 * RtlpInitDeferredCriticalSection
257 *
258 * Initializes the Critical Section implementation.
259 *
260 * Params:
261 * None
262 *
263 * Returns:
264 * None.
265 *
266 * Remarks:
267 * After this call, the Process Critical Section list is protected.
268 *
269 *--*/
270VOID
271NTAPI
273{
274 /* Initialize the CS Protecting the List */
276
277 /* It's now safe to enter it */
279}
280
281/*++
282 * RtlpAllocateDebugInfo
283 *
284 * Finds or allocates memory for a Critical Section Debug Object
285 *
286 * Params:
287 * None
288 *
289 * Returns:
290 * A pointer to an empty Critical Section Debug Object.
291 *
292 * Remarks:
293 * For optimization purposes, the first 64 entries can be cached. From
294 * then on, future Critical Sections will allocate memory from the heap.
295 *
296 *--*/
298NTAPI
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}
323
324/*++
325 * RtlpFreeDebugInfo
326 *
327 * Frees the memory for a Critical Section Debug Object
328 *
329 * Params:
330 * DebugInfo - Pointer to Critical Section Debug Object to free.
331 *
332 * Returns:
333 * None.
334 *
335 * Remarks:
336 * If the pointer is part of the static buffer, then the entry is made
337 * free again. If not, the object is de-allocated from the heap.
338 *
339 *--*/
340VOID
341NTAPI
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}
378
379/*++
380 * RtlDeleteCriticalSection
381 * @implemented NT4
382 *
383 * Deletes a Critical Section
384 *
385 * Params:
386 * CriticalSection - Critical section to delete.
387 *
388 * Returns:
389 * STATUS_SUCCESS, or error value returned by NtClose.
390 *
391 * Remarks:
392 * The critical section members should not be read after this call.
393 *
394 *--*/
396NTAPI
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}
438
439/*++
440 * RtlSetCriticalSectionSpinCount
441 * @implemented NT4
442 *
443 * Sets the spin count for a critical section.
444 *
445 * Params:
446 * CriticalSection - Critical section to set the spin count for.
447 *
448 * SpinCount - Spin count for the critical section.
449 *
450 * Returns:
451 * STATUS_SUCCESS.
452 *
453 * Remarks:
454 * SpinCount is ignored on single-processor systems.
455 *
456 *--*/
457ULONG
458NTAPI
460 ULONG SpinCount)
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}
468
469/*++
470 * RtlEnterCriticalSection
471 * @implemented NT4
472 *
473 * Waits to gain ownership of the critical section.
474 *
475 * Params:
476 * CriticalSection - Critical section to wait for.
477 *
478 * Returns:
479 * STATUS_SUCCESS.
480 *
481 * Remarks:
482 * Uses a fast-path unless contention happens.
483 *
484 *--*/
486NTAPI
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}
526
527/*++
528 * RtlInitializeCriticalSection
529 * @implemented NT4
530 *
531 * Initialises a new critical section.
532 *
533 * Params:
534 * CriticalSection - Critical section to initialise
535 *
536 * Returns:
537 * STATUS_SUCCESS.
538 *
539 * Remarks:
540 * Simply calls RtlInitializeCriticalSectionAndSpinCount
541 *
542 *--*/
544NTAPI
546{
547 /* Call the Main Function */
549}
550
551/*++
552 * RtlInitializeCriticalSectionEx
553 * @implemented NT6.0
554 *
555 * Initialises a new critical section.
556 *
557 * Params:
558 * CriticalSection - Critical section to initialise
559 *
560 * SpinCount - Spin count for the critical section.
561 *
562 * Flags - Flags for initialization.
563 *
564 * Returns:
565 * STATUS_SUCCESS.
566 *
567 * Remarks:
568 * SpinCount is ignored on single-processor systems.
569 *
570 *--*/
572NTAPI
575 _In_ ULONG SpinCount,
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}
679
680/*++
681 * RtlInitializeCriticalSectionAndSpinCount
682 * @implemented NT4
683 *
684 * Initialises a new critical section.
685 *
686 * Params:
687 * CriticalSection - Critical section to initialise
688 *
689 * SpinCount - Spin count for the critical section.
690 *
691 * Returns:
692 * STATUS_SUCCESS.
693 *
694 * Remarks:
695 * SpinCount is ignored on single-processor systems.
696 *
697 *--*/
699NTAPI
702 _In_ ULONG SpinCount)
703{
704 SpinCount &= ~RTL_CRITICAL_SECTION_ALL_FLAG_BITS;
706}
707
708/*++
709 * RtlGetCriticalSectionRecursionCount
710 * @implemented NT5.2 SP1
711 *
712 * Retrieves the recursion count of a given critical section.
713 *
714 * Params:
715 * CriticalSection - Critical section to retrieve its recursion count.
716 *
717 * Returns:
718 * The recursion count.
719 *
720 * Remarks:
721 * We return the recursion count of the critical section if it is owned
722 * by the current thread, and otherwise we return zero.
723 *
724 *--*/
725LONG
726NTAPI
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}
746
747/*++
748 * RtlLeaveCriticalSection
749 * @implemented NT4
750 *
751 * Releases a critical section and makes if available for new owners.
752 *
753 * Params:
754 * CriticalSection - Critical section to release.
755 *
756 * Returns:
757 * STATUS_SUCCESS.
758 *
759 * Remarks:
760 * If another thread was waiting, the slow path is entered.
761 *
762 *--*/
764NTAPI
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}
815
816/*++
817 * RtlTryEnterCriticalSection
818 * @implemented NT4
819 *
820 * Attemps to gain ownership of the critical section without waiting.
821 *
822 * Params:
823 * CriticalSection - Critical section to attempt acquiring.
824 *
825 * Returns:
826 * TRUE if the critical section has been acquired, FALSE otherwise.
827 *
828 * Remarks:
829 * None
830 *
831 *--*/
833NTAPI
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}
855
856VOID
857NTAPI
859{
861}
862
863ULONG
864NTAPI
866{
867 return CriticalSection->RecursionCount != 0;
868}
869
870ULONG
871NTAPI
873{
874 return CriticalSection->OwningThread == NtCurrentTeb()->ClientId.UniqueThread &&
876}
877
878VOID
879NTAPI
881{
883}
884
885/* EOF */
#define NtCurrentPeb()
Definition: FLS.c:22
static ULONG OsVersion
unsigned char BOOLEAN
#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:91
#define UNIMPLEMENTED
Definition: debug.h:115
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
NTSTATUS NTAPI RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:765
static BOOLEAN RtlpDebugInfoFreeList[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:23
NTSTATUS NTAPI RtlpWaitForCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:117
VOID NTAPI RtlpInitDeferredCriticalSection(VOID)
Definition: critical.c:272
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
VOID NTAPI RtlpUnWaitCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:217
#define CRITSECT_HAS_DEBUG_INFO(CriticalSection)
Definition: critical.c:33
NTSTATUS NTAPI RtlDeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:397
ULONG NTAPI RtlIsCriticalSectionLockedByThread(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:872
LONG NTAPI RtlGetCriticalSectionRecursionCount(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:727
LARGE_INTEGER RtlpTimeout
Definition: critical.c:25
VOID NTAPI RtlCheckForOrphanedCriticalSections(HANDLE ThreadHandle)
Definition: critical.c:858
NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount(_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount)
Definition: critical.c:700
#define MAX_STATIC_CS_DEBUG_OBJECTS
Definition: critical.c:17
NTSTATUS NTAPI RtlInitializeCriticalSectionEx(_Out_ PRTL_CRITICAL_SECTION CriticalSection, _In_ ULONG SpinCount, _In_ ULONG Flags)
Definition: critical.c:573
VOID NTAPI RtlpNotOwnerCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:880
ULONG NTAPI RtlIsCriticalSectionLocked(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:865
NTSTATUS NTAPI RtlInitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:545
static BOOLEAN RtlpCritSectInitialized
Definition: critical.c:21
BOOLEAN NTAPI RtlTryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:834
static RTL_CRITICAL_SECTION RtlCriticalSectionLock
Definition: critical.c:19
static RTL_CRITICAL_SECTION_DEBUG RtlpStaticDebugInfo[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:22
ULONG NTAPI RtlSetCriticalSectionSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount)
Definition: critical.c:459
PRTL_CRITICAL_SECTION_DEBUG NTAPI RtlpAllocateDebugInfo(VOID)
Definition: critical.c:299
VOID NTAPI RtlpFreeDebugInfo(PRTL_CRITICAL_SECTION_DEBUG DebugInfo)
Definition: critical.c:342
BOOLEAN RtlpTimeoutDisable
Definition: critical.c:26
static LIST_ENTRY RtlCriticalSectionList
Definition: critical.c:20
NTSTATUS NTAPI RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:487
#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:32
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#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:25
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
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
NTSYSAPI NTSTATUS WINAPI NtReleaseKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define NtCurrentTeb
CRITICAL_SECTION CriticalSection
Definition: iprtprio.c:40
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
static HANDLE hEvent
Definition: comm.c:54
#define _Post_notnull_
Definition: ms_sal.h:701
#define _At_(target, annos)
Definition: ms_sal.h:244
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSYSAPI VOID NTAPI RtlRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord)
#define RTL_CRITSECT_TYPE
Definition: rtltypes.h:264
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
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:455
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 STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_POSSIBLE_DEADLOCK
Definition: ntstatus.h:637
#define STATUS_INVALID_PARAMETER_2
Definition: ntstatus.h:476
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_RESOURCE_NOT_OWNED
Definition: ntstatus.h:737
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:477
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:71
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
LIST_ENTRY ProcessLocksList
Definition: winbase.h:883
ULONG_PTR SpinCount
Definition: winbase.h:899
LONG RecursionCount
Definition: winbase.h:896
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:894
HANDLE LockSemaphore
Definition: winbase.h:898
HANDLE OwningThread
Definition: winbase.h:897
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 _RTL_CRITICAL_SECTION * CriticalSection
Definition: rtltypes.h:1422
#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
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#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
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151