mirror of
https://github.com/reactos/reactos.git
synced 2025-01-03 21:09:19 +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;
|
PEDRIVEROBJ pedo;
|
||||||
|
|
||||||
/* Lock the object */
|
/* Lock the object */
|
||||||
pedo = DRIVEROBJ_LockObject(hdo);
|
pedo = DRIVEROBJ_TryLockObject(hdo);
|
||||||
if (!pedo)
|
if (!pedo)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -100,10 +100,11 @@ EngDeleteDriverObj(
|
||||||
/* Prevent cleanup callback from being called again */
|
/* Prevent cleanup callback from being called again */
|
||||||
pedo->drvobj.pFreeProc = NULL;
|
pedo->drvobj.pFreeProc = NULL;
|
||||||
|
|
||||||
/* NOTE: We don't care about the bLocked param, as our handle manager
|
/* Unlock if the caller indicates it is locked */
|
||||||
allows freeing the object, while we hold any number of locks. */
|
if (bLocked)
|
||||||
|
DRIVEROBJ_UnlockObject(pedo);
|
||||||
|
|
||||||
/* Delete the object */
|
/* Now delete the object */
|
||||||
GDIOBJ_vDeleteObject(&pedo->baseobj);
|
GDIOBJ_vDeleteObject(&pedo->baseobj);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +118,7 @@ EngLockDriverObj(
|
||||||
PEDRIVEROBJ pedo;
|
PEDRIVEROBJ pedo;
|
||||||
|
|
||||||
/* Lock the object */
|
/* Lock the object */
|
||||||
pedo = DRIVEROBJ_LockObject(hdo);
|
pedo = DRIVEROBJ_TryLockObject(hdo);
|
||||||
|
|
||||||
/* Return pointer to the DRIVEROBJ structure */
|
/* Return pointer to the DRIVEROBJ structure */
|
||||||
return &pedo->drvobj;
|
return &pedo->drvobj;
|
||||||
|
@ -133,7 +134,7 @@ EngUnlockDriverObj(
|
||||||
ULONG cLocks;
|
ULONG cLocks;
|
||||||
|
|
||||||
/* First lock to get a pointer to the object */
|
/* First lock to get a pointer to the object */
|
||||||
pedo = DRIVEROBJ_LockObject(hdo);
|
pedo = DRIVEROBJ_TryLockObject(hdo);
|
||||||
if(!pedo)
|
if(!pedo)
|
||||||
{
|
{
|
||||||
/* Object could not be locked, fail. */
|
/* Object could not be locked, fail. */
|
||||||
|
|
|
@ -20,7 +20,7 @@ BOOL NTAPI DRIVEROBJ_Cleanup(PVOID pObject);
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
PEDRIVEROBJ
|
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) \
|
#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt) \
|
||||||
ASSERT((objt) == GDIObjType_DC_TYPE || \
|
ASSERT((objt) == GDIObjType_DC_TYPE || \
|
||||||
(objt) == GDIObjType_RGN_TYPE)
|
(objt) == GDIObjType_RGN_TYPE)
|
||||||
|
#define ASSERT_TRYLOCK_OBJECT_TYPE(objt) \
|
||||||
|
ASSERT((objt) == GDIObjType_DRVOBJ_TYPE)
|
||||||
#else
|
#else
|
||||||
#define DBG_INCREASE_LOCK_COUNT(ppi, hobj)
|
#define DBG_INCREASE_LOCK_COUNT(ppi, hobj)
|
||||||
#define DBG_DECREASE_LOCK_COUNT(x, y)
|
#define DBG_DECREASE_LOCK_COUNT(x, y)
|
||||||
#define ASSERT_SHARED_OBJECT_TYPE(objt)
|
#define ASSERT_SHARED_OBJECT_TYPE(objt)
|
||||||
#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt)
|
#define ASSERT_EXCLUSIVE_OBJECT_TYPE(objt)
|
||||||
|
#define ASSERT_TRYLOCK_OBJECT_TYPE(objt)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
|
@ -621,6 +624,72 @@ GDIOBJ_vReferenceObjectByPointer(POBJ pobj)
|
||||||
DBG_LOGEVENT(&pobj->slhLog, EVENT_REFERENCE, cRefs);
|
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
|
PGDIOBJ
|
||||||
NTAPI
|
NTAPI
|
||||||
GDIOBJ_LockObject(
|
GDIOBJ_LockObject(
|
||||||
|
|
|
@ -141,6 +141,12 @@ GDIOBJ_LockObject(
|
||||||
HGDIOBJ hobj,
|
HGDIOBJ hobj,
|
||||||
UCHAR objt);
|
UCHAR objt);
|
||||||
|
|
||||||
|
PGDIOBJ
|
||||||
|
NTAPI
|
||||||
|
GDIOBJ_TryLockObject(
|
||||||
|
HGDIOBJ hobj,
|
||||||
|
UCHAR objt);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
GDIOBJ_vUnlockObject(
|
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
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
|
ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
|
||||||
|
|
Loading…
Reference in a new issue