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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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/win…
==============================================================================
--- 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