Alexandre Julliard : gdi32: Don't hold the gdi lock while creating a DC.

Alexandre Julliard julliard at winehq.org
Thu Sep 27 09:27:19 CDT 2007


Module: wine
Branch: master
Commit: 7480bd3204535d19da2ea5336b304d01936e418e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=7480bd3204535d19da2ea5336b304d01936e418e

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Sep 26 17:39:25 2007 +0200

gdi32: Don't hold the gdi lock while creating a DC.

---

 dlls/gdi32/dc.c            |   46 ++++++++++++++++++++++----------------------
 dlls/gdi32/enhmfdrv/init.c |   16 +++++++-------
 dlls/gdi32/gdi_private.h   |    4 +-
 dlls/gdi32/mfdrv/init.c    |   16 +++++++-------
 4 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index fe51253..bb91785 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -71,9 +71,9 @@ static inline DC *get_dc_obj( HDC hdc )
 
 
 /***********************************************************************
- *           DC_AllocDC
+ *           alloc_dc_ptr
  */
-DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
+DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
 {
     HDC hdc;
     DC *dc;
@@ -149,6 +149,7 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
     dc->BoundsRect.bottom   = 0;
     dc->saved_visrgn        = NULL;
     PATH_InitGdiPath(&dc->path);
+    GDI_ReleaseObj( dc->hSelf );
     return dc;
 }
 
@@ -189,11 +190,13 @@ void DC_ReleaseDCPtr( DC *dc )
 
 
 /***********************************************************************
- *           DC_FreeDCPtr
+ *           free_dc_ptr
  */
-BOOL DC_FreeDCPtr( DC *dc )
+BOOL free_dc_ptr( DC *dc )
 {
     assert( dc->refcount == 1 );
+    /* grab the gdi lock again */
+    if (!GDI_GetObjPtr( dc->hSelf, MAGIC_DONTCARE )) return FALSE;  /* shouldn't happen */
     return GDI_FreeObject( dc->hSelf, dc );
 }
 
@@ -704,7 +707,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
         ERR( "no driver found for %s\n", debugstr_w(buf) );
         return 0;
     }
-    if (!(dc = DC_AllocDC( funcs, DC_MAGIC ))) goto error;
+    if (!(dc = alloc_dc_ptr( funcs, DC_MAGIC ))) goto error;
     hdc = dc->hSelf;
 
     dc->hBitmap = GetStockObject( DEFAULT_BITMAP );
@@ -724,12 +727,12 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
                 GetDeviceCaps( hdc, DESKTOPHORZRES ), GetDeviceCaps( hdc, DESKTOPVERTRES ) );
 
     DC_InitDC( dc );
-    DC_ReleaseDCPtr( dc );
+    release_dc_ptr( dc );
     return hdc;
 
 error:
     if (dc && dc->hVisRgn) DeleteObject( dc->hVisRgn );
-    if (dc) DC_FreeDCPtr( dc );
+    if (dc) free_dc_ptr( dc );
     DRIVER_release_driver( funcs );
     return 0;
 }
@@ -805,20 +808,20 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
 
     GDI_CheckNotLock();
 
-    if ((origDC = DC_GetDCPtr( hdc )))
+    if ((origDC = get_dc_ptr( hdc )))
     {
         if (GetObjectType( hdc ) == OBJ_DC)
         {
             funcs = origDC->funcs;
             physDev = origDC->physDev;
         }
-        DC_ReleaseDCPtr( origDC ); /* can't hold the lock while loading the driver */
+        release_dc_ptr( origDC );
         if (funcs) funcs = DRIVER_get_driver( funcs );
     }
 
     if (!funcs && !(funcs = DRIVER_load_driver( displayW ))) return 0;
 
-    if (!(dc = DC_AllocDC( funcs, MEMORY_DC_MAGIC ))) goto error;
+    if (!(dc = alloc_dc_ptr( funcs, MEMORY_DC_MAGIC ))) goto error;
 
     TRACE("(%p): returning %p\n", hdc, dc->hSelf );
 
@@ -838,12 +841,12 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
     }
 
     DC_InitDC( dc );
-    DC_ReleaseDCPtr( dc );
+    release_dc_ptr( dc );
     return dc->hSelf;
 
 error:
     if (dc && dc->hVisRgn) DeleteObject( dc->hVisRgn );
