ReactOS 0.4.16-dev-92-g0c2cdca
resource.c File Reference
#include <rtl.h>
#include <debug.h>
Include dependency graph for resource.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI RtlInitializeResource (PRTL_RESOURCE Resource)
 
VOID NTAPI RtlDeleteResource (PRTL_RESOURCE Resource)
 
BOOLEAN NTAPI RtlAcquireResourceExclusive (PRTL_RESOURCE Resource, BOOLEAN Wait)
 
BOOLEAN NTAPI RtlAcquireResourceShared (PRTL_RESOURCE Resource, BOOLEAN Wait)
 
VOID NTAPI RtlConvertExclusiveToShared (PRTL_RESOURCE Resource)
 
VOID NTAPI RtlConvertSharedToExclusive (PRTL_RESOURCE Resource)
 
VOID NTAPI RtlReleaseResource (PRTL_RESOURCE Resource)
 
VOID NTAPI RtlDumpResource (PRTL_RESOURCE Resource)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file resource.c.

Function Documentation

◆ RtlAcquireResourceExclusive()

BOOLEAN NTAPI RtlAcquireResourceExclusive ( PRTL_RESOURCE  Resource,
BOOLEAN  Wait 
)

Definition at line 85 of file resource.c.

88{
90 BOOLEAN retVal = FALSE;
91
92start:
94 if (Resource->NumberActive == 0) /* lock is free */
95 {
96 Resource->NumberActive = -1;
97 retVal = TRUE;
98 }
99 else if (Resource->NumberActive < 0) /* exclusive lock in progress */
100 {
101 if (Resource->OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
102 {
103 retVal = TRUE;
104 Resource->NumberActive--;
105 goto done;
106 }
107wait:
108 if (Wait)
109 {
110 Resource->ExclusiveWaiters++;
111
113 Status = NtWaitForSingleObject(Resource->ExclusiveSemaphore,
114 FALSE,
115 NULL);
116 if (!NT_SUCCESS(Status))
117 goto done;
118 goto start; /* restart the acquisition to avoid deadlocks */
119 }
120 }
121 else /* one or more shared locks are in progress */
122 {
123 if (Wait)
124 goto wait;
125 }
126 if (retVal)
127 Resource->OwningThread = NtCurrentTeb()->ClientId.UniqueThread;
128done:
130 return retVal;
131}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
#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:33
Status
Definition: gdiplustypes.h:25
GLuint start
Definition: gl.h:1545
#define NtCurrentTeb
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
HANDLE UniqueThread
Definition: compat.h:826
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151

◆ RtlAcquireResourceShared()

BOOLEAN NTAPI RtlAcquireResourceShared ( PRTL_RESOURCE  Resource,
BOOLEAN  Wait 
)

Definition at line 139 of file resource.c.

142{
144 BOOLEAN retVal = FALSE;
145
146start:
148 if (Resource->NumberActive < 0)
149 {
150 if (Resource->OwningThread == NtCurrentTeb()->ClientId.UniqueThread)
151 {
152 Resource->NumberActive--;
153 retVal = TRUE;
154 goto done;
155 }
156
157 if (Wait)
158 {
159 Resource->SharedWaiters++;
161 Status = NtWaitForSingleObject(Resource->SharedSemaphore,
162 FALSE,
163 NULL);
164 if (!NT_SUCCESS(Status))
165 goto done;
166 goto start;
167 }
168 }
169 else
170 {
171 if (Status != STATUS_WAIT_0) /* otherwise RtlReleaseResource() has already done it */
172 Resource->NumberActive++;
173 retVal = TRUE;
174 }
175done:
177 return retVal;
178}
#define STATUS_WAIT_0
Definition: ntstatus.h:237
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

◆ RtlConvertExclusiveToShared()

VOID NTAPI RtlConvertExclusiveToShared ( PRTL_RESOURCE  Resource)

Definition at line 186 of file resource.c.

187{
189
190 if (Resource->NumberActive == -1)
191 {
192 Resource->OwningThread = NULL;
193
194 if (Resource->SharedWaiters > 0)
195 {
196 ULONG n;
197 /* prevent new writers from joining until
198 * all queued readers have done their thing */
199 n = Resource->SharedWaiters;
200 Resource->NumberActive = Resource->SharedWaiters + 1;
201 Resource->SharedWaiters = 0;
202 NtReleaseSemaphore(Resource->SharedSemaphore,
203 n,
204 NULL);
205 }
206 else
207 {
208 Resource->NumberActive = 1;
209 }
210 }
211
213}
GLdouble n
Definition: glext.h:7729
NTSTATUS NTAPI NtReleaseSemaphore(IN HANDLE SemaphoreHandle, IN LONG ReleaseCount, OUT PLONG PreviousCount OPTIONAL)
Definition: sem.c:295
uint32_t ULONG
Definition: typedefs.h:59

◆ RtlConvertSharedToExclusive()

VOID NTAPI RtlConvertSharedToExclusive ( PRTL_RESOURCE  Resource)

Definition at line 221 of file resource.c.

222{
224
226
227 if (Resource->NumberActive == 1)
228 {
229 Resource->OwningThread = NtCurrentTeb()->ClientId.UniqueThread;
230 Resource->NumberActive = -1;
231 }
232 else
233 {
234 Resource->ExclusiveWaiters++;
235
237 Status = NtWaitForSingleObject(Resource->ExclusiveSemaphore,
238 FALSE,
239 NULL);
240 if (!NT_SUCCESS(Status))
241 return;
242
244 Resource->OwningThread = NtCurrentTeb()->ClientId.UniqueThread;
245 Resource->NumberActive = -1;
246 }
248}

◆ RtlDeleteResource()

VOID NTAPI RtlDeleteResource ( PRTL_RESOURCE  Resource)

Definition at line 68 of file resource.c.

69{
71 NtClose(Resource->ExclusiveSemaphore);
72 NtClose(Resource->SharedSemaphore);
73 Resource->OwningThread = NULL;
74 Resource->ExclusiveWaiters = 0;
75 Resource->SharedWaiters = 0;
76 Resource->NumberActive = 0;
77}
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402

◆ RtlDumpResource()

VOID NTAPI RtlDumpResource ( PRTL_RESOURCE  Resource)

Definition at line 311 of file resource.c.

312{
313 DbgPrint("RtlDumpResource(%p):\n\tactive count = %d\n\twaiting readers = %u\n\twaiting writers = %u\n",
314 Resource,
315 Resource->NumberActive,
316 Resource->SharedWaiters,
317 Resource->ExclusiveWaiters);
318
319 if (Resource->NumberActive != 0)
320 {
321 DbgPrint("\towner thread = %p\n",
322 Resource->OwningThread);
323 }
324}
#define DbgPrint
Definition: hal.h:12

◆ RtlInitializeResource()

VOID NTAPI RtlInitializeResource ( PRTL_RESOURCE  Resource)

Definition at line 25 of file resource.c.

26{
28
30 if (!NT_SUCCESS(Status))
31 {
33 }
34
35 Status = NtCreateSemaphore(&Resource->SharedSemaphore,
37 NULL,
38 0,
39 65535);
40 if (!NT_SUCCESS(Status))
41 {
43 }
44 Resource->SharedWaiters = 0;
45
46 Status = NtCreateSemaphore(&Resource->ExclusiveSemaphore,
48 NULL,
49 0,
50 65535);
51 if (!NT_SUCCESS(Status))
52 {
54 }
55
56 Resource->ExclusiveWaiters = 0;
57 Resource->NumberActive = 0;
58 Resource->OwningThread = NULL;
59 Resource->TimeoutBoost = 0; /* no info on this one, default value is 0 */
60}
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSTATUS NTAPI NtCreateSemaphore(OUT PHANDLE SemaphoreHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN LONG InitialCount, IN LONG MaximumCount)
Definition: sem.c:69
#define SEMAPHORE_ALL_ACCESS
Definition: winbase.h:160

◆ RtlReleaseResource()

VOID NTAPI RtlReleaseResource ( PRTL_RESOURCE  Resource)

Definition at line 256 of file resource.c.

257{
259
260 if (Resource->NumberActive > 0) /* have one or more readers */
261 {
262 Resource->NumberActive--;
263 if (Resource->NumberActive == 0)
264 {
265 if (Resource->ExclusiveWaiters > 0)
266 {
267wake_exclusive:
268 Resource->ExclusiveWaiters--;
269 NtReleaseSemaphore(Resource->ExclusiveSemaphore,
270 1,
271 NULL);
272 }
273 }
274 }
275 else if (Resource->NumberActive < 0) /* have a writer, possibly recursive */
276 {
277 Resource->NumberActive++;
278 if (Resource->NumberActive == 0)
279 {
280 Resource->OwningThread = 0;
281 if (Resource->ExclusiveWaiters > 0)
282 {
283 goto wake_exclusive;
284 }
285 else
286 {
287 if (Resource->SharedWaiters > 0)
288 {
289 ULONG n;
290 /* prevent new writers from joining until
291 * all queued readers have done their thing */
292 n = Resource->SharedWaiters;
293 Resource->NumberActive = Resource->SharedWaiters;
294 Resource->SharedWaiters = 0;
295 NtReleaseSemaphore(Resource->SharedSemaphore,
296 n,
297 NULL);
298 }
299 }
300 }
301 }
303}