ReactOS 0.4.15-dev-5896-g3f5bcf5
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
25
28
29/* FUNCTIONS *****************************************************************/
30
31/*++
32 * RtlpCreateCriticalSectionSem
33 *
34 * Checks if an Event has been created for the critical section.
35 *
36 * Params:
37 * None
38 *
39 * Returns:
40 * None. Raises an exception if the system call failed.
41 *
42 * Remarks:
43 * None
44 *
45 *--*/
47VOID
49RtlpCreateCriticalSectionSem(PRTL_CRITICAL_SECTION CriticalSection)
50{
52 HANDLE hNewEvent;
54
55 /* Check if we have an event */
56 if (!hEvent)
57 {
58 /* No, so create it */
59 Status = NtCreateEvent(&hNewEvent,
61 NULL,
63 FALSE);
64 if (!NT_SUCCESS(Status))
65 {
66 DPRINT1("Failed to Create Event!\n");
67
68 /*
69 * Use INVALID_HANDLE_VALUE (-1) to signal that
70 * the global keyed event must be used.
71 */
72 hNewEvent = INVALID_HANDLE_VALUE;
73 }
74
75 DPRINT("Created Event: %p\n", hNewEvent);
76
77 /* Exchange the LockSemaphore field with the new handle, if it is still 0 */
79 (PVOID)hNewEvent,
80 NULL) != NULL)
81 {
82 /* Someone else just created an event */
83 if (hNewEvent != INVALID_HANDLE_VALUE)
84 {
85 DPRINT("Closing already created event: %p\n", hNewEvent);
86 NtClose(hNewEvent);
87 }
88 }
89 }
90
91 return;
92}
93
94/*++
95 * RtlpWaitForCriticalSection
96 *
97 * Slow path of RtlEnterCriticalSection. Waits on an Event Object.
98 *
99 * Params:
100 * CriticalSection - Critical section to acquire.
101 *
102 * Returns:
103 * STATUS_SUCCESS, or raises an exception if a deadlock is occuring.
104 *
105 * Remarks:
106 * None
107 *
108 *--*/
110NTAPI
112{
114 EXCEPTION_RECORD ExceptionRecord;
115 BOOLEAN LastChance = FALSE;
116
117 /* Increase the Debug Entry count */
118 DPRINT("Waiting on Critical Section Event: %p %p\n",
121
124
125 /*
126 * If we're shutting down the process, we're allowed to acquire any
127 * critical sections by force (the loader lock in particular)
128 */
130 LdrpShutdownThreadId == NtCurrentTeb()->RealClientId.UniqueThread)
131 {
132 DPRINT("Forcing ownership of critical section %p\n", CriticalSection);
133 return STATUS_SUCCESS;
134 }
135
136 /* Do we have an Event yet? */
138 {
139 RtlpCreateCriticalSectionSem(CriticalSection);
140 }
141
142 for (;;)
143 {
144 /* Increase the number of times we've had contention */
147
148 /* Check if allocating the event failed */
150 {
151 /* Use the global keyed event (NULL as keyed event handle) */
154 FALSE,
155 &RtlpTimeout);
156 }
157 else
158 {
159 /* Wait on the Event */
161 FALSE,
162 &RtlpTimeout);
163 }
164
165 /* We have Timed out */
166 if (Status == STATUS_TIMEOUT)
167 {
168 /* Is this the 2nd time we've timed out? */
169 if (LastChance)
170 {
171 ERROR_DBGBREAK("Deadlock: 0x%p\n", CriticalSection);
172
173 /* Yes it is, we are raising an exception */
174 ExceptionRecord.ExceptionCode = STATUS_POSSIBLE_DEADLOCK;
175 ExceptionRecord.ExceptionFlags = 0;
176 ExceptionRecord.ExceptionRecord = NULL;
177 ExceptionRecord.ExceptionAddress = RtlRaiseException;
178 ExceptionRecord.NumberParameters = 1;
179 ExceptionRecord.ExceptionInformation[0] = (ULONG_PTR)CriticalSection;
180 RtlRaiseException(&ExceptionRecord);
181 }
182
183 /* One more try */
184 LastChance = TRUE;
185 }
186 else
187 {
188 /* If we are here, everything went fine */
189 return STATUS_SUCCESS;
190 }
191 }
192}
193
194/*++
195 * RtlpUnWaitCriticalSection
196 *
197 * Slow path of RtlLeaveCriticalSection. Fires an Event Object.
198 *
199 * Params:
200 * CriticalSection - Critical section to release.
201 *
202 * Returns:
203 * None. Raises an exception if the system call failed.
204 *
205 * Remarks:
206 * None
207 *
208 *--*/
209VOID
210NTAPI
212{
214
215 /* Do we have an Event yet? */
217 {
218 RtlpCreateCriticalSectionSem(CriticalSection);
219 }
220
221 /* Signal the Event */
222 DPRINT("Signaling Critical Section Event: %p, %p\n",
225
226 /* Check if this critical section needs to use the keyed event */
228 {
229 /* Release keyed event */
231 }
232 else
233 {
234 /* Set the event */
236 }
237
238 if (!NT_SUCCESS(Status))
239 {
240 /* We've failed */
241 DPRINT1("Signaling Failed for: %p, %p, 0x%08lx\n",
244 Status);
246 }
247}
248
249/*++
250 * RtlpInitDeferedCriticalSection
251 *
252 * Initializes the Critical Section implementation.
253 *
254 * Params:
255 * None
256 *
257 * Returns:
258 * None.
259 *
260 * Remarks:
261 * After this call, the Process Critical Section list is protected.
262 *
263 *--*/
264VOID
265NTAPI
267{
268 /* Initialize the CS Protecting the List */
270
271 /* It's now safe to enter it */
273}
274
275/*++
276 * RtlpAllocateDebugInfo
277 *
278 * Finds or allocates memory for a Critical Section Debug Object
279 *
280 * Params:
281 * None
282 *
283 * Returns:
284 * A pointer to an empty Critical Section Debug Object.
285 *
286 * Remarks:
287 * For optimization purposes, the first 64 entries can be cached. From
288 * then on, future Critical Sections will allocate memory from the heap.
289 *
290 *--*/
292NTAPI
294{
295 ULONG i;
296
297 /* Try to allocate from our buffer first */
298 for (i = 0; i < MAX_STATIC_CS_DEBUG_OBJECTS; i++)
299 {
300 /* Check if Entry is free */
302 {
303 /* Mark entry in use */
304 DPRINT("Using entry: %lu. Buffer: %p\n", i, &RtlpStaticDebugInfo[i]);
306
307 /* Use free entry found */
308 return &RtlpStaticDebugInfo[i];
309 }
310 }
311
312 /* We are out of static buffer, allocate dynamic */
313 return RtlAllocateHeap(RtlGetProcessHeap(),
314 0,
316}
317
318/*++
319 * RtlpFreeDebugInfo
320 *
321 * Frees the memory for a Critical Section Debug Object
322 *
323 * Params:
324 * DebugInfo - Pointer to Critical Section Debug Object to free.
325 *
326 * Returns:
327 * None.
328 *
329 * Remarks:
330 * If the pointer is part of the static buffer, then the entry is made
331 * free again. If not, the object is de-allocated from the heap.
332 *
333 *--*/
334VOID
335NTAPI
337{
338 SIZE_T EntryId;
339
340 /* Is it part of our cached entries? */
341 if ((DebugInfo >= RtlpStaticDebugInfo) &&
343 {
344 /* Yes. zero it out */
345 RtlZeroMemory(DebugInfo, sizeof(RTL_CRITICAL_SECTION_DEBUG));
346
347 /* Mark as free */
348 EntryId = (DebugInfo - RtlpStaticDebugInfo);
349 DPRINT("Freeing from Buffer: %p. Entry: %Iu inside Process: %p\n",
350 DebugInfo,
351 EntryId,
353 RtlpDebugInfoFreeList[EntryId] = FALSE;
354
355 }
356 else if (!DebugInfo->Flags)
357 {
358 /* It's a dynamic one, so free from the heap */
359 DPRINT("Freeing from Heap: %p inside Process: %p\n",
360 DebugInfo,
362 RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, DebugInfo);
363 }
364 else
365 {
366 /* Wine stores a section name pointer in the Flags member */
367 DPRINT("Assuming static: %p inside Process: %p\n",
368 DebugInfo,
370 }
371}
372
373/*++
374 * RtlDeleteCriticalSection
375 * @implemented NT4
376 *
377 * Deletes a Critical Section
378 *
379 * Params:
380 * CriticalSection - Critical section to delete.
381 *
382 * Returns:
383 * STATUS_SUCCESS, or error value returned by NtClose.
384 *
385 * Remarks:
386 * The critical section members should not be read after this call.
387 *
388 *--*/
390NTAPI
392{
394
395 DPRINT("Deleting Critical Section: %p\n", CriticalSection);
396
397 /* Close the Event Object Handle if it exists */
399 {
400 /* In case NtClose fails, return the status */
402 }
403
404 /* Protect List */
406
408 {
409 /* Remove it from the list */
411#if 0
412 /* We need to preserve Flags for RtlpFreeDebugInfo */
414#endif
415 }
416
417 /* Unprotect */
419
421 {
422 /* Free it */
424 }
425
426 /* Wipe it out */
428
429 /* Return */
430 return Status;
431}
432
433/*++
434 * RtlSetCriticalSectionSpinCount
435 * @implemented NT4
436 *
437 * Sets the spin count for a critical section.
438 *
439 * Params:
440 * CriticalSection - Critical section to set the spin count for.
441 *
442 * SpinCount - Spin count for the critical section.
443 *
444 * Returns:
445 * STATUS_SUCCESS.
446 *
447 * Remarks:
448 * SpinCount is ignored on single-processor systems.
449 *
450 *--*/
451ULONG
452NTAPI
454 ULONG SpinCount)
455{
457
458 /* Set to parameter if MP, or to 0 if this is Uniprocessor */
459 CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
460 return OldCount;
461}
462
463/*++
464 * RtlEnterCriticalSection
465 * @implemented NT4
466 *
467 * Waits to gain ownership of the critical section.
468 *
469 * Params:
470 * CriticalSection - Critical section to wait for.
471 *
472 * Returns:
473 * STATUS_SUCCESS.
474 *
475 * Remarks:
476 * Uses a fast-path unless contention happens.
477 *
478 *--*/
480NTAPI
482{
483 HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread;
484
485 /* Try to lock it */
487 {
488 /* We've failed to lock it! Does this thread actually own it? */
490 {
491 /*
492 * You own it, so you'll get it when you're done with it! No need to
493 * use the interlocked functions as only the thread who already owns
494 * the lock can modify this data.
495 */
497 return STATUS_SUCCESS;
498 }
499
500 /* NOTE - CriticalSection->OwningThread can be NULL here because changing
501 this information is not serialized. This happens when thread a
502 acquires the lock (LockCount == 0) and thread b tries to
503 acquire it as well (LockCount == 1) but thread a hasn't had a
504 chance to set the OwningThread! So it's not an error when
505 OwningThread is NULL here! */
506
507 /* We don't own it, so we must wait for it */
509 }
510
511 /*
512 * Lock successful. Changing this information has not to be serialized
513 * because only one thread at a time can actually change it (the one who
514 * acquired the lock)!
515 */
518 return STATUS_SUCCESS;
519}
520
521/*++
522 * RtlInitializeCriticalSection
523 * @implemented NT4
524 *
525 * Initialises a new critical section.
526 *
527 * Params:
528 * CriticalSection - Critical section to initialise
529 *
530 * Returns:
531 * STATUS_SUCCESS.
532 *
533 * Remarks:
534 * Simply calls RtlInitializeCriticalSectionAndSpinCount
535 *
536 *--*/
538NTAPI
540{
541 /* Call the Main Function */
543}
544
545/*++
546 * RtlInitializeCriticalSectionAndSpinCount
547 * @implemented NT4
548 *
549 * Initialises a new critical section.
550 *
551 * Params:
552 * CriticalSection - Critical section to initialise
553 *
554 * SpinCount - Spin count for the critical section.
555 *
556 * Returns:
557 * STATUS_SUCCESS.
558 *
559 * Remarks:
560 * SpinCount is ignored on single-processor systems.
561 *
562 *--*/
564NTAPI
566 ULONG SpinCount)
567{
568 PRTL_CRITICAL_SECTION_DEBUG CritcalSectionDebugData;
569
570 /* First things first, set up the Object */
571 DPRINT("Initializing Critical Section: %p\n", CriticalSection);
575 CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
577
578 /* Allocate the Debug Data */
579 CritcalSectionDebugData = RtlpAllocateDebugInfo();
580 DPRINT("Allocated Debug Data: %p inside Process: %p\n",
581 CritcalSectionDebugData,
583
584 if (!CritcalSectionDebugData)
585 {
586 /* This is bad! */
587 DPRINT1("Couldn't allocate Debug Data for: %p\n", CriticalSection);
588 return STATUS_NO_MEMORY;
589 }
590
591 /* Set it up */
592 CritcalSectionDebugData->Type = RTL_CRITSECT_TYPE;
593 CritcalSectionDebugData->ContentionCount = 0;
594 CritcalSectionDebugData->EntryCount = 0;
595 CritcalSectionDebugData->CriticalSection = CriticalSection;
596 CritcalSectionDebugData->Flags = 0;
597 CriticalSection->DebugInfo = CritcalSectionDebugData;
598
599 /*
600 * Add it to the List of Critical Sections owned by the process.
601 * If we've initialized the Lock, then use it. If not, then probably
602 * this is the lock initialization itself, so insert it directly.
603 */
605 {
606 DPRINT("Securely Inserting into ProcessLocks: %p, %p, %p\n",
607 &CritcalSectionDebugData->ProcessLocksList,
610
611 /* Protect List */
613
614 /* Add this one */
615 InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
616
617 /* Unprotect */
619 }
620 else
621 {
622 DPRINT("Inserting into ProcessLocks: %p, %p, %p\n",
623 &CritcalSectionDebugData->ProcessLocksList,
626
627 /* Add it directly */
628 InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
629 }
630
631 return STATUS_SUCCESS;
632}
633
634/*++
635 * RtlGetCriticalSectionRecursionCount
636 * @implemented NT5.2 SP1
637 *
638 * Retrieves the recursion count of a given critical section.
639 *
640 * Params:
641 * CriticalSection - Critical section to retrieve its recursion count.
642 *
643 * Returns:
644 * The recursion count.
645 *
646 * Remarks:
647 * We return the recursion count of the critical section if it is owned
648 * by the current thread, and otherwise we return zero.
649 *
650 *--*/
651LONG
652NTAPI
654{
656 {
657 /*
658 * The critical section is owned by the current thread,
659 * therefore retrieve its actual recursion count.
660 */
662 }
663 else
664 {
665 /*
666 * It is not owned by the current thread, so
667 * for this thread there is no recursion.
668 */
669 return 0;
670 }
671}
672
673/*++
674 * RtlLeaveCriticalSection
675 * @implemented NT4
676 *
677 * Releases a critical section and makes if available for new owners.
678 *
679 * Params:
680 * CriticalSection - Critical section to release.
681 *
682 * Returns:
683 * STATUS_SUCCESS.
684 *
685 * Remarks:
686 * If another thread was waiting, the slow path is entered.
687 *
688 *--*/
690NTAPI
692{
693#if DBG
694 HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread;
695
696 /*
697 * In win this case isn't checked. However it's a valid check so it should
698 * only be performed in debug builds!
699 */
701 {
702 DPRINT1("Releasing critical section not owned!\n");
704 }
705#endif
706
707 /*
708 * Decrease the Recursion Count. No need to do this atomically because only
709 * the thread who holds the lock can call this function (unless the program
710 * is totally screwed...
711 */
713 {
715 {
716 DPRINT1("CRITICAL SECTION MESS: Section %p is not acquired!\n", CriticalSection);
717 return STATUS_UNSUCCESSFUL;
718 }
719 /* Someone still owns us, but we are free. This needs to be done atomically. */
721 }
722 else
723 {
724 /*
725 * Nobody owns us anymore. No need to do this atomically.
726 * See comment above.
727 */
729
730 /* Was someone wanting us? This needs to be done atomically. */
732 {
733 /* Let him have us */
735 }
736 }
737
738 /* Sucessful! */
739 return STATUS_SUCCESS;
740}
741
742/*++
743 * RtlTryEnterCriticalSection
744 * @implemented NT4
745 *
746 * Attemps to gain ownership of the critical section without waiting.
747 *
748 * Params:
749 * CriticalSection - Critical section to attempt acquiring.
750 *
751 * Returns:
752 * TRUE if the critical section has been acquired, FALSE otherwise.
753 *
754 * Remarks:
755 * None
756 *
757 *--*/
759NTAPI
761{
762 /* Try to take control */
764 {
765 /* It's ours */
766 CriticalSection->OwningThread = NtCurrentTeb()->ClientId.UniqueThread;
768 return TRUE;
769 }
771 {
772 /* It's already ours */
775 return TRUE;
776 }
777
778 /* It's not ours */
779 return FALSE;
780}
781
782VOID
783NTAPI
785{
787}
788
789ULONG
790NTAPI
792{
793 return CriticalSection->RecursionCount != 0;
794}
795
796ULONG
797NTAPI
799{
800 return CriticalSection->OwningThread == NtCurrentTeb()->ClientId.UniqueThread &&
802}
803
804VOID
805NTAPI
807{
809}
810
811/* EOF */
#define NtCurrentPeb()
Definition: FLS.c:22
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 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:691
static BOOLEAN RtlpDebugInfoFreeList[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:23
NTSTATUS NTAPI RtlpWaitForCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:111
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount)
Definition: critical.c:565
VOID NTAPI RtlpUnWaitCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:211
NTSTATUS NTAPI RtlDeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:391
ULONG NTAPI RtlIsCriticalSectionLockedByThread(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:798
LONG NTAPI RtlGetCriticalSectionRecursionCount(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:653
LARGE_INTEGER RtlpTimeout
Definition: critical.c:24
VOID NTAPI RtlCheckForOrphanedCriticalSections(HANDLE ThreadHandle)
Definition: critical.c:784
VOID NTAPI RtlpInitDeferedCriticalSection(VOID)
Definition: critical.c:266
#define MAX_STATIC_CS_DEBUG_OBJECTS
Definition: critical.c:17
VOID NTAPI RtlpNotOwnerCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:806
ULONG NTAPI RtlIsCriticalSectionLocked(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:791
NTSTATUS NTAPI RtlInitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:539
static BOOLEAN RtlpCritSectInitialized
Definition: critical.c:21
BOOLEAN NTAPI RtlTryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:760
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:453
PRTL_CRITICAL_SECTION_DEBUG NTAPI RtlpAllocateDebugInfo(VOID)
Definition: critical.c:293
VOID NTAPI RtlpFreeDebugInfo(PRTL_CRITICAL_SECTION_DEBUG DebugInfo)
Definition: critical.c:336
static LIST_ENTRY RtlCriticalSectionList
Definition: critical.c:20
NTSTATUS NTAPI RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:481
#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
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_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_RESOURCE_NOT_OWNED
Definition: ntstatus.h:737
long LONG
Definition: pedump.c:60
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
#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
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1165