-    if (dc) DC_FreeDCPtr( dc );
+    if (dc) free_dc_ptr( dc );
     DRIVER_release_driver( funcs );
     return 0;
 }
@@ -861,29 +864,26 @@ BOOL WINAPI DeleteDC( HDC hdc )
 
     GDI_CheckNotLock();
 
-    if (!(dc = DC_GetDCPtr( hdc ))) return FALSE;
+    if (!(dc = get_dc_ptr( hdc ))) return FALSE;
     if (dc->refcount != 1)
     {
         FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
-        DC_ReleaseDCPtr( dc );
+        release_dc_ptr( dc );
         return FALSE;
     }
 
     /* Call hook procedure to check whether is it OK to delete this DC */
-    if (dc->hookThunk)
+    if (dc->hookThunk && !dc->hookThunk( hdc, DCHC_DELETEDC, dc->dwHookData, 0 ))
     {
-        DCHOOKPROC proc = dc->hookThunk;
-        DWORD_PTR data = dc->dwHookData;
-        DC_ReleaseDCPtr( dc );
-        if (!proc( hdc, DCHC_DELETEDC, data, 0 )) return FALSE;
-        if (!(dc = DC_GetDCPtr( hdc ))) return TRUE;  /* deleted by the hook */
+        release_dc_ptr( dc );
+        return FALSE;
     }
 
     while (dc->saveLevel)
     {
         DC * dcs;
         HDC hdcs = dc->saved_dc;
-        if (!(dcs = DC_GetDCPtr( hdcs ))) break;
+        if (!(dcs = get_dc_ptr( hdcs ))) break;
         dc->saved_dc = dcs->saved_dc;
         dc->saveLevel--;
         if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn );
@@ -891,7 +891,7 @@ BOOL WINAPI DeleteDC( HDC hdc )
         if (dcs->hMetaClipRgn) DeleteObject( dcs->hMetaClipRgn );
         if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn );
         PATH_DestroyGdiPath(&dcs->path);
-        DC_FreeDCPtr( dcs );
+        free_dc_ptr( dcs );
     }
 
     if (!(dc->flags & DC_SAVED))
@@ -918,7 +918,7 @@ BOOL WINAPI DeleteDC( HDC hdc )
     if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
     PATH_DestroyGdiPath(&dc->path);
 
-    DC_FreeDCPtr( dc );
+    free_dc_ptr( dc );
     if (funcs) DRIVER_release_driver( funcs );  /* do that after releasing the GDI lock */
     return TRUE;
 }
diff --git a/dlls/gdi32/enhmfdrv/init.c b/dlls/gdi32/enhmfdrv/init.c
index f5c4562..0db9ff6 100644
--- a/dlls/gdi32/enhmfdrv/init.c
+++ b/dlls/gdi32/enhmfdrv/init.c
@@ -171,7 +171,7 @@ static BOOL EMFDRV_DeleteDC( DC *dc )
     HeapFree( GetProcessHeap(), 0, physDev->handles );
     HeapFree( GetProcessHeap(), 0, physDev );
     dc->physDev = NULL;
-    DC_FreeDCPtr( dc );
+    free_dc_ptr( dc );
     return TRUE;
 }
 
