ReactOS  0.4.14-dev-337-gf981a68
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  /* Do we have an Event yet? */
119  {
120  RtlpCreateCriticalSectionSem(CriticalSection);
121  }
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);
140  return STATUS_SUCCESS;
141  }
142 
143  for (;;)
144  {
145  /* Increase the number of times we've had contention */
148 
149  /* Check if allocating the event failed */
151  {
152  /* Use the global keyed event (NULL as keyed event handle) */
155  FALSE,
156  &RtlpTimeout);
157  }
158  else
159  {
160  /* Wait on the Event */
162  FALSE,
163  &RtlpTimeout);
164  }
165 
166  /* We have Timed out */
167  if (Status == STATUS_TIMEOUT)
168  {
169  /* Is this the 2nd time we've timed out? */
170  if (LastChance)
171  {
172  ERROR_DBGBREAK("Deadlock: 0x%p\n", CriticalSection);
173 
174  /* Yes it is, we are raising an exception */
175  ExceptionRecord.ExceptionCode = STATUS_POSSIBLE_DEADLOCK;
176  ExceptionRecord.ExceptionFlags = 0;
177  ExceptionRecord.ExceptionRecord = NULL;
178  ExceptionRecord.ExceptionAddress = RtlRaiseException;
179  ExceptionRecord.NumberParameters = 1;
180  ExceptionRecord.ExceptionInformation[0] = (ULONG_PTR)CriticalSection;
181  RtlRaiseException(&ExceptionRecord);
182  }
183 
184  /* One more try */
185  LastChance = TRUE;
186  }
187  else
188  {
189  /* If we are here, everything went fine */
190  return STATUS_SUCCESS;
191  }
192  }
193 }
194 
195 /*++
196  * RtlpUnWaitCriticalSection
197  *
198  * Slow path of RtlLeaveCriticalSection. Fires an Event Object.
199  *
200  * Params:
201  * CriticalSection - Critical section to release.
202  *
203  * Returns:
204  * None. Raises an exception if the system call failed.
205  *
206  * Remarks:
207  * None
208  *
209  *--*/
210 VOID
211 NTAPI
213 {
215 
216  /* Do we have an Event yet? */
218  {
219  RtlpCreateCriticalSectionSem(CriticalSection);
220  }
221 
222  /* Signal the Event */
223  DPRINT("Signaling Critical Section Event: %p, %p\n",
226 
227  /* Check if this critical section needs to use the keyed event */
229  {
230  /* Release keyed event */
232  }
233  else
234  {
235  /* Set the event */
237  }
238 
239  if (!NT_SUCCESS(Status))
240  {
241  /* We've failed */
242  DPRINT1("Signaling Failed for: %p, %p, 0x%08lx\n",
245  Status);
247  }
248 }
249 
250 /*++
251  * RtlpInitDeferedCriticalSection
252  *
253  * Initializes the Critical Section implementation.
254  *
255  * Params:
256  * None
257  *
258  * Returns:
259  * None.
260  *
261  * Remarks:
262  * After this call, the Process Critical Section list is protected.
263  *
264  *--*/
265 VOID
266 NTAPI
268 {
269  /* Initialize the Process Critical Section List */
271 
272  /* Initialize the CS Protecting the List */
274 
275  /* It's now safe to enter it */
277 }
278 
279 /*++
280  * RtlpAllocateDebugInfo
281  *
282  * Finds or allocates memory for a Critical Section Debug Object
283  *
284  * Params:
285  * None
286  *
287  * Returns:
288  * A pointer to an empty Critical Section Debug Object.
289  *
290  * Remarks:
291  * For optimization purposes, the first 64 entries can be cached. From
292  * then on, future Critical Sections will allocate memory from the heap.
293  *
294  *--*/
296 NTAPI
298 {
299  ULONG i;
300 
301  /* Try to allocate from our buffer first */
302  for (i = 0; i < MAX_STATIC_CS_DEBUG_OBJECTS; i++)
303  {
304  /* Check if Entry is free */
305  if (!RtlpDebugInfoFreeList[i])
306  {
307  /* Mark entry in use */
308  DPRINT("Using entry: %lu. Buffer: %p\n", i, &RtlpStaticDebugInfo[i]);
310 
311  /* Use free entry found */
312  return &RtlpStaticDebugInfo[i];
313  }
314  }
315 
316  /* We are out of static buffer, allocate dynamic */
317  return RtlAllocateHeap(RtlGetProcessHeap(),
318  0,
320 }
321 
322 /*++
323  * RtlpFreeDebugInfo
324  *
325  * Frees the memory for a Critical Section Debug Object
326  *
327  * Params:
328  * DebugInfo - Pointer to Critical Section Debug Object to free.
329  *
330  * Returns:
331  * None.
332  *
333  * Remarks:
334  * If the pointer is part of the static buffer, then the entry is made
335  * free again. If not, the object is de-allocated from the heap.
336  *
337  *--*/
338 VOID
339 NTAPI
341 {
342  SIZE_T EntryId;
343 
344  /* Is it part of our cached entries? */
345  if ((DebugInfo >= RtlpStaticDebugInfo) &&
347  {
348  /* Yes. zero it out */
349  RtlZeroMemory(DebugInfo, sizeof(RTL_CRITICAL_SECTION_DEBUG));
350 
351  /* Mark as free */
352  EntryId = (DebugInfo - RtlpStaticDebugInfo);
353  DPRINT("Freeing from Buffer: %p. Entry: %Iu inside Process: %p\n",
354  DebugInfo,
355  EntryId,
357  RtlpDebugInfoFreeList[EntryId] = FALSE;
358 
359  }
360  else if (!DebugInfo->Flags)
361  {
362  /* It's a dynamic one, so free from the heap */
363  DPRINT("Freeing from Heap: %p inside Process: %p\n",
364  DebugInfo,
366  RtlFreeHeap(NtCurrentPeb()->ProcessHeap, 0, DebugInfo);
367  }
368  else
369  {
370  /* Wine stores a section name pointer in the Flags member */
371  DPRINT("Assuming static: %p inside Process: %p\n",
372  DebugInfo,
374  }
375 }
376 
377 /*++
378  * RtlDeleteCriticalSection
379  * @implemented NT4
380  *
381  * Deletes a Critical Section
382  *
383  * Params:
384  * CriticalSection - Critical section to delete.
385  *
386  * Returns:
387  * STATUS_SUCCESS, or error value returned by NtClose.
388  *
389  * Remarks:
390  * The critical section members should not be read after this call.
391  *
392  *--*/
393 NTSTATUS
394 NTAPI
396 {
398 
399  DPRINT("Deleting Critical Section: %p\n", CriticalSection);
400 
401  /* Close the Event Object Handle if it exists */
403  {
404  /* In case NtClose fails, return the status */
406  }
407 
408  /* Protect List */
410 
412  {
413  /* Remove it from the list */
415 #if 0
416  /* We need to preserve Flags for RtlpFreeDebugInfo */
418 #endif
419  }
420 
421  /* Unprotect */
423 
425  {
426  /* Free it */
428  }
429 
430  /* Wipe it out */
432 
433  /* Return */
434  return Status;
435 }
436 
437 /*++
438  * RtlSetCriticalSectionSpinCount
439  * @implemented NT4
440  *
441  * Sets the spin count for a critical section.
442  *
443  * Params:
444  * CriticalSection - Critical section to set the spin count for.
445  *
446  * SpinCount - Spin count for the critical section.
447  *
448  * Returns:
449  * STATUS_SUCCESS.
450  *
451  * Remarks:
452  * SpinCount is ignored on single-processor systems.
453  *
454  *--*/
455 ULONG
456 NTAPI
458  ULONG SpinCount)
459 {
460  ULONG OldCount = (ULONG)CriticalSection->SpinCount;
461 
462  /* Set to parameter if MP, or to 0 if this is Uniprocessor */
463  CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
464  return OldCount;
465 }
466 
467 /*++
468  * RtlEnterCriticalSection
469  * @implemented NT4
470  *
471  * Waits to gain ownership of the critical section.
472  *
473  * Params:
474  * CriticalSection - Critical section to wait for.
475  *
476  * Returns:
477  * STATUS_SUCCESS.
478  *
479  * Remarks:
480  * Uses a fast-path unless contention happens.
481  *
482  *--*/
483 NTSTATUS
484 NTAPI
486 {
487  HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread;
488 
489  /* Try to lock it */
491  {
492  /* We've failed to lock it! Does this thread actually own it? */
494  {
495  /*
496  * You own it, so you'll get it when you're done with it! No need to
497  * use the interlocked functions as only the thread who already owns
498  * the lock can modify this data.
499  */
501  return STATUS_SUCCESS;
502  }
503 
504  /* NOTE - CriticalSection->OwningThread can be NULL here because changing
505  this information is not serialized. This happens when thread a
506  acquires the lock (LockCount == 0) and thread b tries to
507  acquire it as well (LockCount == 1) but thread a hasn't had a
508  chance to set the OwningThread! So it's not an error when
509  OwningThread is NULL here! */
510 
511  /* We don't own it, so we must wait for it */
513  }
514 
515  /*
516  * Lock successful. Changing this information has not to be serialized
517  * because only one thread at a time can actually change it (the one who
518  * acquired the lock)!
519  */
522  return STATUS_SUCCESS;
523 }
524 
525 /*++
526  * RtlInitializeCriticalSection
527  * @implemented NT4
528  *
529  * Initialises a new critical section.
530  *
531  * Params:
532  * CriticalSection - Critical section to initialise
533  *
534  * Returns:
535  * STATUS_SUCCESS.
536  *
537  * Remarks:
538  * Simply calls RtlInitializeCriticalSectionAndSpinCount
539  *
540  *--*/
541 NTSTATUS
542 NTAPI
544 {
545  /* Call the Main Function */
547 }
548 
549 /*++
550  * RtlInitializeCriticalSectionAndSpinCount
551  * @implemented NT4
552  *
553  * Initialises a new critical section.
554  *
555  * Params:
556  * CriticalSection - Critical section to initialise
557  *
558  * SpinCount - Spin count for the critical section.
559  *
560  * Returns:
561  * STATUS_SUCCESS.
562  *
563  * Remarks:
564  * SpinCount is ignored on single-processor systems.
565  *
566  *--*/
567 NTSTATUS
568 NTAPI
570  ULONG SpinCount)
571 {
572  PRTL_CRITICAL_SECTION_DEBUG CritcalSectionDebugData;
573 
574  /* First things first, set up the Object */
575  DPRINT("Initializing Critical Section: %p\n", CriticalSection);
579  CriticalSection->SpinCount = (NtCurrentPeb()->NumberOfProcessors > 1) ? SpinCount : 0;
581 
582  /* Allocate the Debug Data */
583  CritcalSectionDebugData = RtlpAllocateDebugInfo();
584  DPRINT("Allocated Debug Data: %p inside Process: %p\n",
585  CritcalSectionDebugData,
587 
588  if (!CritcalSectionDebugData)
589  {
590  /* This is bad! */
591  DPRINT1("Couldn't allocate Debug Data for: %p\n", CriticalSection);
592  return STATUS_NO_MEMORY;
593  }
594 
595  /* Set it up */
596  CritcalSectionDebugData->Type = RTL_CRITSECT_TYPE;
597  CritcalSectionDebugData->ContentionCount = 0;
598  CritcalSectionDebugData->EntryCount = 0;
599  CritcalSectionDebugData->CriticalSection = CriticalSection;
600  CritcalSectionDebugData->Flags = 0;
601  CriticalSection->DebugInfo = CritcalSectionDebugData;
602 
603  /*
604  * Add it to the List of Critical Sections owned by the process.
605  * If we've initialized the Lock, then use it. If not, then probably
606  * this is the lock initialization itself, so insert it directly.
607  */
609  {
610  DPRINT("Securely Inserting into ProcessLocks: %p, %p, %p\n",
611  &CritcalSectionDebugData->ProcessLocksList,
614 
615  /* Protect List */
617 
618  /* Add this one */
619  InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
620 
621  /* Unprotect */
623  }
624  else
625  {
626  DPRINT("Inserting into ProcessLocks: %p, %p, %p\n",
627  &CritcalSectionDebugData->ProcessLocksList,
630 
631  /* Add it directly */
632  InsertTailList(&RtlCriticalSectionList, &CritcalSectionDebugData->ProcessLocksList);
633  }
634 
635  return STATUS_SUCCESS;
636 }
637 
638 /*++
639  * RtlGetCriticalSectionRecursionCount
640  * @implemented NT5.2 SP1
641  *
642  * Retrieves the recursion count of a given critical section.
643  *
644  * Params:
645  * CriticalSection - Critical section to retrieve its recursion count.
646  *
647  * Returns:
648  * The recursion count.
649  *
650  * Remarks:
651  * We return the recursion count of the critical section if it is owned
652  * by the current thread, and otherwise we return zero.
653  *
654  *--*/
655 LONG
656 NTAPI
658 {
660  {
661  /*
662  * The critical section is owned by the current thread,
663  * therefore retrieve its actual recursion count.
664  */
666  }
667  else
668  {
669  /*
670  * It is not owned by the current thread, so
671  * for this thread there is no recursion.
672  */
673  return 0;
674  }
675 }
676 
677 /*++
678  * RtlLeaveCriticalSection
679  * @implemented NT4
680  *
681  * Releases a critical section and makes if available for new owners.
682  *
683  * Params:
684  * CriticalSection - Critical section to release.
685  *
686  * Returns:
687  * STATUS_SUCCESS.
688  *
689  * Remarks:
690  * If another thread was waiting, the slow path is entered.
691  *
692  *--*/
693 NTSTATUS
694 NTAPI
696 {
697 #if DBG
698  HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread;
699 
700  /*
701  * In win this case isn't checked. However it's a valid check so it should
702  * only be performed in debug builds!
703  */
705  {
706  DPRINT1("Releasing critical section not owned!\n");
708  }
709 #endif
710 
711  /*
712  * Decrease the Recursion Count. No need to do this atomically because only
713  * the thread who holds the lock can call this function (unless the program
714  * is totally screwed...
715  */
717  {
718  /* Someone still owns us, but we are free. This needs to be done atomically. */
720 
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 /* EOF */
static BOOLEAN RtlpDebugInfoFreeList[MAX_STATIC_CS_DEBUG_OBJECTS]
Definition: critical.c:23
VOID NTAPI RtlpUnWaitCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:212
ULONG_PTR SpinCount
Definition: winbase.h:871
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS WINAPI NtWaitForKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
ULONG NTAPI RtlIsCriticalSectionLocked(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:791
#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:100
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
ULONG NTAPI RtlIsCriticalSectionLockedByThread(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:798
#define _Post_notnull_
Definition: no_sal2.h:460
LONG RecursionCount
Definition: winbase.h:868
_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:695
#define InsertTailList(ListHead, Entry)
NTSYSAPI VOID NTAPI RtlRaiseException(_In_ PEXCEPTION_RECORD ExceptionRecord)
HANDLE UniqueProcess
Definition: compat.h:482
NTSTATUS NTAPI RtlDeleteCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:395
static BOOLEAN RtlpCritSectInitialized
Definition: critical.c:21
PVOID ExceptionAddress
Definition: compat.h:199
PRTL_CRITICAL_SECTION_DEBUG NTAPI RtlpAllocateDebugInfo(VOID)
Definition: critical.c:297
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:196
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
long LONG
Definition: pedump.c:60
ULONG NTAPI RtlSetCriticalSectionSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount)
Definition: critical.c:457
#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
#define MAX_STATIC_CS_DEBUG_OBJECTS
Definition: critical.c:17
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
HANDLE OwningThread
Definition: winbase.h:869
void DPRINT(...)
Definition: polytest.cpp:61
HANDLE LockSemaphore
Definition: winbase.h:870
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
VOID NTAPI RtlpFreeDebugInfo(PRTL_CRITICAL_SECTION_DEBUG DebugInfo)
Definition: critical.c:340
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:201
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1176
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:458
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PVOID HANDLE
Definition: typedefs.h:71
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
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:866
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
HANDLE UniqueThread
Definition: compat.h:483
NTSTATUS NTAPI RtlEnterCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:485
NTSTATUS NTAPI RtlInitializeCriticalSectionAndSpinCount(PRTL_CRITICAL_SECTION CriticalSection, ULONG SpinCount)
Definition: critical.c:569
#define InterlockedDecrement
Definition: armddk.h:52
Definition: typedefs.h:117
LIST_ENTRY ProcessLocksList
Definition: winbase.h:855
#define STATUS_POSSIBLE_DEADLOCK
Definition: ntstatus.h:623
HANDLE LdrpShutdownThreadId
Definition: ldrinit.c:35
HANDLE ProcessHeap
Definition: servman.c:15
Status
Definition: gdiplustypes.h:24
struct _EXCEPTION_RECORD * ExceptionRecord
Definition: compat.h:198
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define InterlockedIncrement
Definition: armddk.h:53
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define NtCurrentPeb()
Definition: FLS.c:20
VOID NTAPI RtlpInitDeferedCriticalSection(VOID)
Definition: critical.c:267
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSYSAPI NTSTATUS WINAPI NtReleaseKeyedEvent(HANDLE, const void *, BOOLEAN, const LARGE_INTEGER *)
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:543
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
DWORD ExceptionFlags
Definition: compat.h:197
DWORD NumberParameters
Definition: compat.h:200
LONG NTAPI RtlGetCriticalSectionRecursionCount(PRTL_CRITICAL_SECTION CriticalSection)
Definition: critical.c:657
return STATUS_SUCCESS
Definition: btrfs.c:2938
struct _RTL_CRITICAL_SECTION * CriticalSection
Definition: rtltypes.h:1416
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)