Author: jgardou Date: Fri Apr 16 00:38:04 2010 New Revision: 46891
URL: http://svn.reactos.org/svn/reactos?rev=46891&view=rev Log: [WIN32K] - Introduce deadlocks killer GDIOBJ_LockMultipleObjs, unused for now - Make the PDEVOBJ DCs list a sorted list Didicated to Physicus
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/gdiobj.h branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c branches/reactos-yarotows/subsystems/win32/win32k/objects/gdiobj.c
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/gdiobj.h URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/include/gdiobj.h [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/include/gdiobj.h [iso-8859-1] Fri Apr 16 00:38:04 2010 @@ -34,6 +34,7 @@ typedef PVOID PGDIOBJ;
typedef BOOL (INTERNAL_CALL *GDICLEANUPPROC)(PVOID ObjectBody); +typedef VOID (INTERNAL_CALL *GDILOCKOBJPROC)(PVOID ObjectBody);
/* Every GDI Object must have this standard type of header. * It's for thread locking. */ @@ -71,6 +72,7 @@ BOOL INTERNAL_CALL GDIOBJ_FreeObjByHandle (HGDIOBJ hObj, DWORD ObjectType); PGDIOBJ INTERNAL_CALL GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ObjectType); PGDIOBJ INTERNAL_CALL GDIOBJ_ShareLockObj (HGDIOBJ hObj, DWORD ObjectType); +VOID INTERNAL_CALL GDIOBJ_LockMultipleObjs(ULONG ulCount, IN HGDIOBJ* ahObj, OUT PGDIOBJ* apObj);
PVOID INTERNAL_CALL GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process);
@@ -87,7 +89,7 @@ BOOL FASTCALL IntGdiSetRegionOwner(HRGN,DWORD);
/*! - * Release GDI object. Every object locked by GDIOBJ_LockObj() must be unlocked. + * Release GDI object. Every object locked by GDIOBJ_LockObj() must be unlocked. * You should unlock the object * as soon as you don't need to have access to it's data.
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/objects/dclife.c [iso-8859-1] Fri Apr 16 00:38:04 2010 @@ -159,30 +159,52 @@
if (dctype == DCTYPE_DIRECT) { + PDC pdcTmp; /* Direct DCs get the surface from the PDEV */ pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev);
/* Maintain a list of DC attached to this device */ - if(!pdc->dclevel.pSurface->hDC) + /* We must sort them so when locking them one after the other we don't risk deadlocks */ + /* The greatest the first, as in GDIOBJ_LockMultiplObjs */ + if((ULONG_PTR)pdc->dclevel.pSurface->hDC < (ULONG_PTR)pdc->BaseObject.hHmgr) + { + /* Insert it at the head of the list */ + pdc->hdcNext = pdc->dclevel.pSurface->hDC ; pdc->dclevel.pSurface->hDC = pdc->BaseObject.hHmgr ; + pdcTmp = DC_LockDc(pdc->hdcNext); + if(pdcTmp) + { + pdcTmp->hdcPrev = pdc->BaseObject.hHmgr ; + DC_UnlockDc(pdcTmp); + } + } else { - PDC Surf_Dc = DC_LockDc(pdc->dclevel.pSurface->hDC); - if(!Surf_Dc) + HDC hdcTmp = pdc->dclevel.pSurface->hDC; + HDC hdcNext = NULL ; + HDC hdcPrev = NULL ; + /* Find its place */ + while((ULONG_PTR)hdcTmp > (ULONG_PTR)pdc->BaseObject.hHmgr) { - DPRINT1("Something went wrong with device DC list!\n"); - /* Save what can be saved ... */ - pdc->dclevel.pSurface->hDC = pdc->BaseObject.hHmgr; + pdcTmp = DC_LockDc(hdcTmp); + hdcNext = hdcTmp ; + hdcPrev = pdcTmp->hdcPrev ; + hdcTmp = pdcTmp->hdcNext ; + DC_UnlockDc(pdcTmp); } - else + pdc->hdcPrev = hdcPrev; + pdc->hdcNext = hdcNext; + /* Insert it */ + pdcTmp = DC_LockDc(hdcPrev); + ASSERT(pdcTmp) ; /* There should always be a previous */ + pdcTmp->hdcNext = pdc->BaseObject.hHmgr ; + DC_UnlockDc(pdcTmp) ; + + pdcTmp = DC_LockDc(hdcNext); + if(pdcTmp) /* Last one is NULL */ { - /* Insert this one at the head of the list */ - pdc->hdcNext = Surf_Dc->BaseObject.hHmgr; - /* Sanity check */ - ASSERT(NULL == Surf_Dc->hdcPrev); - Surf_Dc->hdcPrev = pdc->BaseObject.hHmgr ; - pdc->dclevel.pSurface->hDC = pdc->BaseObject.hHmgr; - DC_UnlockDc(Surf_Dc); + pdcTmp->hdcPrev = pdc->BaseObject.hHmgr; + DC_UnlockDc(pdcTmp); } }
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/gdiobj.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] Fri Apr 16 00:38:04 2010 @@ -1625,6 +1625,40 @@ return MappedView; }
+/* Locks multiple objects at a time */ +VOID +INTERNAL_CALL +GDIOBJ_LockMultipleObjs(ULONG ulCount, + IN HGDIOBJ* ahObj, + OUT PGDIOBJ* apObj) +{ + UINT i; + HGDIOBJ hTmp ; + BOOL unsorted = TRUE; + /* We bubble-sort them */ + while(unsorted) + { + unsorted = FALSE ; + for(i=0; i<ulCount - 1; i++) + { + /* The greatest the first */ + if((ULONG_PTR)ahObj[i] < (ULONG_PTR)ahObj[i+1]) + { + hTmp = ahObj[i]; + ahObj[i]=ahObj[i+1]; + ahObj[i+1] = hTmp; + unsorted = TRUE ; + } + } + } + /* Then we lock them */ + for(i=0; i<ulCount; i++) + { + apObj[i]=GDIOBJ_LockObj(ahObj[i], GDI_OBJECT_TYPE_DONTCARE); + } +} + + /** PUBLIC FUNCTIONS **********************************************************/
BOOL