Author: jgardou
Date: Wed Jan 29 18:32:14 2014
New Revision: 61883
URL:
http://svn.reactos.org/svn/reactos?rev=61883&view=rev
Log:
[WIN32K]
- Implement GDIOBJ_TryLockObject and used it for DRIVEROBJs
- Fix EngUnlockDriverObj
Modified:
trunk/reactos/win32ss/gdi/eng/driverobj.c
trunk/reactos/win32ss/gdi/eng/driverobj.h
trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c
trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h
trunk/reactos/win32ss/gdi/ntgdi/misc.h
Modified: trunk/reactos/win32ss/gdi/eng/driverobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/driverobj.…
==============================================================================
--- trunk/reactos/win32ss/gdi/eng/driverobj.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/eng/driverobj.c [iso-8859-1] Wed Jan 29 18:32:14 2014
@@ -80,7 +80,7 @@
PEDRIVEROBJ pedo;
/* Lock the object */
- pedo = DRIVEROBJ_LockObject(hdo);
+ pedo = DRIVEROBJ_TryLockObject(hdo);
if (!pedo)
{
return FALSE;
@@ -100,10 +100,11 @@
/* Prevent cleanup callback from being called again */
pedo->drvobj.pFreeProc = NULL;
- /* NOTE: We don't care about the bLocked param, as our handle manager
- allows freeing the object, while we hold any number of locks. */
+ /* Unlock if the caller indicates it is locked */
+ if (bLocked)
+ DRIVEROBJ_UnlockObject(pedo);
- /* Delete the object */
+ /* Now delete the object */
GDIOBJ_vDeleteObject(&pedo->baseobj);
return TRUE;
}
@@ -117,7 +118,7 @@
PEDRIVEROBJ pedo;
/* Lock the object */
- pedo = DRIVEROBJ_LockObject(hdo);
+ pedo = DRIVEROBJ_TryLockObject(hdo);
/* Return pointer to the DRIVEROBJ structure */
return &pedo->drvobj;
@@ -133,7 +134,7 @@
ULONG cLocks;
/* First lock to get a pointer to the object */
- pedo = DRIVEROBJ_LockObject(hdo);
+ pedo = DRIVEROBJ_TryLockObject(hdo);
if(!pedo)
{
/* Object could not be locked, fail. */
Modified: trunk/reactos/win32ss/gdi/eng/driverobj.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/driverobj.…
==============================================================================
--- trunk/reactos/win32ss/gdi/eng/driverobj.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/eng/driverobj.h [iso-8859-1] Wed Jan 29 18:32:14 2014
@@ -20,7 +20,7 @@
FORCEINLINE
PEDRIVEROBJ
-DRIVEROBJ_LockObject(HDRVOBJ hdo)
+DRIVEROBJ_TryLockObject(HDRVOBJ hdo)
{
- return GDIOBJ_LockObject(hdo, GDIObjType_DRVOBJ_TYPE);
+ return GDIOBJ_TryLockObject(hdo, GDIObjType_DRVOBJ_TYPE);
}
Modified: trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/gdiobj.c [iso-8859-1] Wed Jan 29 18:32:14 2014
@@ -52,11 +52,14 @@
#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt) \
ASSERT((objt) == GDIObjType_DC_TYPE || \
(objt) == GDIObjType_RGN_TYPE)
+#define ASSERT_TRYLOCK_OBJECT_TYPE(objt) \
+ ASSERT((objt) == GDIObjType_DRVOBJ_TYPE)
#else
#define DBG_INCREASE_LOCK_COUNT(ppi, hobj)
#define DBG_DECREASE_LOCK_COUNT(x, y)
#define ASSERT_SHARED_OBJECT_TYPE(objt)
#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt)
+#define ASSERT_TRYLOCK_OBJECT_TYPE(objt)
#endif
#if defined(_M_IX86) || defined(_M_AMD64)
@@ -623,6 +626,72 @@
PGDIOBJ
NTAPI
+GDIOBJ_TryLockObject(
+ HGDIOBJ hobj,
+ UCHAR objt)
+{
+ PENTRY pentry;
+ POBJ pobj;
+ DWORD dwThreadId;
+
+ /* Check if the handle type matches */
+ ASSERT_TRYLOCK_OBJECT_TYPE(objt);
+ if ((((ULONG_PTR)hobj >> 16) & 0x1f) != objt)
+ {
+ DPRINT("Wrong object type: hobj=0x%p, objt=0x%x\n", hobj, objt);
+ return NULL;
+ }
+
+ /* Reference the handle entry */
+ pentry = ENTRY_ReferenceEntryByHandle(hobj, 0);
+ if (!pentry)
+ {
+ DPRINT("GDIOBJ: Requested handle 0x%p is not valid.\n", hobj);
+ return NULL;
+ }
+
+ /* Get the pointer to the BASEOBJECT */
+ pobj = pentry->einfo.pobj;
+
+ /* Check if we already own the lock */
+ dwThreadId = PtrToUlong(PsGetCurrentThreadId());
+ if (pobj->dwThreadId != dwThreadId)
+ {
+ /* Disable APCs and try acquiring the push lock */
+ KeEnterCriticalRegion();
+ if(!ExTryAcquirePushLockExclusive(&pobj->pushlock))
+ {
+ ULONG cRefs, ulIndex;
+ /* Already owned. Clean up and leave. */
+ KeLeaveCriticalRegion();
+
+ /* Calculate the index */
+ ulIndex = GDI_HANDLE_GET_INDEX(pobj->hHmgr);
+
+ /* Decrement reference count */
+ ASSERT((gpaulRefCount[ulIndex] & REF_MASK_COUNT) > 0);
+ cRefs = InterlockedDecrement((LONG*)&gpaulRefCount[ulIndex]);
+ ASSERT(cRefs & REF_MASK_VALID);
+
+ return NULL;
+ }
+
+ /* Set us as lock owner */
+ ASSERT(pobj->dwThreadId == 0);
+ pobj->dwThreadId = dwThreadId;
+ }
+
+ /* Increase lock count */
+ pobj->cExclusiveLock++;
+ DBG_INCREASE_LOCK_COUNT(PsGetCurrentProcessWin32Process(), hobj);
+ DBG_LOGEVENT(&pobj->slhLog, EVENT_LOCK, 0);
+
+ /* Return the object */
+ return pobj;
+}
+
+PGDIOBJ
+NTAPI
GDIOBJ_LockObject(
HGDIOBJ hobj,
UCHAR objt)
Modified: trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/gdiobj.h [iso-8859-1] Wed Jan 29 18:32:14 2014
@@ -141,6 +141,12 @@
HGDIOBJ hobj,
UCHAR objt);
+PGDIOBJ
+NTAPI
+GDIOBJ_TryLockObject(
+ HGDIOBJ hobj,
+ UCHAR objt);
+
VOID
NTAPI
GDIOBJ_vUnlockObject(
Modified: trunk/reactos/win32ss/gdi/ntgdi/misc.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/misc.h?r…
==============================================================================
--- trunk/reactos/win32ss/gdi/ntgdi/misc.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/gdi/ntgdi/misc.h [iso-8859-1] Wed Jan 29 18:32:14 2014
@@ -113,6 +113,14 @@
}
FORCEINLINE
+BOOLEAN
+ExTryAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
+{
+ /* Try acquiring the lock */
+ return !InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V);
+}
+
+FORCEINLINE
VOID
ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
{