Leaked source code of windows server 2003
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.
|
|
/******************************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; } } };
|