ReactOS  0.4.14-dev-55-g2da92ac
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 
92 start:
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  }
107 wait:
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;
128 done:
130  return retVal;
131 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1176
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
HANDLE UniqueThread
Definition: compat.h:475
Status
Definition: gdiplustypes.h:24
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
GLuint start
Definition: gl.h:1545
IN BOOLEAN Wait
Definition: fatprocs.h:1529
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

◆ RtlAcquireResourceShared()

BOOLEAN NTAPI RtlAcquireResourceShared ( PRTL_RESOURCE  Resource,
BOOLEAN  Wait 
)

Definition at line 139 of file resource.c.

142 {
144  BOOLEAN retVal = FALSE;
145 
146 start:
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  }
175 done:
177  return retVal;
178 }
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define STATUS_WAIT_0
Definition: ntstatus.h:223
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1176
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
HANDLE UniqueThread
Definition: compat.h:475
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
Status
Definition: gdiplustypes.h:24
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
GLuint start
Definition: gl.h:1545
IN BOOLEAN Wait
Definition: fatprocs.h:1529
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

◆ 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
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI NtReleaseSemaphore(IN HANDLE SemaphoreHandle, IN LONG ReleaseCount, OUT PLONG PreviousCount OPTIONAL)
Definition: sem.c:294
unsigned int ULONG
Definition: retypes.h:1

◆ 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 }
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

◆ 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 }
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
NTSYSAPI NTSTATUS NTAPI RtlDeleteCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)

◆ 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: loader.c:25
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848

◆ 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 }
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
LONG NTSTATUS
Definition: precomp.h:26
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
#define SEMAPHORE_ALL_ACCESS
Definition: winbase.h:160
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

◆ 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  {
267 wake_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 }
GLdouble n
Definition: glext.h:7729
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI NtReleaseSemaphore(IN HANDLE SemaphoreHandle, IN LONG ReleaseCount, OUT PLONG PreviousCount OPTIONAL)
Definition: sem.c:294
unsigned int ULONG
Definition: retypes.h:1