/*
* GDIOBJ.C - GDI object manipulation routines
*
- * $Id: gdiobj.c,v 1.67 2004/05/10 17:07:20 weiden Exp $
+ * $Id: gdiobj.c,v 1.73 2004/10/02 16:48:12 navaraf Exp $
*
*/
#include <w32k.h>
static PGDI_HANDLE_TABLE HandleTable = 0;
static FAST_MUTEX HandleTableMutex;
static FAST_MUTEX RefCountHandling;
+static LARGE_INTEGER ShortDelay;
/*!
* Allocate GDI object table.
MemSize = sizeof(GDI_HANDLE_TABLE) + sizeof(PGDIOBJ) * Size;
- /* prevent APC delivery for the *FastMutexUnsafe calls */
- const KIRQL PrevIrql = KfRaiseIrql(APC_LEVEL);
- ExAcquireFastMutexUnsafe (&HandleTableMutex);
+ ExAcquireFastMutex(&HandleTableMutex);
handleTable = ExAllocatePoolWithTag(PagedPool, MemSize, TAG_GDIHNDTBLE);
ASSERT( handleTable );
memset (handleTable, 0, MemSize);
#endif
handleTable->wTableSize = Size;
handleTable->AllocationHint = 1;
- handleTable->LookasideLists = ExAllocatePoolWithTag(NonPagedPool,
+ handleTable->LookasideLists = ExAllocatePoolWithTag(PagedPool,
OBJTYPE_COUNT * sizeof(PAGED_LOOKASIDE_LIST),
TAG_GDIHNDTBLE);
if (NULL == handleTable->LookasideLists)
{
ExFreePool(handleTable);
- ExReleaseFastMutexUnsafe (&HandleTableMutex);
- KfLowerIrql(PrevIrql);
+ ExReleaseFastMutex(&HandleTableMutex);
return NULL;
}
for (ObjType = 0; ObjType < OBJTYPE_COUNT; ObjType++)
ExInitializePagedLookasideList(handleTable->LookasideLists + ObjType, NULL, NULL, 0,
ObjSizes[ObjType].Size + sizeof(GDIOBJHDR), TAG_GDIOBJ, 0);
}
- ExReleaseFastMutexUnsafe (&HandleTableMutex);
- KfLowerIrql(PrevIrql);
+ ExReleaseFastMutex(&HandleTableMutex);
return handleTable;
}
newObject->Magic = GDI_TYPE_TO_MAGIC(ObjectType);
newObject->lockfile = NULL;
newObject->lockline = 0;
+#ifdef GDIOBJ_USE_FASTMUTEX
ExInitializeFastMutex(&newObject->Lock);
+ newObject->RecursiveLockCount = 0;
+#else
+ newObject->LockTid = 0;
+ newObject->LockCount = 0;
+#endif
HandleTable->Handles[Index] = newObject;
#if GDI_COUNT_OBJECTS
HandleTable->HandlesCount++;
ExInitializeFastMutex (&HandleTableMutex);
ExInitializeFastMutex (&RefCountHandling);
+ ShortDelay.QuadPart = -100;
+
HandleTable = GDIOBJ_iAllocHandleTable (GDI_HANDLE_COUNT);
DPRINT("HandleTable: %x\n", HandleTable );
GDIOBJ_LockObjDbg (const char* file, int line, HGDIOBJ hObj, DWORD ObjectType)
{
PGDIOBJHDR ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(hObj));
+#ifndef GDIOBJ_USE_FASTMUTEX
+ DWORD CurrentTid = (DWORD)PsGetCurrentThreadId();
+#endif
DPRINT("(%s:%i) GDIOBJ_LockObjDbg(0x%08x,0x%08x)\n", file, line, hObj, ObjectType);
if (! GDI_VALID_OBJECT(hObj, ObjHdr, ObjectType, GDIOBJFLAG_DEFAULT))
return NULL;
}
-#ifdef NDEBUG
- ExAcquireFastMutex(&ObjHdr->Lock);
+#ifdef GDIOBJ_USE_FASTMUTEX
+ if (ObjHdr->Lock.Owner == KeGetCurrentThread())
+ {
+ ObjHdr->RecursiveLockCount++;
+ }
+ else
+ {
+#ifdef NDEBUG
+ ExAcquireFastMutex(&ObjHdr->Lock);
#else /* NDEBUG */
- if (! ExTryToAcquireFastMutex(&ObjHdr->Lock))
+ if (! ExTryToAcquireFastMutex(&ObjHdr->Lock))
+ {
+ DPRINT1("Caution! GDIOBJ_LockObj trying to lock object 0x%x second time\n", hObj);
+ DPRINT1(" called from: %s:%i (thread %x)\n", file, line, KeGetCurrentThread());
+ if (NULL != ObjHdr->lockfile)
+ {
+ DPRINT1(" previously locked from: %s:%i (thread %x)\n", ObjHdr->lockfile, ObjHdr->lockline, ObjHdr->Lock.Owner);
+ }
+ ExAcquireFastMutex(&ObjHdr->Lock);
+ DPRINT1(" Disregard previous message about object 0x%x, it's ok\n", hObj);
+ }
+#endif /* NDEBUG */
+ ObjHdr->RecursiveLockCount++;
+ }
+#else
+ if (ObjHdr->LockTid == CurrentTid)
+ {
+ InterlockedIncrement(&ObjHdr->LockCount);
+ }
+ else
{
- DPRINT1("Caution! GDIOBJ_LockObj trying to lock object 0x%x second time\n", hObj);
- DPRINT1(" called from: %s:%i\n", file, line);
- if (NULL != ObjHdr->lockfile)
+ for (;;)
{
- DPRINT1(" previously locked from: %s:%i\n", ObjHdr->lockfile, ObjHdr->lockline);
+ if (InterlockedCompareExchange(&ObjHdr->LockTid, CurrentTid, 0) == CurrentTid)
+ {
+ InterlockedIncrement(&ObjHdr->LockCount);
+ break;
+ }
+ /* FIXME: KeDelayExecutionThread(KernelMode, FALSE, &ShortDelay); */
}
- ExAcquireFastMutex(&ObjHdr->Lock);
- DPRINT1(" Disregard previous message about object 0x%x, it's ok\n", hObj);
}
-#endif /* NDEBUG */
+#endif
ExAcquireFastMutex(&RefCountHandling);
ObjHdr->dwCount++;
GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ObjectType)
{
PGDIOBJHDR ObjHdr = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(hObj));
+#ifndef GDIOBJ_USE_FASTMUTEX
+ DWORD CurrentTid = (DWORD)PsGetCurrentThreadId();
+#endif
DPRINT("GDIOBJ_LockObj: hObj: 0x%08x, type: 0x%08x, objhdr: %x\n", hObj, ObjectType, ObjHdr);
if (! GDI_VALID_OBJECT(hObj, ObjHdr, ObjectType, GDIOBJFLAG_DEFAULT))
return NULL;
}
- ExAcquireFastMutex(&ObjHdr->Lock);
+#ifdef GDIOBJ_USE_FASTMUTEX
+ if (ObjHdr->Lock.Owner == KeGetCurrentThread())
+ {
+ ObjHdr->RecursiveLockCount++;
+ }
+ else
+ {
+ ExAcquireFastMutex(&ObjHdr->Lock);
+ ObjHdr->RecursiveLockCount++;
+ }
+#else
+ if (ObjHdr->LockTid == CurrentTid)
+ {
+ InterlockedIncrement(&ObjHdr->LockCount);
+ }
+ else
+ {
+ for (;;)
+ {
+ if (InterlockedCompareExchange(&ObjHdr->LockTid, CurrentTid, 0) == CurrentTid)
+ {
+ InterlockedIncrement(&ObjHdr->LockCount);
+ break;
+ }
+ /* FIXME: KeDelayExecutionThread(KernelMode, FALSE, &ShortDelay); */
+ }
+ }
+#endif
ExAcquireFastMutex(&RefCountHandling);
ObjHdr->dwCount++;
return FALSE;
}
- ExReleaseFastMutex(&ObjHdr->Lock);
+#ifdef GDIOBJ_USE_FASTMUTEX
+ if (--ObjHdr->RecursiveLockCount == 0)
+ ExReleaseFastMutex(&ObjHdr->Lock);
+#else
+ if (InterlockedDecrement(&ObjHdr->LockCount) == 0)
+ {
+ InterlockedExchange(&ObjHdr->LockTid, 0);
+ }
+#endif
ExAcquireFastMutex(&RefCountHandling);
if (0 == (ObjHdr->dwCount & ~0x80000000))