2 * reactos ERESOURCE handling by libcaptive
3 * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; exactly version 2 of June 1991 is required
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "reactos/ddk/exfuncs.h" /* self */
23 #include <glib/gmessages.h>
24 #include "reactos/ddk/extypes.h" /* for ERESOURCE */
25 #include "captive/macros.h"
28 #define ERESOURCE_OWNING_COUNT_SHARED(Resource) ((Resource)->OwnerThreads[0].OwnerCount)
29 #define ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource) ((Resource)->OwnerThreads[1].OwnerCount)
32 static gboolean PERESOURE_validate(PERESOURCE Resource)
34 g_return_val_if_fail(Resource!=NULL,FALSE);
36 g_return_val_if_fail(Resource->ActiveCount
37 ==ERESOURCE_OWNING_COUNT_SHARED(Resource)+ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource),FALSE);
44 * ExAcquireResourceExclusiveLite:
45 * @Resource: Resource to acquire for exclusive access.
46 * %NULL value is forbidden.
47 * @Wait: %TRUE if the caller may wait to acquire @Resource.
49 * Acquires a resource exclusively for the calling thread.
51 * Returns: %TRUE if the resource was acquired.
52 * libcaptive always returns %TRUE.
54 BOOLEAN ExAcquireResourceExclusiveLite(PERESOURCE Resource,BOOLEAN Wait)
56 g_return_val_if_fail(PERESOURE_validate(Resource),FALSE);
58 Resource->ActiveCount++;
59 ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)++;
61 g_assert(PERESOURE_validate(Resource));
67 * ExAcquireResourceSharedLite:
68 * @Resource: Resource to acquire.
69 * %NULL value is forbidden.
70 * @Wait: %TRUE if the caller may wait to acquire @Resource.
72 * Shared acquire of resource for the calling thread.
74 * Returns: %TRUE if the resource was acquired.
75 * libcaptive always returns %TRUE.
77 BOOLEAN ExAcquireResourceSharedLite(PERESOURCE Resource,BOOLEAN Wait)
79 g_return_val_if_fail(PERESOURE_validate(Resource),FALSE);
81 Resource->ActiveCount++;
82 ERESOURCE_OWNING_COUNT_SHARED(Resource)++;
84 g_assert(PERESOURE_validate(Resource));
90 * ExConvertExclusiveToSharedLite:
91 * @Resource: Resource to convert access mode.
92 * %NULL value is forbidden.
94 * Converts a given resource from acquired for exclusive access to being
95 * acquired for shared access.
97 * You must already have exclusive access to @Resource before the call.
99 VOID ExConvertExclusiveToSharedLite(PERESOURCE Resource)
101 g_return_if_fail(PERESOURE_validate(Resource));
102 g_return_if_fail(ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)>0);
104 ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)--;
105 ERESOURCE_OWNING_COUNT_SHARED(Resource)++;
107 g_assert(PERESOURE_validate(Resource));
112 * ExAcquireSharedStarveExclusive:
113 * @Resource: Resource to acquire for shared access.
114 * %NULL value is forbidden.
115 * @Wait: %TRUE if the caller should wait to acquire @Resource.
117 * Acquires a given resource for shared access. Current thread has priority
118 * over any threads currently wating for exclusive access to this @Resource.
120 * libcaptive has the same implementation as ExAcquireResourceSharedLite().
122 * Returns: %TRUE if the resource was acquired.
123 * libcaptive always returns %TRUE.
125 BOOLEAN ExAcquireSharedStarveExclusive(PERESOURCE Resource,BOOLEAN Wait)
127 g_return_val_if_fail(PERESOURE_validate(Resource),FALSE);
129 return ExAcquireResourceSharedLite(Resource,Wait);
134 * ExAcquireSharedWaitForExclusive:
135 * @Resource: Resource to acquire for shared access.
136 * %NULL value is forbidden.
137 * @Wait: %TRUE if the caller should wait to acquire @Resource.
139 * Acquires a given resource for shared access. Any threads currently wating
140 * for exclusive access to this @Resource have priority over the current
143 * libcaptive has the same implementation as ExAcquireResourceSharedLite().
145 * Returns: %TRUE if the resource was acquired.
146 * libcaptive always returns %TRUE.
148 BOOLEAN ExAcquireSharedWaitForExclusive(PERESOURCE Resource,BOOLEAN Wait)
150 g_return_val_if_fail(PERESOURE_validate(Resource),FALSE);
152 return ExAcquireResourceSharedLite(Resource,Wait);
157 * ExReleaseResourceForThreadLite:
158 * @Resource: Resource to release.
159 * %NULL value is forbidden.
160 * @ResourceThreadId: Thread which currently owns @Resource.
161 * %NULL value is forbidden.
162 * Value ExGetCurrentResourceThread() required by libcaptive.
164 * Function releases @Resource. @ResourceThreadId must be either exclusive or
165 * shared owner of @Resource.
166 * FIXME: W32 undocumented: Ownership counter is decremented by 1;
167 * @ResourceThreadId may still own @Resource after this function finishes.
168 * FIXME: W32 undocumented: It is expected shared ownership should be released first.
169 * ntfs.sys of NT-5.1sp1 behaviour: Init,AcqExcl,AcqShared,Rel,expectExcl.
170 * Maybe acquire ordering also makes sense?
172 VOID ExReleaseResourceForThreadLite(PERESOURCE Resource,ERESOURCE_THREAD ResourceThreadId)
174 g_return_if_fail(PERESOURE_validate(Resource));
175 g_return_if_fail(ResourceThreadId==ExGetCurrentResourceThread());
176 g_return_if_fail(Resource->ActiveCount>0);
178 /**/ if (ERESOURCE_OWNING_COUNT_SHARED(Resource)>0)
179 ERESOURCE_OWNING_COUNT_SHARED(Resource)--;
180 else if (ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)>0)
181 ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)--;
182 else g_assert_not_reached();
184 Resource->ActiveCount--;
186 g_assert(PERESOURE_validate(Resource));
191 * ExReleaseResourceForThreadLite:
192 * @Resource: Resource to release.
193 * %NULL value is forbidden.
195 * Function releases @Resource. Current thread must be either exclusive or
196 * shared owner of @Resource.
197 * FIXME: W32 undocumented: Ownership counter is decremented by 1;
198 * Current thread may still own @Resource after this function finishes.
199 * FIXME: W32 undocumented: It is expected exclusive ownership should be released first.
201 VOID ExReleaseResourceLite(PERESOURCE Resource)
203 g_return_if_fail(PERESOURE_validate(Resource));
205 return ExReleaseResourceForThreadLite(Resource,ExGetCurrentResourceThread());
210 * ExGetExclusiveWaiterCount:
211 * @Resource: Resource to query.
212 * %NULL value is forbidden.
214 * Reports the number of waiters for exclusive access.
216 * Returns: Number of waiters for exclusive access.
217 * This function always returns 0 by libcaptive.
219 ULONG ExGetExclusiveWaiterCount(PERESOURCE Resource)
221 g_return_val_if_fail(PERESOURE_validate(Resource),0);
228 * ExGetSharedWaiterCount:
229 * @Resource: Resource to query.
230 * %NULL value is forbidden.
232 * Reports the number of currently pending waiters for shared access to
235 * Returns: Number of waiters for shared access.
236 * This function always returns 0 by libcaptive.
238 ULONG ExGetSharedWaiterCount(PERESOURCE Resource)
240 g_return_val_if_fail(PERESOURE_validate(Resource),0);
247 * ExIsResourceAcquiredExclusiveLite:
248 * @Resource: Resource to query.
249 * %NULL value is forbidden.
251 * Query if the calling thread owns exclusive access to @Resource.
253 * Returns: %TRUE if the caller has exclusive access to @Resource,
255 BOOLEAN ExIsResourceAcquiredExclusiveLite(PERESOURCE Resource)
257 g_return_val_if_fail(PERESOURE_validate(Resource),FALSE);
259 return ERESOURCE_OWNING_COUNT_EXCLUSIVE(Resource)>0;
264 * ExIsResourceAcquiredSharedLite:
265 * @Resource: Resource to query.
266 * %NULL value is forbidden.
268 * Query if the calling thread owns shared access to @Resource.
269 * Exclusive access is considered equivalent to shared access in this case.
271 * Returns: Count how many times the caller owns @Resource for any access,
272 * Value 0 is returned if the resource is not owned at all.
274 USHORT ExIsResourceAcquiredSharedLite(PERESOURCE Resource)
276 g_return_val_if_fail(PERESOURE_validate(Resource),0);
278 g_assert(Resource->ActiveCount==(USHORT)Resource->ActiveCount);
279 return Resource->ActiveCount;
284 * ExInitializeResourceLite:
285 * @Resource: Memory block of size #PERESOURCE to initialize.
286 * %NULL value is forbidden.
288 * Initializes fields of #PERESOURCE structure.
290 * Returns: %STATUS_SUCCESS if the resource was initialized successfully.
291 * libcaptive always returns %STATUS_SUCCESS.
293 NTSTATUS ExInitializeResourceLite(PERESOURCE Resource)
295 g_return_val_if_fail(Resource!=NULL,STATUS_INVALID_PARAMETER);
297 CAPTIVE_MEMZERO(Resource);
298 KeInitializeSpinLock(&Resource->SpinLock);
300 g_assert(PERESOURE_validate(Resource));
301 return STATUS_SUCCESS;
306 * ExReinitializeResourceLite:
307 * @Resource: Resource to reinitialize sized as #ERESOURCE.
308 * %NULL value is forbidden.
310 * Reinitialize data fields of @Resource. @Resource must be already initialized
311 * by ExInitializeResourceLite(). Its state is lost and it becomes a fresh new
312 * #ERESOURCED without any its owners.
314 VOID ExReinitializeResourceLite(PERESOURCE Resource)
316 g_return_if_fail(PERESOURE_validate(Resource));
318 ExDeleteResourceLite(Resource); /* errors ignored */
319 ExInitializeResourceLite(Resource); /* errors ignored */
324 * ExDeleteResourceLite:
325 * @Resource: Resource to delete.
326 * %NULL value is forbidden.
328 * Deletes any resources allocated for @Resource. Memory of #ERESOURCE pointer
329 * directly by @Resource is not freed - its storage belongs to the caller.
331 * This function is a NOP for libcaptive.
333 * Returns: %STATUS_SUCCESS if the resource was successfully deleted.
334 * libcaptive always returns %STATUS_SUCCESS.
336 NTSTATUS ExDeleteResourceLite(PERESOURCE Resource)
338 g_return_val_if_fail(PERESOURE_validate(Resource),STATUS_INVALID_PARAMETER);
340 return STATUS_SUCCESS;