ReactOS  0.4.15-dev-3175-g222acf5
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  *--*/
47 VOID
48 NTAPI
49 RtlpCreateCriticalSectionSem(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  *--*/
109 NTSTATUS
110 NTAPI
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  *--*/
209 VOID
210 NTAPI
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  *--*/
264 VOID
265 NTAPI
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  *--*/
292 NTAPI
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 */
301  if (!RtlpDebugInfoFreeList[i])
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  *--*/
334 VOID
335 NTAPI
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  *--*/
389 NTSTATUS
390 NTAPI
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  *--*/
451 ULONG
452 NTAPI
454  ULONG SpinCount)
455 {
456  ULONG OldCount = (ULONG)CriticalSection->SpinCount;
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  *--*/
479 NTSTATUS
480 NTAPI
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  *--*/
537 NTSTATUS
538 NTAPI
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  *--*/
563 NTSTATUS
564 NTAPI
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  *--*/
651 LONG
652 NTAPI
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  *--*/
689 NTSTATUS
690 NTAPI
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  *--*/
758 BOOLEAN
759 NTAPI
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 
782 VOID
783 NTAPI
785 {
787 }
788 
789 ULONG
790 NTAPI
792 {
793  return CriticalSection->RecursionCount != 0;
794 }
795 
796 ULONG
797 NTAPI
799 {
800  return CriticalSection->OwningThread == NtCurrentTeb()->ClientId.UniqueThread &&
802 }
803 
804 VOID
805 NTAPI
807 {
809 }
810 
811 /* EOF */
static BOOLEAN RtlpDebugInfoFreeList[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:23
VOID NTAPI RtlpUnWaitCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:211
ULONG_PTR SpinCount
Definition: winbase.h:893
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
ULONG NTAPI RtlIsCriticalSectionLocked(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:791
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
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 InterlockedCompareExchange
Definition: interlocked.h:104
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
ULONG NTAPI RtlIsCriticalSectionLockedByThread(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:798
LONG RecursionCount
Definition: winbase.h:890
_At_(CriticalSection->LockSemaphore, _Post_notnull_) VOID NTAPI RtlpCreateCriticalSectionSem(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:46
BOOLEAN NTAPI RtlTryEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:760
#define RTL_CRITSECT_TYPE
Definition: rtltypes.h:262
LARGE_INTEGER RtlpTimeout
Definition: critical.c:24
NTSTATUS NTAPI RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:691
#define InsertTailList(ListHead, Entry)
NTSYSAPI VOID NTAPI RtlRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord)
HANDLE UniqueProcess
Definition: compat.h:684
NTSTATUS NTAPI RtlDeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:391
static BOOLEAN RtlpCritSectInitialized
Definition: critical.c:21
PVOID ExceptionAddress
Definition: compat.h:211
PRTL_CRITICAL_SECTION_DEBUG NTAPI RtlpAllocateDebugInfo(VOID)
Definition: critical.c:293
static HANDLE hEvent
Definition: comm.c:54
VOID NTAPI RtlCheckForOrphanedCriticalSections(HANDLE ThreadHandle)
Definition: critical.c:784
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
DWORD ExceptionCode
Definition: compat.h:208
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
ULONG NTAPI RtlSetCriticalSectionSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount)
Definition: critical.c:453
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
CRITICAL_SECTION CriticalSection
Definition: iprtprio.c:40
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
static LIST_ENTRY RtlCriticalSectionList
Definition: critical.c:20
#define ERROR_DBGBREAK(...)
Definition: debug.h:221
NTSYSAPI NTSTATUS WINAPI NtReleaseKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
#define MAX_STATIC_CS_DEBUG_OBJECTS
Definition: critical.c:17
unsigned char BOOLEAN
HANDLE OwningThread
Definition: winbase.h:891
HANDLE LockSemaphore
Definition: winbase.h:892
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
Status
Definition: gdiplustypes.h:24
VOID NTAPI RtlpFreeDebugInfo(PRTL_CRITICAL_SECTION_DEBUG DebugInfo)
Definition: critical.c:336
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1163
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define _Post_notnull_
Definition: ms_sal.h:701
PVOID HANDLE
Definition: typedefs.h:73
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
static RTL_CRITICAL_SECTION RtlCriticalSectionLock
Definition: critical.c:19
NTSTATUS NTAPI RtlpWaitForCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:111
BOOLEAN LdrpShutdownInProgress
Definition: ldrinit.c:34
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:888
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
HANDLE UniqueThread
Definition: compat.h:685
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
NTSTATUS NTAPI RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:481
NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount)
Definition: critical.c:565
#define InterlockedDecrement
Definition: armddk.h:52
Definition: typedefs.h:119
LIST_ENTRY ProcessLocksList
Definition: winbase.h:877
#define STATUS_POSSIBLE_DEADLOCK
Definition: ntstatus.h:637
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
HANDLE ProcessHeap
Definition: servman.c:15
#define STATUS_RESOURCE_NOT_OWNED
Definition: ntstatus.h:737
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:210
VOID NTAPI RtlpNotOwnerCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:806
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define InterlockedIncrement
Definition: armddk.h:53
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
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 NtCurrentPeb()
Definition: FLS.c:22
VOID NTAPI RtlpInitDeferedCriticalSection(VOID)
Definition: critical.c:266
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define NULL
Definition: types.h:112
static RTL_CRITICAL_SECTION_DEBUG RtlpStaticDebugInfo[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:22
NTSTATUS NTAPI RtlInitializeCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:539
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:115
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
DWORD ExceptionFlags
Definition: compat.h:209
#define STATUS_SUCCESS
Definition: shellext.h:65
DWORD NumberParameters
Definition: compat.h:212
#define DPRINT
Definition: sndvol32.h:71
LONG NTAPI RtlGetCriticalSectionRecursionCount(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:653
struct _RTL_CRITICAL_SECTION * CriticalSection
Definition: rtltypes.h:1420
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)