You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
8.4 KiB
337 lines
8.4 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: devlock.hxx
|
|
*
|
|
* Device locking object.
|
|
*
|
|
* Created: 03-Jul-1990 17:41:42
|
|
* Author: Donald Sidoroff [donalds]
|
|
*
|
|
* Copyright (c) 1992-1999 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
#define DLO_VALID 0x00000001
|
|
#define DLO_ALLOC 0x00000010 // for MULTIDEVLOCKOBJ
|
|
#define DLO_LOCKED 0x00000020 // for MULTIDEVLOCKOBJ
|
|
#define DLO_SHAREDACCESS 0x00000100
|
|
|
|
class DEVLOCKOBJ
|
|
{
|
|
private:
|
|
HSEMAPHORE hsemTrg;
|
|
PPDEV ppdevTrg;
|
|
FLONG fl;
|
|
|
|
public:
|
|
BOOL bLock(XDCOBJ&);
|
|
VOID vLockNoDrawing(XDCOBJ&);
|
|
VOID vLock(PDEVOBJ& po)
|
|
{
|
|
GDIFunctionID(DEVLOCKOBJ::vLock);
|
|
|
|
hsemTrg = NULL;
|
|
fl = DLO_VALID;
|
|
if (po.bDisplayPDEV())
|
|
{
|
|
//
|
|
// make sure we don't have any wrong sequence of acquiring locks
|
|
// should always acquire a DEVLOCK before we have the palette semaphore
|
|
//
|
|
|
|
ASSERTGDI (!GreIsSemaphoreOwnedByCurrentThread(ghsemPalette) ||
|
|
GreIsSemaphoreOwnedByCurrentThread(po.hsemDevLock()),
|
|
"potential deadlock!\n");
|
|
|
|
hsemTrg = po.hsemDevLock();
|
|
ppdevTrg = po.ppdev;
|
|
GreAcquireSemaphoreEx(hsemTrg, SEMORDER_DEVLOCK, NULL);
|
|
GreEnterMonitoredSection(ppdevTrg, WD_DEVLOCK);
|
|
}
|
|
}
|
|
|
|
DEVLOCKOBJ() { }
|
|
DEVLOCKOBJ(XDCOBJ& dco) { bLock(dco); }
|
|
DEVLOCKOBJ(PDEVOBJ& po) { vLock(po); }
|
|
|
|
// vDestructor -- manual version of the normal C++ destructor; needed
|
|
// by the C-callable OpenGL interface.
|
|
|
|
VOID vDestructor()
|
|
{
|
|
GDIFunctionID(DEVLOCKOBJ::vDestructor);
|
|
|
|
if(fl & DLO_SHAREDACCESS)
|
|
{
|
|
GreReleaseSemaphore(ghsemShareDevLock);
|
|
}
|
|
else if (hsemTrg != NULL)
|
|
{
|
|
GreExitMonitoredSection(ppdevTrg, WD_DEVLOCK);
|
|
GreReleaseSemaphoreEx(hsemTrg);
|
|
}
|
|
|
|
#ifdef CHECK_SEMAPHORE_USAGE
|
|
GreCheckSemaphoreUsage();
|
|
#endif
|
|
}
|
|
|
|
VOID vDestructorNULL()
|
|
{
|
|
GDIFunctionID(DEVLOCKOBJ::vDestructorNULL);
|
|
|
|
if(fl & DLO_SHAREDACCESS)
|
|
{
|
|
GreReleaseSemaphore(ghsemShareDevLock);
|
|
fl &= ~(DLO_SHAREDACCESS);
|
|
}
|
|
else if (hsemTrg != NULL)
|
|
{
|
|
ASSERT(ppdevTrg);
|
|
GreExitMonitoredSection(ppdevTrg, WD_DEVLOCK);
|
|
GreReleaseSemaphoreEx(hsemTrg);
|
|
hsemTrg = NULL;
|
|
ppdevTrg = NULL;
|
|
}
|
|
|
|
#ifdef CHECK_SEMAPHORE_USAGE
|
|
GreCheckSemaphoreUsage();
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
~DEVLOCKOBJ() { vDestructor(); }
|
|
|
|
HSEMAPHORE hsemDst() { return(hsemTrg); }
|
|
BOOL bValid() { return(fl & DLO_VALID); }
|
|
VOID vInit()
|
|
{
|
|
hsemTrg = NULL;
|
|
ppdevTrg = NULL;
|
|
fl = 0;
|
|
}
|
|
};
|
|
|
|
/*********************************Class************************************\
|
|
* class DEVLOCKBLTOBJ
|
|
*
|
|
* Lock the target and optionally the source for BitBlt, et. al.
|
|
*
|
|
* History:
|
|
* Mon 18-Apr-1994 -by- Patrick Haluptzok [patrickh]
|
|
* Support Async devices.
|
|
*
|
|
* 17-Nov-1992 -by- Donald Sidoroff [donalds]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
class DEVLOCKBLTOBJ
|
|
{
|
|
private:
|
|
HSEMAPHORE hsemTrg;
|
|
HSEMAPHORE hsemSrc;
|
|
PPDEV ppdevTrg;
|
|
PPDEV ppdevSrc;
|
|
FLONG fl;
|
|
|
|
public:
|
|
BOOL bLock(XDCOBJ&);
|
|
BOOL bLock(XDCOBJ&,XDCOBJ&);
|
|
|
|
DEVLOCKBLTOBJ(XDCOBJ& dco) { bLock(dco); }
|
|
DEVLOCKBLTOBJ(XDCOBJ& dcoTrg,XDCOBJ& dcoSrc) { bLock(dcoTrg,dcoSrc); }
|
|
DEVLOCKBLTOBJ() {}
|
|
|
|
//
|
|
// vUnLock and vLock are used to temparily
|
|
// release and re-aquire the DEVLOCK
|
|
//
|
|
|
|
VOID vUnLock ()
|
|
{
|
|
GDIFunctionID(DEVLOCKBLTOBJ::vUnLock);
|
|
|
|
if (hsemTrg != NULL)
|
|
{
|
|
ASSERT(ppdevTrg);
|
|
GreExitMonitoredSection(ppdevTrg, WD_DEVLOCK);
|
|
GreReleaseSemaphore(hsemTrg);
|
|
hsemTrg = NULL;
|
|
ppdevTrg = NULL;
|
|
}
|
|
|
|
if (hsemSrc != NULL)
|
|
{
|
|
ASSERT(ppdevSrc);
|
|
GreExitMonitoredSection(ppdevSrc, WD_DEVLOCK);
|
|
GreReleaseSemaphore(hsemSrc);
|
|
hsemSrc = NULL;
|
|
ppdevSrc = NULL;
|
|
}
|
|
|
|
if(fl & DLO_SHAREDACCESS)
|
|
{
|
|
GreReleaseSemaphore(ghsemShareDevLock);
|
|
fl &= ~(DLO_SHAREDACCESS);
|
|
}
|
|
|
|
#ifdef CHECK_SEMAPHORE_USAGE
|
|
GreCheckSemaphoreUsage();
|
|
#endif
|
|
|
|
}
|
|
|
|
~DEVLOCKBLTOBJ()
|
|
{
|
|
GDIFunctionID(DEVLOCKBLTOBJ::~DEVLOCKBLTOBJ);
|
|
|
|
if (hsemTrg != NULL)
|
|
{
|
|
ASSERT(ppdevTrg);
|
|
GreExitMonitoredSection(ppdevTrg, WD_DEVLOCK);
|
|
GreReleaseSemaphore(hsemTrg);
|
|
}
|
|
|
|
if (hsemSrc != NULL)
|
|
{
|
|
ASSERT(ppdevSrc);
|
|
GreExitMonitoredSection(ppdevSrc, WD_DEVLOCK);
|
|
GreReleaseSemaphore(hsemSrc);
|
|
}
|
|
|
|
if(fl & DLO_SHAREDACCESS)
|
|
{
|
|
GreReleaseSemaphore(ghsemShareDevLock);
|
|
}
|
|
|
|
#ifdef CHECK_SEMAPHORE_USAGE
|
|
GreCheckSemaphoreUsage();
|
|
#endif
|
|
|
|
}
|
|
|
|
BOOL bValid() { return(fl & DLO_VALID); }
|
|
|
|
VOID vInit()
|
|
{
|
|
hsemTrg = NULL;
|
|
hsemSrc = NULL;
|
|
ppdevTrg = NULL;
|
|
ppdevSrc = NULL;
|
|
fl = 0;
|
|
}
|
|
};
|
|
|
|
/*********************************Class************************************\
|
|
* class MULTIDEVLOCLOBJ
|
|
*
|
|
* Lock the all PDEV for the MDEV.
|
|
*
|
|
* History:
|
|
* Tue 07-Jul-1998 -by- Hideyuki Nagase [hideyukn]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
#define QUICK_MULTIDEVLOCK_SIZE 5
|
|
|
|
class MULTIDEVLOCKOBJ
|
|
{
|
|
private:
|
|
FLONG fl;
|
|
ULONG ulArraySize;
|
|
HSEMAPHORE *phsemArray;
|
|
HSEMAPHORE hsemQuickBuf[QUICK_MULTIDEVLOCK_SIZE];
|
|
|
|
public:
|
|
|
|
MULTIDEVLOCKOBJ() { vInit(NULL); }
|
|
MULTIDEVLOCKOBJ(PMDEV pmdev) { vInit(pmdev); }
|
|
~MULTIDEVLOCKOBJ()
|
|
{
|
|
vUnlock();
|
|
if (fl & DLO_ALLOC)
|
|
{
|
|
VFREEMEM(phsemArray);
|
|
}
|
|
}
|
|
|
|
BOOL bValid() { return(fl & DLO_VALID); }
|
|
BOOL bLocked() { return(fl & DLO_LOCKED); }
|
|
BOOL bValidLockTable() { return(phsemArray != NULL); }
|
|
|
|
VOID vInit(PMDEV pmdev)
|
|
{
|
|
fl = 0;
|
|
ulArraySize = 0;
|
|
phsemArray = NULL;
|
|
|
|
if (pmdev)
|
|
{
|
|
// + 1 : for parent pdev's lock
|
|
|
|
ulArraySize = pmdev->chdev;
|
|
|
|
if (ulArraySize > QUICK_MULTIDEVLOCK_SIZE)
|
|
{
|
|
phsemArray = (HSEMAPHORE *) PALLOCNOZ(sizeof(HSEMAPHORE) * pmdev->chdev,'pmtG');
|
|
if (phsemArray)
|
|
{
|
|
fl = (DLO_VALID|DLO_ALLOC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
phsemArray = hsemQuickBuf;
|
|
fl = DLO_VALID;
|
|
}
|
|
|
|
if (phsemArray)
|
|
{
|
|
PDEVOBJ po;
|
|
|
|
// Save all the children's devlock to buffer in class
|
|
|
|
for (ULONG i = 0; i < pmdev->chdev; i++)
|
|
{
|
|
po.vInit(pmdev->Dev[i].hdev);
|
|
*(phsemArray + i) = po.hsemDevLock();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fl = DLO_VALID;
|
|
}
|
|
}
|
|
|
|
VOID vLock()
|
|
{
|
|
GDIFunctionID(MULTIDEVLOCKOBJ::vLock);
|
|
|
|
if (bValidLockTable() && !bLocked())
|
|
{
|
|
for (ULONG i = 0; i < ulArraySize; i++)
|
|
{
|
|
GreAcquireSemaphoreEx(*(phsemArray+i), SEMORDER_DEVLOCK, NULL);
|
|
}
|
|
|
|
fl |= DLO_LOCKED;
|
|
}
|
|
}
|
|
|
|
VOID vUnlock()
|
|
{
|
|
GDIFunctionID(MULTIDEVLOCKOBJ::vUnLock);
|
|
|
|
if (bValidLockTable() && bLocked())
|
|
{
|
|
for (ULONG i = 0; i < ulArraySize; i++)
|
|
{
|
|
GreReleaseSemaphoreEx(*(phsemArray+i));
|
|
}
|
|
|
|
fl &= ~DLO_LOCKED;
|
|
}
|
|
}
|
|
};
|
|
|
|
|