3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/ntdll/rtl/critical.c
6 * PURPOSE: Critical sections
11 /* INCLUDES ******************************************************************/
13 #include <ddk/ntddk.h>
14 #include <ntdll/rtl.h>
15 #include <ntos/synch.h>
17 #include <ntdll/ntdll.h>
19 /* FUNCTIONS *****************************************************************/
22 RtlDeleteCriticalSection(PCRITICAL_SECTION CriticalSection)
24 NtClose(CriticalSection->LockSemaphore);
25 CriticalSection->Reserved = -1;
29 RtlEnterCriticalSection(PCRITICAL_SECTION CriticalSection)
31 HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread;
34 if (InterlockedIncrement(&CriticalSection->LockCount))
38 if (CriticalSection->OwningThread == Thread)
40 CriticalSection->RecursionCount++;
44 // DbgPrint("Entering wait for critical section\n");
45 Status = NtWaitForSingleObject(CriticalSection->LockSemaphore,
47 if (!NT_SUCCESS(Status))
49 DbgPrint("RtlEnterCriticalSection: Failed to wait (Status %x)\n",
52 // DbgPrint("Left wait for critical section\n");
54 CriticalSection->OwningThread = Thread;
55 CriticalSection->RecursionCount = 1;
58 if ((ret = InterlockedIncrement(&(CriticalSection->LockCount) )) != 1)
60 if (CriticalSection->OwningThread != Thread)
62 NtWaitForSingleObject(CriticalSection->LockSemaphore,
65 CriticalSection->OwningThread = Thread;
70 CriticalSection->OwningThread = Thread;
73 CriticalSection->RecursionCount++;
78 RtlInitializeCriticalSection(PCRITICAL_SECTION CriticalSection)
82 CriticalSection->LockCount = -1;
83 CriticalSection->RecursionCount = 0;
84 CriticalSection->OwningThread = (HANDLE)0;
85 CriticalSection->Reserved = 0;
87 Status = NtCreateSemaphore(&CriticalSection->LockSemaphore,
96 RtlLeaveCriticalSection(PCRITICAL_SECTION CriticalSection)
98 HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread;
100 if (CriticalSection->OwningThread != Thread)
102 DbgPrint("Freeing critical section not owned\n");
106 CriticalSection->RecursionCount--;
107 if (CriticalSection->RecursionCount > 0)
109 InterlockedDecrement(&CriticalSection->LockCount);
112 CriticalSection->OwningThread = 0;
113 if (InterlockedIncrement(&CriticalSection->LockCount) >= 0)
117 Status = NtReleaseSemaphore(CriticalSection->LockSemaphore, 1, NULL);
118 if (!NT_SUCCESS(Status))
120 DbgPrint("Failed to release semaphore (Status %x)\n",
126 CriticalSection->RecursionCount--;
127 if (CriticalSection->RecursionCount == 0)
129 CriticalSection->OwningThread = (HANDLE)-1;
130 // if LockCount > 0 and RecursionCount == 0 there
131 // is a waiting thread
132 // ReleaseSemaphore will fire up a waiting thread
133 if (InterlockedDecrement(&CriticalSection->LockCount) > 0)
135 NtReleaseSemaphore(CriticalSection->LockSemaphore,1,NULL);
140 InterlockedDecrement(&CriticalSection->LockCount);
146 RtlTryEnterCriticalSection(PCRITICAL_SECTION CriticalSection)
148 if (InterlockedCompareExchange((PVOID*)&CriticalSection->LockCount,
149 (PVOID)1, (PVOID)0 ) == 0)
151 CriticalSection->OwningThread =
152 (HANDLE) NtCurrentTeb()->Cid.UniqueThread;
153 CriticalSection->RecursionCount++;
156 if (CriticalSection->OwningThread ==
157 (HANDLE)NtCurrentTeb()->Cid.UniqueThread)
159 CriticalSection->RecursionCount++;