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 *****************************************************************/
25 RtlDeleteCriticalSection(PCRITICAL_SECTION CriticalSection)
27 NtClose(CriticalSection->LockSemaphore);
28 CriticalSection->Reserved = -1;
35 RtlEnterCriticalSection(PCRITICAL_SECTION CriticalSection)
37 HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread;
39 if (InterlockedIncrement(&CriticalSection->LockCount))
43 if (CriticalSection->OwningThread == Thread)
45 CriticalSection->RecursionCount++;
49 // DbgPrint("Entering wait for critical section\n");
50 Status = NtWaitForSingleObject(CriticalSection->LockSemaphore,
52 if (!NT_SUCCESS(Status))
54 DbgPrint("RtlEnterCriticalSection: Failed to wait (Status %x)\n",
57 // DbgPrint("Left wait for critical section\n");
59 CriticalSection->OwningThread = Thread;
60 CriticalSection->RecursionCount = 1;
63 if ((ret = InterlockedIncrement(&(CriticalSection->LockCount) )) != 1)
65 if (CriticalSection->OwningThread != Thread)
67 NtWaitForSingleObject(CriticalSection->LockSemaphore,
70 CriticalSection->OwningThread = Thread;
75 CriticalSection->OwningThread = Thread;
78 CriticalSection->RecursionCount++;
86 RtlInitializeCriticalSection(PCRITICAL_SECTION CriticalSection)
90 CriticalSection->LockCount = -1;
91 CriticalSection->RecursionCount = 0;
92 CriticalSection->OwningThread = (HANDLE)0;
93 CriticalSection->Reserved = 0;
95 Status = NtCreateSemaphore(&CriticalSection->LockSemaphore,
107 RtlLeaveCriticalSection(PCRITICAL_SECTION CriticalSection)
109 HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread;
111 if (CriticalSection->OwningThread != Thread)
113 DbgPrint("Freeing critical section not owned\n");
117 CriticalSection->RecursionCount--;
118 if (CriticalSection->RecursionCount > 0)
120 InterlockedDecrement(&CriticalSection->LockCount);
123 CriticalSection->OwningThread = 0;
124 if (InterlockedDecrement(&CriticalSection->LockCount) >= 0)
128 Status = NtReleaseSemaphore(CriticalSection->LockSemaphore, 1, NULL);
129 if (!NT_SUCCESS(Status))
131 DbgPrint("Failed to release semaphore (Status %x)\n",
137 CriticalSection->RecursionCount--;
138 if (CriticalSection->RecursionCount == 0)
140 CriticalSection->OwningThread = (HANDLE)-1;
141 // if LockCount > 0 and RecursionCount == 0 there
142 // is a waiting thread
143 // ReleaseSemaphore will fire up a waiting thread
144 if (InterlockedDecrement(&CriticalSection->LockCount) > 0)
146 NtReleaseSemaphore(CriticalSection->LockSemaphore,1,NULL);
151 InterlockedDecrement(&CriticalSection->LockCount);
160 RtlTryEnterCriticalSection(PCRITICAL_SECTION CriticalSection)
162 if (InterlockedCompareExchange((PVOID*)&CriticalSection->LockCount,
163 (PVOID)0, (PVOID)-1 ) == (PVOID)-1)
165 CriticalSection->OwningThread =
166 (HANDLE) NtCurrentTeb()->Cid.UniqueThread;
167 CriticalSection->RecursionCount = 1;
170 if (CriticalSection->OwningThread ==
171 (HANDLE)NtCurrentTeb()->Cid.UniqueThread)
173 InterlockedIncrement(&CriticalSection->LockCount);
174 CriticalSection->RecursionCount++;