@@ -314,11 +314,11 @@ HDC WINAPI CreateEnhMetaFileW(
 
     TRACE("%s\n", debugstr_w(filename) );
 
-    if (!(dc = DC_AllocDC( &EMFDRV_Funcs, ENHMETAFILE_DC_MAGIC ))) return 0;
+    if (!(dc = alloc_dc_ptr( &EMFDRV_Funcs, ENHMETAFILE_DC_MAGIC ))) return 0;
 
     physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
     if (!physDev) {
-        DC_FreeDCPtr( dc );
+        free_dc_ptr( dc );
         return 0;
     }
     dc->physDev = (PHYSDEV)physDev;
@@ -334,7 +334,7 @@ HDC WINAPI CreateEnhMetaFileW(
 
     if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) {
         HeapFree( GetProcessHeap(), 0, physDev );
-        DC_FreeDCPtr( dc );
+        free_dc_ptr( dc );
         return 0;
     }
 
@@ -415,7 +415,7 @@ HDC WINAPI CreateEnhMetaFileW(
 
     TRACE("returning %p\n", dc->hSelf);
     ret = dc->hSelf;
-    DC_ReleaseDCPtr( dc );
+    release_dc_ptr( dc );
 
     if( !hdc )
       DeleteDC( hRefDC );
@@ -436,16 +436,16 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
 
     TRACE("(%p)\n", hdc );
 
-    if (!(dc = DC_GetDCPtr( hdc ))) return NULL;
+    if (!(dc = get_dc_ptr( hdc ))) return NULL;
     if (GDIMAGIC(dc->header.wMagic) != ENHMETAFILE_DC_MAGIC)
     {
-        DC_ReleaseDCPtr( dc );
+        release_dc_ptr( dc );
         return NULL;
     }
     if (dc->refcount != 1)
     {
         FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
-        DC_ReleaseDCPtr( dc );
+        release_dc_ptr( dc );
         return NULL;
     }
     physDev = (EMFDRV_PDEVICE *)dc->physDev;
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index 157a7de..adad616 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -393,11 +393,11 @@ extern INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp );
 extern void CLIPPING_UpdateGCRegion( DC * dc );
 
 /* dc.c */
-extern DC * DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic );
+extern DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic );
 extern DC * DC_GetDCUpdate( HDC hdc );
 extern DC * DC_GetDCPtr( HDC hdc );
 extern void DC_ReleaseDCPtr( DC *dc );
-extern BOOL DC_FreeDCPtr( DC *dc );
+extern BOOL free_dc_ptr( DC *dc );
 extern DC *get_dc_ptr( HDC hdc );
 extern void release_dc_ptr( DC *dc );
 extern void update_dc( DC *dc );
diff --git a/dlls/gdi32/mfdrv/init.c b/dlls/gdi32/mfdrv/init.c
index aa10e96..c2cf404 100644
--- a/dlls/gdi32/mfdrv/init.c
+++ b/dlls/gdi32/mfdrv/init.c
@@ -165,12 +165,12 @@ static DC *MFDRV_AllocMetaFile(void)
     DC *dc;
     METAFILEDRV_PDEVICE *physDev;
 
-    if (!(dc = DC_AllocDC( &MFDRV_Funcs, METAFILE_DC_MAGIC ))) return NULL;
+    if (!(dc = alloc_dc_ptr( &MFDRV_Funcs, METAFILE_DC_MAGIC ))) return NULL;
 
     physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
     if (!physDev)
     {
-        DC_FreeDCPtr( dc );
+        free_dc_ptr( dc );
         return NULL;
     }
     dc->physDev = (PHYSDEV)physDev;
@@ -179,7 +179,7 @@ static DC *MFDRV_AllocMetaFile(void)
     if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
     {
         HeapFree( GetProcessHeap(), 0, physDev );
-        DC_FreeDCPtr( dc );
+        free_dc_ptr( dc );
         return NULL;
     }
 
@@ -215,7 +215,7 @@ static BOOL MFDRV_DeleteDC( DC *dc )
     HeapFree( GetProcessHeap(), 0, physDev->handles );
     HeapFree( GetProcessHeap(), 0, physDev );
     dc->physDev = NULL;
-    DC_FreeDCPtr( dc );
+    free_dc_ptr( dc );
     return TRUE;
 }
 
@@ -267,7 +267,7 @@ HDC WINAPI CreateMetaFileW( LPCWSTR filename )
 
     TRACE("returning %p\n", dc->hSelf);
     ret = dc->hSelf;
-    DC_ReleaseDCPtr( dc );
+    release_dc_ptr( dc );
     return ret;
 }
 
@@ -306,16 +306,16 @@ static DC *MFDRV_CloseMetaFile( HDC hdc )
 
     TRACE("(%p)\n", hdc );
 
-    if (!(dc = DC_GetDCPtr( hdc ))) return NULL;
+    if (!(dc = get_dc_ptr( hdc ))) return NULL;
     if (GDIMAGIC(dc->header.wMagic) != METAFILE_DC_MAGIC)
     {
-        DC_ReleaseDCPtr( dc );
+        release_dc_ptr( dc );
         return NULL;
     }
     if (dc->refcount != 1)
     {
         FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
-        DC_ReleaseDCPtr( dc );
+        release_dc_ptr( dc );
         return NULL;
     }
     physDev = (METAFILEDRV_PDEVICE *)dc->physDev;




More information about the wine-cvs mailing list