Author: fireball
Date: Tue Apr 22 15:44:34 2008
New Revision: 33111
URL:
http://svn.reactos.org/svn/reactos?rev=33111&view=rev
Log:
Bug fixes from Alex:
- CDFS should enter a critical region before acquiring a resource.
- "Fix" resource assert during installation by adding some padding at the end of
the VFAT FCB header -- corruption happens at pad 51.
- Once we detect corruption at pad 51, skip the FCB instead of attempting to flush it.
- Fix a serious bug in our detection of incorrect resource usage while APCs are not
disabled.
- Fix a serious bug which caused shared resources not to wake up waiters when it was
released, and which cause it to wake up waiters when there were still active locks held.
New ERESOURCE implementation by Aleksey (thanks to Alex for providing the information
required)
- Remove ERESOURCE_XP concept, and fix the three incorrect and different definitions of
the ERESOURCE structure.
- Fix the ERESOURCE implementation to use the new Vista ERESOURCE type. Two main changes:
* The count is now a 32-bit count called ActiveEntries. ActiveCount is now simply a
flip-flop bit (0/1) for backward compatibility (we set to 0 when active entries is 0, and
1 when active entries is > 0)
* Instead of caching two owners, we only cache one owner, in the OwnerEntry field.
- Optimize some search algorithms slightly (just better code).
- Remove duplicated code for ExReleaseResourceLite and call ExReleaseResourceForThreadLite
instead. Alex says this is ok.
Modified:
trunk/reactos/drivers/filesystems/cdfs/create.c
trunk/reactos/drivers/filesystems/fastfat/flush.c
trunk/reactos/drivers/filesystems/fastfat/vfat.h
trunk/reactos/include/ddk/winddk.h
trunk/reactos/include/ndk/extypes.h
trunk/reactos/ntoskrnl/ex/resource.c
Modified: trunk/reactos/drivers/filesystems/cdfs/create.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/cdfs/c…
==============================================================================
--- trunk/reactos/drivers/filesystems/cdfs/create.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/cdfs/create.c [iso-8859-1] Tue Apr 22 15:44:34 2008
@@ -277,11 +277,13 @@
DeviceExt = DeviceObject->DeviceExtension;
+ KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource,
TRUE);
Status = CdfsCreateFile(DeviceObject,
Irp);
ExReleaseResourceLite(&DeviceExt->DirResource);
+ KeLeaveCriticalRegion();
ByeBye:
Irp->IoStatus.Status = Status;
Modified: trunk/reactos/drivers/filesystems/fastfat/flush.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/flush.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/flush.c [iso-8859-1] Tue Apr 22 15:44:34
2008
@@ -52,6 +52,7 @@
ListEntry = ListEntry->Flink;
if (!vfatFCBIsDirectory(Fcb))
{
+ if (Fcb->PadPad51) continue; // Corrupt FCB
ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
Status = VfatFlushFile(DeviceExt, Fcb);
ExReleaseResourceLite (&Fcb->MainResource);
Modified: trunk/reactos/drivers/filesystems/fastfat/vfat.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/fastfa…
==============================================================================
--- trunk/reactos/drivers/filesystems/fastfat/vfat.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/filesystems/fastfat/vfat.h [iso-8859-1] Tue Apr 22 15:44:34
2008
@@ -322,6 +322,21 @@
{
/* FCB header required by ROS/NT */
FSRTL_COMMON_FCB_HEADER RFCB;
+ ULONG PadPad;
+ ULONG PadPad2;
+ ULONG PadPad3;
+ ULONG PadPad4;
+ ULONG PadPad5;
+ ULONG PadPad50;
+ ULONG PadPad51;
+ ULONG PadPad52;
+ ULONG PadPad53;
+ ULONG PadPad54;
+ ULONG PadPad55;
+ ULONG PadPad56;
+ ULONG PadPad6;
+ ULONG PadPad7;
+ ULONG PadPad8;
SECTION_OBJECT_POINTERS SectionObjectPointers;
ERESOURCE MainResource;
ERESOURCE PagingIoResource;
Modified: trunk/reactos/include/ddk/winddk.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/winddk.h?rev=3…
==============================================================================
--- trunk/reactos/include/ddk/winddk.h [iso-8859-1] (original)
+++ trunk/reactos/include/ddk/winddk.h [iso-8859-1] Tue Apr 22 15:44:34 2008
@@ -3279,22 +3279,25 @@
#define RESOURCE_HASH_TABLE_SIZE 64
-typedef struct _ERESOURCE {
- LIST_ENTRY SystemResourcesList;
- POWNER_ENTRY OwnerTable;
- SHORT ActiveCount;
- USHORT Flag;
- volatile PKSEMAPHORE SharedWaiters;
- volatile PKEVENT ExclusiveWaiters;
- OWNER_ENTRY OwnerThreads[2];
- ULONG ContentionCount;
- USHORT NumberOfSharedWaiters;
- USHORT NumberOfExclusiveWaiters;
- _ANONYMOUS_UNION union {
- PVOID Address;
- ULONG_PTR CreatorBackTraceIndex;
- } DUMMYUNIONNAME;
- KSPIN_LOCK SpinLock;
+typedef struct _ERESOURCE
+{
+ LIST_ENTRY SystemResourcesList;
+ POWNER_ENTRY OwnerTable;
+ SHORT ActiveCount;
+ USHORT Flag;
+ volatile PKSEMAPHORE SharedWaiters;
+ volatile PKEVENT ExclusiveWaiters;
+ OWNER_ENTRY OwnerEntry;
+ ULONG ActiveEntries;
+ ULONG ContentionCount;
+ ULONG NumberOfSharedWaiters;
+ ULONG NumberOfExclusiveWaiters;
+ union
+ {
+ PVOID Address;
+ ULONG_PTR CreatorBackTraceIndex;
+ };
+ KSPIN_LOCK SpinLock;
} ERESOURCE, *PERESOURCE;
typedef struct _DEVOBJ_EXTENSION
Modified: trunk/reactos/include/ndk/extypes.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/extypes.h?rev=…
==============================================================================
--- trunk/reactos/include/ndk/extypes.h [iso-8859-1] (original)
+++ trunk/reactos/include/ndk/extypes.h [iso-8859-1] Tue Apr 22 15:44:34 2008
@@ -377,29 +377,6 @@
);
//
-// Compatibility with Windows XP Drivers using ERESOURCE
-//
-typedef struct _ERESOURCE_XP
-{
- LIST_ENTRY SystemResourcesList;
- POWNER_ENTRY OwnerTable;
- SHORT ActiveCount;
- USHORT Flag;
- PKSEMAPHORE SharedWaiters;
- PKEVENT ExclusiveWaiters;
- OWNER_ENTRY OwnerThreads[2];
- ULONG ContentionCount;
- USHORT NumberOfSharedWaiters;
- USHORT NumberOfExclusiveWaiters;
- union
- {
- PVOID Address;
- ULONG_PTR CreatorBackTraceIndex;
- };
- KSPIN_LOCK SpinLock;
-} ERESOURCE_XP, *PERESOURCE_XP;
-
-//
// Executive Work Queue Structures
//
typedef struct _EX_QUEUE_WORKER_INFO
Modified: trunk/reactos/ntoskrnl/ex/resource.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/resource.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/resource.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ex/resource.c [iso-8859-1] Tue Apr 22 15:44:34 2008
@@ -30,7 +30,7 @@
VOID
FORCEINLINE
-ExAcquireResourceLock(IN PERESOURCE_XP Resource,
+ExAcquireResourceLock(IN PERESOURCE Resource,
IN PKLOCK_QUEUE_HANDLE LockHandle)
{
UNREFERENCED_PARAMETER(Resource);
@@ -42,7 +42,7 @@
VOID
FORCEINLINE
-ExReleaseResourceLock(IN PERESOURCE_XP Resource,
+ExReleaseResourceLock(IN PERESOURCE Resource,
IN PKLOCK_QUEUE_HANDLE LockHandle)
{
UNREFERENCED_PARAMETER(Resource);
@@ -56,7 +56,7 @@
VOID
FORCEINLINE
-ExAcquireResourceLock(IN PERESOURCE_XP Resource,
+ExAcquireResourceLock(IN PERESOURCE Resource,
IN PKLOCK_QUEUE_HANDLE LockHandle)
{
/* Acquire the lock */
@@ -65,7 +65,7 @@
VOID
FORCEINLINE
-ExReleaseResourceLock(IN PERESOURCE_XP Resource,
+ExReleaseResourceLock(IN PERESOURCE Resource,
IN PKLOCK_QUEUE_HANDLE LockHandle)
{
UNREFERENCED_PARAMETER(Resource);
@@ -102,7 +102,7 @@
*--*/
VOID
NTAPI
-ExpVerifyResource(IN PERESOURCE_XP Resource)
+ExpVerifyResource(IN PERESOURCE Resource)
{
/* Verify the resource data */
ASSERT((((ULONG_PTR)Resource) & (sizeof(ULONG_PTR) - 1)) == 0);
@@ -139,12 +139,12 @@
VOID
NTAPI
ExpCheckForApcsDisabled(IN KIRQL Irql,
- IN PERESOURCE_XP Resource,
+ IN PERESOURCE Resource,
IN PKTHREAD Thread)
{
/* Check if we should care and check if we should break */
if ((ExResourceStrict) &&
- (Irql >= APC_LEVEL) &&
+ (Irql < APC_LEVEL) &&
!(((PETHREAD)Thread)->SystemThread) &&
!(Thread->CombinedApcDisable))
{
@@ -201,7 +201,7 @@
*--*/
VOID
NTAPI
-ExpAllocateExclusiveWaiterEvent(IN PERESOURCE_XP Resource,
+ExpAllocateExclusiveWaiterEvent(IN PERESOURCE Resource,
IN PKLOCK_QUEUE_HANDLE LockHandle)
{
PKEVENT Event;
@@ -261,7 +261,7 @@
*--*/
VOID
NTAPI
-ExpAllocateSharedWaiterSemaphore(IN PERESOURCE_XP Resource,
+ExpAllocateSharedWaiterSemaphore(IN PERESOURCE Resource,
IN PKLOCK_QUEUE_HANDLE LockHandle)
{
PKSEMAPHORE Semaphore;
@@ -321,7 +321,7 @@
*--*/
VOID
NTAPI
-ExpExpandResourceOwnerTable(IN PERESOURCE_XP Resource,
+ExpExpandResourceOwnerTable(IN PERESOURCE Resource,
IN PKLOCK_QUEUE_HANDLE LockHandle)
{
POWNER_ENTRY Owner, Table;
@@ -421,53 +421,44 @@
*--*/
POWNER_ENTRY
FASTCALL
-ExpFindFreeEntry(IN PERESOURCE_XP Resource,
+ExpFindFreeEntry(IN PERESOURCE Resource,
IN PKLOCK_QUEUE_HANDLE LockHandle)
{
POWNER_ENTRY Owner, Limit;
- POWNER_ENTRY FreeEntry = NULL;
/* Sanity check */
ASSERT(LockHandle != 0);
- ASSERT(Resource->OwnerThreads[0].OwnerThread != 0);
-
- /* Check if the next built-in entry is free */
- if (!Resource->OwnerThreads[1].OwnerThread)
- {
- /* Return it */
- FreeEntry = &Resource->OwnerThreads[1];
+ ASSERT(Resource->OwnerEntry.OwnerThread != 0);
+
+ /* Get the current table pointer */
+ Owner = Resource->OwnerTable;
+ if (Owner)
+ {
+ /* Set the limit, move to the next owner and loop owner entries */
+ Limit = &Owner[Owner->TableSize];
+ Owner++;
+ while (Owner->OwnerThread)
+ {
+ /* Move to the next one */
+ Owner++;
+
+ /* Check if the entry is free */
+ if (Owner == Limit) goto Expand;
+ }
+
+ /* Update the resource entry */
+ KeGetCurrentThread()->ResourceIndex = (UCHAR)(Owner -
Resource->OwnerTable);
}
else
{
- /* Get the current table pointer */
- Owner = Resource->OwnerTable;
- if (Owner)
- {
- /* Set the limit, move to the next owner and loop owner entries */
- Limit = &Owner[Owner->TableSize];
- Owner++;
- do
- {
- /* Check if the entry is free */
- if (!Owner->OwnerThread)
- {
- /* Update the resource entry and return it */
- KeGetCurrentThread()->ResourceIndex =
- (UCHAR)(Owner - Resource->OwnerTable);
- return Owner;
- }
-
- /* Move to the next one */
- Owner++;
- } while (Owner != Limit);
- }
-
+Expand:
/* No free entry, expand the table */
ExpExpandResourceOwnerTable(Resource, LockHandle);
+ Owner = NULL;
}
/* Return the entry found */
- return FreeEntry;
+ return Owner;
}
/*++
@@ -493,60 +484,78 @@
*--*/
POWNER_ENTRY
FASTCALL
-ExpFindEntryForThread(IN PERESOURCE_XP Resource,
+ExpFindEntryForThread(IN PERESOURCE Resource,
IN ERESOURCE_THREAD Thread,
- IN PKLOCK_QUEUE_HANDLE LockHandle)
+ IN PKLOCK_QUEUE_HANDLE LockHandle,
+ IN BOOLEAN FirstEntryInelligible)
{
POWNER_ENTRY FreeEntry, Owner, Limit;
/* Start by looking in the static array */
- Owner = &Resource->OwnerThreads[0];
+ Owner = &Resource->OwnerEntry;
if (Owner->OwnerThread == Thread) return Owner;
- Owner++;
- if (Owner->OwnerThread == Thread) return Owner;
/* Check if this is a free entry */
- FreeEntry = !Owner->OwnerThread ? Owner : NULL;
-
- /* Loop the table */
+ if ((FirstEntryInelligible) || (Owner->OwnerThread))
+ {
+ /* No free entry */
+ FreeEntry = NULL;
+ }
+ else
+ {
+ /* Use the first entry as our free entry */
+ FreeEntry = Owner;
+ }
+
+ /* Get the current table pointer */
Owner = Resource->OwnerTable;
if (Owner)
{
- /* Calculate the limit, skip the first entry, and start looping */
+ /* Set the limit, move to the next owner and loop owner entries */
Limit = &Owner[Owner->TableSize];
Owner++;
- do
- {
- /* Check if we found a match */
- if (Owner->OwnerThread == Thread)
+ while (Owner->OwnerThread != Thread)
+ {
+ /* Check if we don't have a free entry */
+ if (!FreeEntry)
{
- /* We did, update the index and return it */
- KeGetCurrentThread()->ResourceIndex =
- (UCHAR)(Owner - Resource->OwnerTable);
- return Owner;
+ /* Check if this entry is free */
+ if (!Owner->OwnerThread)
+ {
+ /* Save it as our free entry */
+ FreeEntry = Owner;
+ }
}
- /* If we don't yet have a free entry and this one is, choose it */
- if (!(FreeEntry) && !(Owner->OwnerThread)) FreeEntry = Owner;
+ /* Move to the next one */
Owner++;
- } while (Owner != Limit);
- }
-
- /* Check if it's OK to do an expansion */
- if (!LockHandle) return NULL;
-
- /* If we found a free entry by now, return it */
- if (FreeEntry)
- {
- /* Set the resource index */
- KeGetCurrentThread()->ResourceIndex =
- (UCHAR)(FreeEntry - Resource->OwnerTable);
- return FreeEntry;
- }
-
- /* No free entry, expand the table */
- ExpExpandResourceOwnerTable(Resource, LockHandle);
- return NULL;
+
+ /* Check if the entry is free */
+ if (Owner == Limit) goto Expand;
+ }
+
+ /* Update the resource entry */
+ KeGetCurrentThread()->ResourceIndex = (UCHAR)(Owner -
Resource->OwnerTable);
+ return Owner;
+ }
+ else
+ {
+Expand:
+ /* Check if it's OK to do an expansion */
+ if (!LockHandle) return NULL;
+
+ /* If we found a free entry by now, return it */
+ if (FreeEntry)
+ {
+ /* Set the resource index */
+ KeGetCurrentThread()->ResourceIndex = (UCHAR)(FreeEntry -
Resource->OwnerTable);
+ return FreeEntry;
+ }
+
+ /* No free entry, expand the table */
+ ExpExpandResourceOwnerTable(Resource, LockHandle);
+ return NULL;
+ }
}
/*++
@@ -614,7 +623,7 @@
*--*/
VOID
FASTCALL
-ExpWaitForResource(IN PERESOURCE_XP Resource,
+ExpWaitForResource(IN PERESOURCE Resource,
IN PVOID Object)
{
ULONG i;
@@ -656,19 +665,16 @@
/* Dump debug information */
DPRINT1("Resource @ %lx\n", Resource);
- DPRINT1(" ActiveCount = %04lx Flags = %s%s%s\n",
- Resource->ActiveCount,
+ DPRINT1(" ActiveEntries = %04lx Flags = %s%s%s\n",
+ Resource->ActiveEntries,
IsOwnedExclusive(Resource) ? "IsOwnedExclusive " :
"",
IsSharedWaiting(Resource) ? "SharedWaiter " :
"",
IsExclusiveWaiting(Resource) ? "ExclusiveWaiter " :
"");
DPRINT1(" NumberOfExclusiveWaiters = %04lx\n",
Resource->NumberOfExclusiveWaiters);
DPRINT1(" Thread = %08lx, Count = %02x\n",
- Resource->OwnerThreads[0].OwnerThread,
- Resource->OwnerThreads[0].OwnerCount);
- DPRINT1(" Thread = %08lx, Count = %02x\n",
- Resource->OwnerThreads[1].OwnerThread,
- Resource->OwnerThreads[1].OwnerCount);
+ Resource->OwnerEntry.OwnerThread,
+ Resource->OwnerEntry.OwnerCount);
/* Dump out the table too */
Owner = Resource->OwnerTable;
@@ -702,16 +708,12 @@
Thread->WaitNext = TRUE;
/* Get the owner thread and boost it */
- OwnerThread = (PKTHREAD)Resource->OwnerThreads[0].OwnerThread;
+ OwnerThread = (PKTHREAD)Resource->OwnerEntry.OwnerThread;
if (OwnerThread) ExpBoostOwnerThread(Thread, OwnerThread);
/* If it's a shared resource */
if (!IsOwnedExclusive(Resource))
{
- /* Boost the other owner thread too */
- OwnerThread = (PKTHREAD)Resource->OwnerThreads[1].OwnerThread;
- if (OwnerThread) ExpBoostOwnerThread(Thread, OwnerThread);
-
/* Get the table */
Owner = Resource->OwnerTable;
if (Owner)
@@ -773,13 +775,12 @@
*--*/
BOOLEAN
NTAPI
-ExAcquireResourceExclusiveLite(IN PERESOURCE resource,
+ExAcquireResourceExclusiveLite(IN PERESOURCE Resource,
IN BOOLEAN Wait)
{
KLOCK_QUEUE_HANDLE LockHandle;
ERESOURCE_THREAD Thread;
BOOLEAN Success;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity check */
ASSERT((Resource->Flag & ResourceNeverExclusive) == 0);
@@ -797,14 +798,14 @@
/* Check if there is a shared owner or exclusive owner */
TryAcquire:
- if (Resource->ActiveCount)
- {
- /* Check if it's exclusively owned, and we own it */
+ if (Resource->ActiveEntries)
+ {
+ /* Check if it's exclusively owned, and we own it */
if ((IsOwnedExclusive(Resource)) &&
- (Resource->OwnerThreads[0].OwnerThread == Thread))
+ (Resource->OwnerEntry.OwnerThread == Thread))
{
/* Increase the owning count */
- Resource->OwnerThreads[0].OwnerCount++;
+ Resource->OwnerEntry.OwnerCount++;
Success = TRUE;
}
else
@@ -834,8 +835,7 @@
ExpWaitForResource(Resource, Resource->ExclusiveWaiters);
/* Set owner and return success */
- Resource->OwnerThreads[0].OwnerThread =
- ExGetCurrentResourceThread();
+ Resource->OwnerEntry.OwnerThread = ExGetCurrentResourceThread();
return TRUE;
}
}
@@ -843,10 +843,13 @@
else
{
/* Nobody owns it, so let's! */
+ ASSERT(Resource->ActiveEntries == 0);
+ ASSERT(Resource->ActiveCount == 0);
Resource->Flag |= ResourceOwnedExclusive;
+ Resource->ActiveEntries = 1;
Resource->ActiveCount = 1;
- Resource->OwnerThreads[0].OwnerThread = Thread;
- Resource->OwnerThreads[0].OwnerCount = 1;
+ Resource->OwnerEntry.OwnerThread = Thread;
+ Resource->OwnerEntry.OwnerCount = 1;
Success = TRUE;
}
@@ -887,13 +890,13 @@
*--*/
BOOLEAN
NTAPI
-ExAcquireResourceSharedLite(IN PERESOURCE resource,
+ExAcquireResourceSharedLite(IN PERESOURCE Resource,
IN BOOLEAN Wait)
{
KLOCK_QUEUE_HANDLE LockHandle;
ERESOURCE_THREAD Thread;
POWNER_ENTRY Owner;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
+ BOOLEAN FirstEntryBusy;
/* Get the thread */
Thread = ExGetCurrentResourceThread();
@@ -906,85 +909,112 @@
ExAcquireResourceLock(Resource, &LockHandle);
ExpCheckForApcsDisabled(LockHandle.OldIrql, Resource, (PKTHREAD)Thread);
- /* See if nobody owns us */
-TryAcquire:
- if (!Resource->ActiveCount)
- {
- /* Setup the owner entry */
- Owner = &Resource->OwnerThreads[1];
- Owner->OwnerThread = Thread;
- Owner->OwnerCount = 1;
+ /* Check how many active entries we've got */
+ while (Resource->ActiveEntries != 0)
+ {
+ /* Check if it's exclusively owned */
+ if (IsOwnedExclusive(Resource))
+ {
+ /* Check if we own it */
+ if (Resource->OwnerEntry.OwnerThread == Thread)
+ {
+ /* Increase the owning count */
+ Resource->OwnerEntry.OwnerCount++;
+
+ /* Release the lock and return */
+ ExReleaseResourceLock(Resource, &LockHandle);
+ return TRUE;
+ }
+
+ /* Find a free entry */
+ Owner = ExpFindFreeEntry(Resource, &LockHandle);
+ if (!Owner) continue;
+ }
+ else
+ {
+ /* Resource is shared, find who owns it */
+ FirstEntryBusy = IsExclusiveWaiting(Resource);
+ Owner = ExpFindEntryForThread(Resource,
+ Thread,
+ &LockHandle,
+ FirstEntryBusy);
+ if (!Owner) continue;
+
+ /* Is it us? */
+ if (Owner->OwnerThread == Thread)
+ {
+ /* Increase acquire count and return */
+ Owner->OwnerCount++;
+ ASSERT(Owner->OwnerCount != 0);
+
+ /* Release the lock and return */
+ ExReleaseResourceLock(Resource, &LockHandle);
+ return TRUE;
+ }
+
+ /* Try to find if there are exclusive waiters */
+ if (!FirstEntryBusy)
+ {
+ /* There are none, so acquire it */
+ Owner->OwnerThread = Thread;
+ Owner->OwnerCount = 1;
+
+ /* Check how many active entries we had */
+ if (Resource->ActiveEntries == 0)
+ {
+ /* Set initial counts */
+ ASSERT(Resource->ActiveCount == 0);
+ Resource->ActiveEntries = 1;
+ Resource->ActiveCount = 1;
+ }
+ else
+ {
+ /* Increase active entries */
+ ASSERT(Resource->ActiveCount == 1);
+ Resource->ActiveEntries++;
+ }
+
+ /* Release the lock and return */
+ ExReleaseResourceLock(Resource, &LockHandle);
+ return TRUE;
+ }
+ }
+
+ /* If we got here, then we need to wait. Are we allowed? */
+ if (!Wait)
+ {
+ /* Release the lock and return */
+ ExReleaseResourceLock(Resource, &LockHandle);
+ return FALSE;
+ }
+
+ /* Check if we have a shared waiters semaphore */
+ if (!Resource->SharedWaiters)
+ {
+ /* Allocate it and try another acquire */
+ ExpAllocateSharedWaiterSemaphore(Resource, &LockHandle);
+ }
+ else
+ {
+ /* We have shared waiters, wait for it */
+ break;
+ }
+ }
+
+ /* Did we get here because we don't have active entries? */
+ if (Resource->ActiveEntries == 0)
+ {
+ /* Acquire it */
+ ASSERT(Resource->ActiveEntries == 0);
+ ASSERT(Resource->ActiveCount == 0);
+ Resource->ActiveEntries = 1;
Resource->ActiveCount = 1;
-
+ Resource->OwnerEntry.OwnerThread = Thread;
+ Resource->OwnerEntry.OwnerCount = 1;
+
/* Release the lock and return */
ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
- }
-
- /* Check if it's exclusively owned */
- if (IsOwnedExclusive(Resource))
- {
- /* Check if we own it */
- if (Resource->OwnerThreads[0].OwnerThread == Thread)
- {
- /* Increase the owning count */
- Resource->OwnerThreads[0].OwnerCount++;
-
- /* Release the lock and return */
- ExReleaseResourceLock(Resource, &LockHandle);
- return TRUE;
- }
-
- /* Find a free entry */
- Owner = ExpFindFreeEntry(Resource, &LockHandle);
- if (!Owner) goto TryAcquire;
- }
- else
- {
- /* Resource is shared, find who owns it */
- Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle);
- if (!Owner) goto TryAcquire;
-
- /* Is it us? */
- if (Owner->OwnerThread == Thread)
- {
- /* Increase acquire count and return */
- Owner->OwnerCount++;
- ASSERT(Owner->OwnerCount != 0);
-
- /* Release the lock and return */
- ExReleaseResourceLock(Resource, &LockHandle);
- return TRUE;
- }
-
- /* Try to find if there are exclusive waiters */
- if (!IsExclusiveWaiting(Resource))
- {
- /* There are none, so acquire it */
- Owner->OwnerThread = Thread;
- Owner->OwnerCount = 1;
- Resource->ActiveCount++;
-
- /* Release the lock and return */
- ExReleaseResourceLock(Resource, &LockHandle);
- return TRUE;
- }
- }
-
- /* If we got here, then we need to wait. Are we allowed? */
- if (!Wait)
- {
- /* Release the lock and return */
- ExReleaseResourceLock(Resource, &LockHandle);
- return FALSE;
- }
-
- /* Check if we have a shared waiters semaphore */
- if (!Resource->SharedWaiters)
- {
- /* Allocate it and try another acquire */
- ExpAllocateSharedWaiterSemaphore(Resource, &LockHandle);
- goto TryAcquire;
}
/* Now wait for the resource */
@@ -1038,13 +1068,12 @@
*--*/
BOOLEAN
NTAPI
-ExAcquireSharedStarveExclusive(IN PERESOURCE resource,
+ExAcquireSharedStarveExclusive(IN PERESOURCE Resource,
IN BOOLEAN Wait)
{
KLOCK_QUEUE_HANDLE LockHandle;
ERESOURCE_THREAD Thread;
POWNER_ENTRY Owner;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Get the thread */
Thread = ExGetCurrentResourceThread();
@@ -1056,15 +1085,18 @@
/* Acquire the lock */
ExAcquireResourceLock(Resource, &LockHandle);
- /* See if nobody owns us */
+ /* See if anyone owns it */
TryAcquire:
- if (!Resource->ActiveCount)
+ if (Resource->ActiveEntries == 0)
{
/* Nobody owns it, so let's take control */
+ ASSERT(Resource->ActiveEntries == 0);
+ ASSERT(Resource->ActiveCount == 0);
Resource->ActiveCount = 1;
- Resource->OwnerThreads[1].OwnerThread = Thread;
- Resource->OwnerThreads[1].OwnerCount = 1;
-
+ Resource->ActiveEntries = 1;
+ Resource->OwnerEntry.OwnerThread = Thread;
+ Resource->OwnerEntry.OwnerCount = 1;
+
/* Release the lock and return */
ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
@@ -1074,10 +1106,10 @@
if (IsOwnedExclusive(Resource))
{
/* Check if we own it */
- if (Resource->OwnerThreads[0].OwnerThread == Thread)
+ if (Resource->OwnerEntry.OwnerThread == Thread)
{
/* Increase the owning count */
- Resource->OwnerThreads[0].OwnerCount++;
+ Resource->OwnerEntry.OwnerCount++;
/* Release the lock and return */
ExReleaseResourceLock(Resource, &LockHandle);
@@ -1091,7 +1123,7 @@
else
{
/* Resource is shared, find who owns it */
- Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle);
+ Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle, FALSE);
if (!Owner) goto TryAcquire;
/* Is it us? */
@@ -1109,7 +1141,21 @@
/* Acquire it */
Owner->OwnerThread = Thread;
Owner->OwnerCount = 1;
- Resource->ActiveCount++;
+
+ /* Check how many active entries we had */
+ if (Resource->ActiveEntries == 0)
+ {
+ /* Set initial counts */
+ ASSERT(Resource->ActiveCount == 0);
+ Resource->ActiveEntries = 1;
+ Resource->ActiveCount = 1;
+ }
+ else
+ {
+ /* Increase active entries */
+ ASSERT(Resource->ActiveCount == 1);
+ Resource->ActiveEntries++;
+ }
/* Release the lock and return */
ExReleaseResourceLock(Resource, &LockHandle);
@@ -1176,13 +1222,12 @@
*--*/
BOOLEAN
NTAPI
-ExAcquireSharedWaitForExclusive(IN PERESOURCE resource,
+ExAcquireSharedWaitForExclusive(IN PERESOURCE Resource,
IN BOOLEAN Wait)
{
KLOCK_QUEUE_HANDLE LockHandle;
ERESOURCE_THREAD Thread;
POWNER_ENTRY Owner;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Get the thread */
Thread = ExGetCurrentResourceThread();
@@ -1196,12 +1241,15 @@
/* See if nobody owns us */
TryAcquire:
- if (!Resource->ActiveCount)
+ if (!Resource->ActiveEntries)
{
/* Nobody owns it, so let's take control */
+ ASSERT(Resource->ActiveEntries == 0);
+ ASSERT(Resource->ActiveCount == 0);
Resource->ActiveCount = 1;
- Resource->OwnerThreads[1].OwnerThread = Thread;
- Resource->OwnerThreads[1].OwnerCount = 1;
+ Resource->ActiveEntries = 1;
+ Resource->OwnerEntry.OwnerThread = Thread;
+ Resource->OwnerEntry.OwnerCount = 1;
/* Release the lock and return */
ExReleaseResourceLock(Resource, &LockHandle);
@@ -1212,10 +1260,10 @@
if (IsOwnedExclusive(Resource))
{
/* Check if we own it */
- if (Resource->OwnerThreads[0].OwnerThread == Thread)
+ if (Resource->OwnerEntry.OwnerThread == Thread)
{
/* Increase the owning count */
- Resource->OwnerThreads[0].OwnerCount++;
+ Resource->OwnerEntry.OwnerCount++;
/* Release the lock and return */
ExReleaseResourceLock(Resource, &LockHandle);
@@ -1256,11 +1304,11 @@
ExAcquireResourceLock(Resource, &LockHandle);
/* Find who owns it now */
- while (!(Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle)));
+ while (!(Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle,
TRUE)));
/* Sanity checks */
ASSERT(IsOwnedExclusive(Resource) == FALSE);
- ASSERT(Resource->ActiveCount > 0);
+ ASSERT(Resource->ActiveEntries > 0);
ASSERT(Owner->OwnerThread != Thread);
/* Take control */
@@ -1274,7 +1322,7 @@
else
{
/* Resource is shared, find who owns it */
- Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle);
+ Owner = ExpFindEntryForThread(Resource, Thread, &LockHandle, FALSE);
if (!Owner) goto TryAcquire;
/* Is it us? */
@@ -1292,8 +1340,22 @@
/* No exclusive waiters, so acquire it */
Owner->OwnerThread = Thread;
Owner->OwnerCount = 1;
- Resource->ActiveCount++;
-
+
+ /* Check how many active entries we had */
+ if (Resource->ActiveEntries == 0)
+ {
+ /* Set initial counts */
+ ASSERT(Resource->ActiveCount == 0);
+ Resource->ActiveEntries = 1;
+ Resource->ActiveCount = 1;
+ }
+ else
+ {
+ /* Increase active entries */
+ ASSERT(Resource->ActiveCount == 1);
+ Resource->ActiveEntries++;
+ }
+
/* Release the lock and return */
ExReleaseResourceLock(Resource, &LockHandle);
return TRUE;
@@ -1345,18 +1407,17 @@
*--*/
VOID
NTAPI
-ExConvertExclusiveToSharedLite(IN PERESOURCE resource)
+ExConvertExclusiveToSharedLite(IN PERESOURCE Resource)
{
ULONG OldWaiters;
KLOCK_QUEUE_HANDLE LockHandle;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity checks */
ASSERT(KeIsExecutingDpc() == FALSE);
ExpVerifyResource(Resource);
ASSERT(IsOwnedExclusive(Resource));
- ASSERT(Resource->OwnerThreads[0].OwnerThread ==
(ERESOURCE_THREAD)PsGetCurrentThread());
-
+ ASSERT(Resource->OwnerEntry.OwnerThread ==
(ERESOURCE_THREAD)PsGetCurrentThread());
+
/* Lock the resource */
ExAcquireResourceLock(Resource, &LockHandle);
@@ -1368,7 +1429,7 @@
{
/* Make the waiters active owners */
OldWaiters = Resource->NumberOfSharedWaiters;
- Resource->ActiveCount = Resource->ActiveCount + (USHORT)OldWaiters;
+ Resource->ActiveEntries += OldWaiters;
Resource->NumberOfSharedWaiters = 0;
/* Release lock and wake the waiters */
@@ -1400,10 +1461,9 @@
*--*/
NTSTATUS
NTAPI
-ExDeleteResourceLite(IN PERESOURCE resource)
+ExDeleteResourceLite(IN PERESOURCE Resource)
{
KLOCK_QUEUE_HANDLE LockHandle;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity checks */
ASSERT(IsSharedWaiting(Resource) == FALSE);
@@ -1446,10 +1506,9 @@
*--*/
VOID
NTAPI
-ExDisableResourceBoostLite(IN PERESOURCE resource)
+ExDisableResourceBoostLite(IN PERESOURCE Resource)
{
KLOCK_QUEUE_HANDLE LockHandle;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity check */
ExpVerifyResource(Resource);
@@ -1481,10 +1540,8 @@
*--*/
ULONG
NTAPI
-ExGetExclusiveWaiterCount(IN PERESOURCE resource)
-{
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
-
+ExGetExclusiveWaiterCount(IN PERESOURCE Resource)
+{
/* Return the count */
return Resource->NumberOfExclusiveWaiters;
}
@@ -1506,10 +1563,8 @@
*--*/
ULONG
NTAPI
-ExGetSharedWaiterCount(IN PERESOURCE resource)
-{
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
-
+ExGetSharedWaiterCount(IN PERESOURCE Resource)
+{
/* Return the count */
return Resource->NumberOfSharedWaiters;
}
@@ -1532,13 +1587,12 @@
*--*/
NTSTATUS
NTAPI
-ExInitializeResourceLite(IN PERESOURCE resource)
-{
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
+ExInitializeResourceLite(IN PERESOURCE Resource)
+{
KLOCK_QUEUE_HANDLE LockHandle;
/* Clear the structure */
- RtlZeroMemory(Resource, sizeof(ERESOURCE_XP));
+ RtlZeroMemory(Resource, sizeof(ERESOURCE));
/* Initialize the lock */
KeInitializeSpinLock(&Resource->SpinLock);
@@ -1570,18 +1624,16 @@
*--*/
BOOLEAN
NTAPI
-ExIsResourceAcquiredExclusiveLite(IN PERESOURCE resource)
-{
- ERESOURCE_THREAD Thread = ExGetCurrentResourceThread();
+ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
+{
BOOLEAN IsAcquired = FALSE;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity check */
ExpVerifyResource(Resource);
/* Check if it's exclusively acquired */
if ((IsOwnedExclusive(Resource)) &&
- (Resource->OwnerThreads[0].OwnerThread == Thread))
+ (Resource->OwnerEntry.OwnerThread == ExGetCurrentResourceThread()))
{
/* It is acquired */
IsAcquired = TRUE;
@@ -1611,82 +1663,72 @@
*--*/
ULONG
NTAPI
-ExIsResourceAcquiredSharedLite(IN PERESOURCE resource)
+ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
{
ERESOURCE_THREAD Thread;
ULONG i, Size;
ULONG Count = 0;
KLOCK_QUEUE_HANDLE LockHandle;
POWNER_ENTRY Owner;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity check */
ExpVerifyResource(Resource);
/* Check if nobody owns us */
- if (!Resource->ActiveCount) return 0;
+ if (!Resource->ActiveEntries) return 0;
/* Get the thread */
Thread = ExGetCurrentResourceThread();
/* Check if we are in the thread list */
- if (Resource->OwnerThreads[0].OwnerThread == Thread)
+ if (Resource->OwnerEntry.OwnerThread == Thread)
{
/* Found it, return count */
- Count = Resource->OwnerThreads[0].OwnerCount;
+ Count = Resource->OwnerEntry.OwnerCount;
}
else
{
/* We can't own an exclusive resource at this point */
if (IsOwnedExclusive(Resource)) return 0;
- /* Check if we are in the other thread list */
- if (Resource->OwnerThreads[1].OwnerThread == Thread)
- {
- /* Found it on the second list, return count */
- Count = Resource->OwnerThreads[1].OwnerCount;
- }
- else
- {
- /* Lock the resource */
- ExAcquireResourceLock(Resource, &LockHandle);
-
- /* Not in the list, do a full table look up */
- Owner = Resource->OwnerTable;
- if (Owner)
+ /* Lock the resource */
+ ExAcquireResourceLock(Resource, &LockHandle);
+
+ /* Not in the list, do a full table look up */
+ Owner = Resource->OwnerTable;
+ if (Owner)
+ {
+ /* Get the resource index */
+ i = ((PKTHREAD)Thread)->ResourceIndex;
+ Size = Owner->TableSize;
+
+ /* Check if the index is valid and check if we don't match */
+ if ((i >= Size) || (Owner[i].OwnerThread != Thread))
{
- /* Get the resource index */
- i = ((PKTHREAD)Thread)->ResourceIndex;
- Size = Owner->TableSize;
-
- /* Check if the index is valid and check if we don't match */
- if ((i >= Size) || (Owner[i].OwnerThread != Thread))
+ /* Sh*t! We need to do a full search */
+ for (i = 1; i < Size; i++)
{
- /* Sh*t! We need to do a full search */
- for (i = 1; i < Size; i++)
+ /* Move to next owner */
+ Owner++;
+
+ /* Try to find a match */
+ if (Owner->OwnerThread == Thread)
{
- /* Move to next owner */
- Owner++;
-
- /* Try to find a match */
- if (Owner->OwnerThread == Thread)
- {
- /* Finally! */
- Count = Owner->OwnerCount;
- break;
- }
+ /* Finally! */
+ Count = Owner->OwnerCount;
+ break;
}
}
- else
- {
- /* We found the match directlry */
- Count = Owner[i].OwnerCount;
- }
}
-
- /* Release the lock */
- ExReleaseResourceLock(Resource, &LockHandle);
- }
+ else
+ {
+ /* We found the match directlry */
+ Count = Owner[i].OwnerCount;
+ }
+ }
+
+ /* Release the lock */
+ ExReleaseResourceLock(Resource, &LockHandle);
}
/* Return count */
@@ -1719,13 +1761,12 @@
*--*/
NTSTATUS
NTAPI
-ExReinitializeResourceLite(IN PERESOURCE resource)
+ExReinitializeResourceLite(IN PERESOURCE Resource)
{
PKEVENT Event;
PKSEMAPHORE Semaphore;
ULONG i, Size;
POWNER_ENTRY Owner;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Get the owner table */
Owner = Resource->OwnerTable;
@@ -1744,6 +1785,7 @@
/* Zero the flags and count */
Resource->Flag = 0;
Resource->ActiveCount = 0;
+ Resource->ActiveEntries = 0;
/* Reset the semaphore */
Semaphore = Resource->SharedWaiters;
@@ -1754,10 +1796,8 @@
if (Event) KeInitializeEvent(Event, SynchronizationEvent, FALSE);
/* Clear the resource data */
- Resource->OwnerThreads[0].OwnerThread = 0;
- Resource->OwnerThreads[1].OwnerThread = 0;
- Resource->OwnerThreads[0].OwnerCount = 0;
- Resource->OwnerThreads[1].OwnerCount = 0;
+ Resource->OwnerEntry.OwnerThread = 0;
+ Resource->OwnerEntry.OwnerCount = 0;
Resource->ContentionCount = 0;
Resource->NumberOfSharedWaiters = 0;
Resource->NumberOfExclusiveWaiters = 0;
@@ -1782,178 +1822,10 @@
*--*/
VOID
FASTCALL
-ExReleaseResourceLite(IN PERESOURCE resource)
-{
- ERESOURCE_THREAD Thread;
- ULONG Count, i;
- KLOCK_QUEUE_HANDLE LockHandle;
- POWNER_ENTRY Owner, Limit;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
-
- /* Sanity check */
- ExpVerifyResource(Resource);
-
- /* Get the thread and lock the resource */
- Thread = ExGetCurrentResourceThread();
- ExAcquireResourceLock(Resource, &LockHandle);
- ExpCheckForApcsDisabled(LockHandle.OldIrql, Resource, (PKTHREAD)Thread);
-
- /* Check if it's exclusively owned */
- if (IsOwnedExclusive(Resource))
- {
- /* Decrement owner count and check if we're done */
- ASSERT(Resource->OwnerThreads[0].OwnerCount > 0);
- if (--Resource->OwnerThreads[0].OwnerCount)
- {
- /* Done, release lock! */
- ExReleaseResourceLock(Resource, &LockHandle);
- return;
- }
-
- /* Clear the owner */
- Resource->OwnerThreads[0].OwnerThread = 0;
-
- /* Check the active count */
- ASSERT(Resource->ActiveCount > 0);
- if (!(--Resource->ActiveCount))
- {
- /* Check if there are shared waiters */
- if (IsSharedWaiting(Resource))
- {
- /* Remove the exclusive flag */
- Resource->Flag &= ~ResourceOwnedExclusive;
-
- /* Give ownership to another thread */
- Count = Resource->NumberOfSharedWaiters;
- Resource->ActiveCount = (SHORT)Count;
- Resource->NumberOfSharedWaiters = 0;
-
- /* Release lock and let someone else have it */
- ExReleaseResourceLock(Resource, &LockHandle);
- KeReleaseSemaphore(Resource->SharedWaiters, 0, Count, FALSE);
- return;
- }
- else if (IsExclusiveWaiting(Resource))
- {
- /* Give exclusive access */
- Resource->OwnerThreads[0].OwnerThread = 1;
- Resource->OwnerThreads[0].OwnerCount = 1;
- Resource->ActiveCount = 1;
- Resource->NumberOfExclusiveWaiters--;
-
- /* Release the lock and give it away */
- ExReleaseResourceLock(Resource, &LockHandle);
- KeSetEventBoostPriority(Resource->ExclusiveWaiters,
- (PKTHREAD*)
- &Resource->OwnerThreads[0].OwnerThread);
- return;
- }
- }
-
- /* Remove the exclusive flag */
- Resource->Flag &= ~ResourceOwnedExclusive;
- }
- else
- {
- /* Check if we are in the thread list */
- if (Resource->OwnerThreads[1].OwnerThread == Thread)
- {
- /* Found it, get owner */
- Owner = &Resource->OwnerThreads[1];
- }
- else if (Resource->OwnerThreads[0].OwnerThread == Thread)
- {
- /* Found it, get owner */
- Owner = &Resource->OwnerThreads[0];
- }
- else
- {
- /* Not in the list, do a full table look up */
- i = ((PKTHREAD)Thread)->ResourceIndex;
- Owner = Resource->OwnerTable;
- if (!Owner)
- {
- /* Nobody owns us, bugcheck! */
- KEBUGCHECKEX(RESOURCE_NOT_OWNED,
- (ULONG_PTR)Resource,
- Thread,
- (ULONG_PTR)Resource->OwnerTable,
- (ULONG_PTR)2);
- }
-
- /* Check if we're out of the size and don't match */
- if ((i >= Owner->TableSize) || (Owner[i].OwnerThread != Thread))
- {
- /* Get the last entry */
- Limit = &Owner[Owner->TableSize];
- for (;;)
- {
- /* Move to the next entry */
- Owner++;
-
- /* Check if we don't match */
- if (Owner >= Limit)
- {
- /* Nobody owns us, bugcheck! */
- KEBUGCHECKEX(RESOURCE_NOT_OWNED,
- (ULONG_PTR)Resource,
- Thread,
- (ULONG_PTR)Resource->OwnerTable,
- 2);
- }
-
- /* Check for a match */
- if (Owner->OwnerThread == Thread) break;
- }
- }
- else
- {
- /* Get the entry directly */
- Owner = &Owner[i];
- }
- }
-
- /* Sanity checks */
- ASSERT(Owner->OwnerThread == Thread);
- ASSERT(Owner->OwnerCount > 0);
-
- /* Check if we are the last owner */
- if (--Owner->OwnerCount)
- {
- /* Release lock */
- ExReleaseResourceLock(Resource, &LockHandle);
- return;
- }
-
- /* Clear owner */
- Owner->OwnerThread = 0;
-
- /* See if the resource isn't being owned anymore */
- ASSERT(Resource->ActiveCount > 0);
- if (!(--Resource->ActiveCount))
- {
- /* Check if there's an exclusive waiter */
- if (IsExclusiveWaiting(Resource))
- {
- /* Give exclusive access */
- Resource->Flag |= ResourceOwnedExclusive;
- Resource->OwnerThreads[0].OwnerThread = 1;
- Resource->OwnerThreads[0].OwnerCount = 1;
- Resource->ActiveCount = 1;
- Resource->NumberOfExclusiveWaiters--;
-
- /* Release the lock and give it away */
- ExReleaseResourceLock(Resource, &LockHandle);
- KeSetEventBoostPriority(Resource->ExclusiveWaiters,
- (PKTHREAD*)
- &Resource->OwnerThreads[0].OwnerThread);
- return;
- }
- }
- }
-
- /* Release lock */
- ExReleaseResourceLock(Resource, &LockHandle);
+ExReleaseResourceLite(IN PERESOURCE Resource)
+{
+ /* Just call the For-Thread function */
+ ExReleaseResourceForThreadLite(Resource, (ERESOURCE_THREAD)PsGetCurrentThread());
}
/*++
@@ -1977,14 +1849,13 @@
*--*/
VOID
NTAPI
-ExReleaseResourceForThreadLite(IN PERESOURCE resource,
+ExReleaseResourceForThreadLite(IN PERESOURCE Resource,
IN ERESOURCE_THREAD Thread)
{
ULONG i;
ULONG Count;
KLOCK_QUEUE_HANDLE LockHandle;
POWNER_ENTRY Owner, Limit;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
ASSERT(Thread != 0);
/* Get the thread and lock the resource */
@@ -1998,8 +1869,8 @@
if (IsOwnedExclusive(Resource))
{
/* Decrement owner count and check if we're done */
- ASSERT(Resource->OwnerThreads[0].OwnerThread == Thread);
- if (--Resource->OwnerThreads[0].OwnerCount)
+ ASSERT(Resource->OwnerEntry.OwnerThread == Thread);
+ if (--Resource->OwnerEntry.OwnerCount)
{
/* Done, release lock! */
ExReleaseResourceLock(Resource, &LockHandle);
@@ -2007,60 +1878,56 @@
}
/* Clear the owner */
- Resource->OwnerThreads[0].OwnerThread = 0;
-
- /* See if the resource isn't being owned anymore */
- ASSERT(Resource->ActiveCount > 0);
- if (!(--Resource->ActiveCount))
- {
- /* Check if there are shared waiters */
- if (IsSharedWaiting(Resource))
- {
- /* Remove the exclusive flag */
- Resource->Flag &= ~ResourceOwnedExclusive;
-
- /* Give ownage to another thread */
- Count = Resource->NumberOfSharedWaiters;
- Resource->ActiveCount = (SHORT)Count;
- Resource->NumberOfSharedWaiters = 0;
-
- /* Release lock and let someone else have it */
- ExReleaseResourceLock(Resource, &LockHandle);
- KeReleaseSemaphore(Resource->SharedWaiters, 0, Count, FALSE);
- return;
- }
- else if (IsExclusiveWaiting(Resource))
- {
- /* Give exclusive access */
- Resource->OwnerThreads[0].OwnerThread = 1;
- Resource->OwnerThreads[0].OwnerCount = 1;
- Resource->ActiveCount = 1;
- Resource->NumberOfExclusiveWaiters--;
-
- /* Release the lock and give it away */
- ExReleaseResourceLock(Resource, &LockHandle);
- KeSetEventBoostPriority(Resource->ExclusiveWaiters,
- (PKTHREAD*)
- &Resource->OwnerThreads[0].OwnerThread);
- return;
- }
-
+ Resource->OwnerEntry.OwnerThread = 0;
+
+ /* Decrement the number of active entries */
+ ASSERT(Resource->ActiveEntries == 1);
+ Resource->ActiveEntries--;
+
+ /* Check if there are shared waiters */
+ if (IsSharedWaiting(Resource))
+ {
/* Remove the exclusive flag */
Resource->Flag &= ~ResourceOwnedExclusive;
- }
+
+ /* Give ownage to another thread */
+ Count = Resource->NumberOfSharedWaiters;
+ Resource->ActiveEntries = Count;
+ Resource->NumberOfSharedWaiters = 0;
+
+ /* Release lock and let someone else have it */
+ ASSERT(Resource->ActiveCount = 1);
+ ExReleaseResourceLock(Resource, &LockHandle);
+ KeReleaseSemaphore(Resource->SharedWaiters, 0, Count, FALSE);
+ return;
+ }
+ else if (IsExclusiveWaiting(Resource))
+ {
+ /* Give exclusive access */
+ Resource->OwnerEntry.OwnerThread = 1;
+ Resource->OwnerEntry.OwnerCount = 1;
+ Resource->ActiveEntries = 1;
+ Resource->NumberOfExclusiveWaiters--;
+
+ /* Release the lock and give it away */
+ ASSERT(Resource->ActiveCount = 1);
+ ExReleaseResourceLock(Resource, &LockHandle);
+ KeSetEventBoostPriority(Resource->ExclusiveWaiters,
+
(PKTHREAD*)&Resource->OwnerEntry.OwnerThread);
+ return;
+ }
+
+ /* Remove the exclusive flag */
+ Resource->Flag &= ~ResourceOwnedExclusive;
+ Resource->ActiveCount = 0;
}
else
{
/* Check if we are in the thread list */
- if (Resource->OwnerThreads[0].OwnerThread == Thread)
+ if (Resource->OwnerEntry.OwnerThread == Thread)
{
/* Found it, get owner */
- Owner = &Resource->OwnerThreads[0];
- }
- else if (Resource->OwnerThreads[1].OwnerThread == Thread)
- {
- /* Found it on the second list, get owner */
- Owner = &Resource->OwnerThreads[1];
+ Owner = &Resource->OwnerEntry;
}
else
{
@@ -2111,9 +1978,9 @@
ASSERT(Owner->OwnerCount > 0);
/* Check if we are the last owner */
- if (!(--Owner->OwnerCount))
- {
- /* Release lock */
+ if (--Owner->OwnerCount)
+ {
+ /* There are other owners, release lock */
ExReleaseResourceLock(Resource, &LockHandle);
return;
}
@@ -2122,26 +1989,29 @@
Owner->OwnerThread = 0;
/* See if the resource isn't being owned anymore */
- ASSERT(Resource->ActiveCount > 0);
- if (!(--Resource->ActiveCount))
+ ASSERT(Resource->ActiveEntries > 0);
+ if (!(--Resource->ActiveEntries))
{
/* Check if there's an exclusive waiter */
if (IsExclusiveWaiting(Resource))
{
/* Give exclusive access */
Resource->Flag |= ResourceOwnedExclusive;
- Resource->OwnerThreads[0].OwnerThread = 1;
- Resource->OwnerThreads[0].OwnerCount = 1;
- Resource->ActiveCount = 1;
+ Resource->OwnerEntry.OwnerThread = 1;
+ Resource->OwnerEntry.OwnerCount = 1;
+ Resource->ActiveEntries = 1;
Resource->NumberOfExclusiveWaiters--;
/* Release the lock and give it away */
+ ASSERT(Resource->ActiveCount = 1);
ExReleaseResourceLock(Resource, &LockHandle);
KeSetEventBoostPriority(Resource->ExclusiveWaiters,
- (PKTHREAD*)
- &Resource->OwnerThreads[0].OwnerThread);
+
(PKTHREAD*)&Resource->OwnerEntry.OwnerThread);
return;
}
+
+ /* Clear the active count */
+ Resource->ActiveCount = 0;
}
}
@@ -2180,13 +2050,12 @@
*--*/
VOID
NTAPI
-ExSetResourceOwnerPointer(IN PERESOURCE resource,
+ExSetResourceOwnerPointer(IN PERESOURCE Resource,
IN PVOID OwnerPointer)
{
ERESOURCE_THREAD Thread;
KLOCK_QUEUE_HANDLE LockHandle;
POWNER_ENTRY Owner, ThisOwner;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity check */
ASSERT((OwnerPointer != 0) && (((ULONG_PTR)OwnerPointer & 3) == 3));
@@ -2204,21 +2073,22 @@
if (IsOwnedExclusive(Resource))
{
/* If it's exclusive, set the first entry no matter what */
- ASSERT(Resource->OwnerThreads[0].OwnerThread == Thread);
- ASSERT(Resource->OwnerThreads[0].OwnerCount > 0);
- Resource->OwnerThreads[0].OwnerThread = (ULONG_PTR)OwnerPointer;
+ ASSERT(Resource->OwnerEntry.OwnerThread == Thread);
+ ASSERT(Resource->OwnerEntry.OwnerCount > 0);
+ Resource->OwnerEntry.OwnerThread = (ULONG_PTR)OwnerPointer;
}
else
{
/* Set the thread in both entries */
ThisOwner = ExpFindEntryForThread(Resource,
(ERESOURCE_THREAD)OwnerPointer,
- 0);
- Owner = ExpFindEntryForThread(Resource, Thread, 0);
+ 0,
+ FALSE);
+ Owner = ExpFindEntryForThread(Resource, Thread, 0, FALSE);
if (!Owner)
{
/* Nobody owns it, crash */
- KEBUGCHECKEX(RESOURCE_NOT_OWNED,
+ KeBugCheckEx(RESOURCE_NOT_OWNED,
(ULONG_PTR)Resource,
Thread,
(ULONG_PTR)Resource->OwnerTable,
@@ -2232,8 +2102,8 @@
ThisOwner->OwnerCount += Owner->OwnerCount;
Owner->OwnerCount = 0;
Owner->OwnerThread = 0;
- ASSERT(Resource->ActiveCount >= 2);
- Resource->ActiveCount--;
+ ASSERT(Resource->ActiveEntries >= 2);
+ Resource->ActiveEntries--;
}
else
{
@@ -2264,12 +2134,11 @@
*--*/
BOOLEAN
NTAPI
-ExTryToAcquireResourceExclusiveLite(IN PERESOURCE resource)
+ExTryToAcquireResourceExclusiveLite(IN PERESOURCE Resource)
{
ERESOURCE_THREAD Thread;
KLOCK_QUEUE_HANDLE LockHandle;
BOOLEAN Acquired = FALSE;
- PERESOURCE_XP Resource = (PERESOURCE_XP)resource;
/* Sanity check */
ASSERT((Resource->Flag & ResourceNeverExclusive) == 0);
@@ -2289,16 +2158,17 @@
{
/* No owner, give exclusive access */
Resource->Flag |= ResourceOwnedExclusive;
- Resource->OwnerThreads[0].OwnerThread = Thread;
- Resource->OwnerThreads[0].OwnerCount = 1;
+ Resource->OwnerEntry.OwnerThread = Thread;
+ Resource->OwnerEntry.OwnerCount = 1;
Resource->ActiveCount = 1;
+ Resource->ActiveEntries = 1;
Acquired = TRUE;
}
else if ((IsOwnedExclusive(Resource)) &&
- (Resource->OwnerThreads[0].OwnerThread == Thread))
+ (Resource->OwnerEntry.OwnerThread == Thread))
{
/* Do a recursive acquire */
- Resource->OwnerThreads[0].OwnerCount++;
+ Resource->OwnerEntry.OwnerCount++;
Acquired = TRUE;
}