mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
[WIN32K]
- Implement GDIOBJ_TryLockObject and used it for DRIVEROBJs - Fix EngUnlockDriverObj svn path=/trunk/; revision=61883
This commit is contained in:
parent
ad76a6a077
commit
e2be2729b0
5 changed files with 92 additions and 8 deletions
|
@ -80,7 +80,7 @@ EngDeleteDriverObj(
|
|||
PEDRIVEROBJ pedo;
|
||||
|
||||
/* Lock the object */
|
||||
pedo = DRIVEROBJ_LockObject(hdo);
|
||||
pedo = DRIVEROBJ_TryLockObject(hdo);
|
||||
if (!pedo)
|
||||
{
|
||||
return FALSE;
|
||||
|
@ -100,10 +100,11 @@ EngDeleteDriverObj(
|
|||
/* 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 @@ EngLockDriverObj(
|
|||
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 @@ EngUnlockDriverObj(
|
|||
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. */
|
||||
|
|
|
@ -20,7 +20,7 @@ BOOL NTAPI DRIVEROBJ_Cleanup(PVOID pObject);
|
|||
|
||||
FORCEINLINE
|
||||
PEDRIVEROBJ
|
||||
DRIVEROBJ_LockObject(HDRVOBJ hdo)
|
||||
DRIVEROBJ_TryLockObject(HDRVOBJ hdo)
|
||||
{
|
||||
return GDIOBJ_LockObject(hdo, GDIObjType_DRVOBJ_TYPE);
|
||||
return GDIOBJ_TryLockObject(hdo, GDIObjType_DRVOBJ_TYPE);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
@ -621,6 +624,72 @@ GDIOBJ_vReferenceObjectByPointer(POBJ pobj)
|
|||
DBG_LOGEVENT(&pobj->slhLog, EVENT_REFERENCE, cRefs);
|
||||
}
|
||||
|
||||
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(
|
||||
|
|
|
@ -141,6 +141,12 @@ GDIOBJ_LockObject(
|
|||
HGDIOBJ hobj,
|
||||
UCHAR objt);
|
||||
|
||||
PGDIOBJ
|
||||
NTAPI
|
||||
GDIOBJ_TryLockObject(
|
||||
HGDIOBJ hobj,
|
||||
UCHAR objt);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
GDIOBJ_vUnlockObject(
|
||||
|
|
|
@ -112,6 +112,14 @@ ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue