From a4e83efd833254c88f51f5495dee69f07d47b4a7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Thu, 15 Apr 2010 22:38:04 +0000 Subject: [PATCH] [WIN32K] - Introduce deadlocks killer GDIOBJ_LockMultipleObjs, unused for now - Make the PDEVOBJ DCs list a sorted list Didicated to Physicus svn path=/branches/reactos-yarotows/; revision=46891 --- subsystems/win32/win32k/include/gdiobj.h | 4 +- subsystems/win32/win32k/objects/dclife.c | 50 +++++++++++++++++------- subsystems/win32/win32k/objects/gdiobj.c | 34 ++++++++++++++++ 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/subsystems/win32/win32k/include/gdiobj.h b/subsystems/win32/win32k/include/gdiobj.h index 50ed2e6163f..40ca099dc5b 100644 --- a/subsystems/win32/win32k/include/gdiobj.h +++ b/subsystems/win32/win32k/include/gdiobj.h @@ -34,6 +34,7 @@ extern PGDI_HANDLE_TABLE GdiHandleTable; 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 @@ VOID INTERNAL_CALL GDIOBJ_FreeObj (POBJ pObj, UCHAR ObjectType); 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 IntGdiSetDCOwnerEx( HDC, DWORD, BOOL); 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. diff --git a/subsystems/win32/win32k/objects/dclife.c b/subsystems/win32/win32k/objects/dclife.c index 1581a141ad1..45851f3578d 100644 --- a/subsystems/win32/win32k/objects/dclife.c +++ b/subsystems/win32/win32k/objects/dclife.c @@ -159,30 +159,52 @@ DC_vInitDc( 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); } } diff --git a/subsystems/win32/win32k/objects/gdiobj.c b/subsystems/win32/win32k/objects/gdiobj.c index 76b77f0eebe..70c131e31eb 100644 --- a/subsystems/win32/win32k/objects/gdiobj.c +++ b/subsystems/win32/win32k/objects/gdiobj.c @@ -1625,6 +1625,40 @@ GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process) 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