Alexandre Julliard : gdi32: Release GDI handles before freeing the object.
Alexandre Julliard
julliard at winehq.org
Thu Jan 29 09:14:41 CST 2009
Module: wine
Branch: master
Commit: de831f334c8a2b09a96bc881f8359a6f1c766729
URL: http://source.winehq.org/git/wine.git/?a=commit;h=de831f334c8a2b09a96bc881f8359a6f1c766729
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jan 28 18:45:21 2009 +0100
gdi32: Release GDI handles before freeing the object.
This makes it unnecessary to hold the GDI lock during destruction.
---
dlls/gdi32/bitmap.c | 10 +++++++---
dlls/gdi32/brush.c | 4 ++--
dlls/gdi32/dc.c | 5 ++---
dlls/gdi32/enhmetafile.c | 4 ++--
dlls/gdi32/font.c | 8 +++++---
dlls/gdi32/gdi_private.h | 2 +-
dlls/gdi32/gdiobj.c | 24 ++++++++++++++----------
dlls/gdi32/metafile.c | 5 ++---
dlls/gdi32/palette.c | 4 ++--
dlls/gdi32/pen.c | 4 ++--
dlls/gdi32/region.c | 12 +++++++-----
11 files changed, 46 insertions(+), 36 deletions(-)
diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c
index 520964d..8bb21f2 100644
--- a/dlls/gdi32/bitmap.c
+++ b/dlls/gdi32/bitmap.c
@@ -628,12 +628,16 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
*/
static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
{
+ const DC_FUNCTIONS *funcs;
BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP );
if (!bmp) return FALSE;
+ funcs = bmp->funcs;
+ GDI_ReleaseObj( handle );
+
+ if (funcs && funcs->pDeleteBitmap) funcs->pDeleteBitmap( handle );
- if (bmp->funcs && bmp->funcs->pDeleteBitmap)
- bmp->funcs->pDeleteBitmap( handle );
+ if (!(bmp = free_gdi_handle( handle ))) return FALSE;
HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits );
@@ -665,7 +669,7 @@ static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
}
HeapFree(GetProcessHeap(), 0, bmp->color_table);
}
- return GDI_FreeObject( handle, bmp );
+ return HeapFree( GetProcessHeap(), 0, bmp );
}
diff --git a/dlls/gdi32/brush.c b/dlls/gdi32/brush.c
index 6b0369b..885fe88 100644
--- a/dlls/gdi32/brush.c
+++ b/dlls/gdi32/brush.c
@@ -416,7 +416,7 @@ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
*/
static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
{
- BRUSHOBJ *brush = GDI_GetObjPtr( handle, OBJ_BRUSH );
+ BRUSHOBJ *brush = free_gdi_handle( handle );
if (!brush) return FALSE;
switch(brush->logbrush.lbStyle)
@@ -428,7 +428,7 @@ static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
break;
}
- return GDI_FreeObject( handle, brush );
+ return HeapFree( GetProcessHeap(), 0, brush );
}
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c
index 5b05973..3648f64 100644
--- a/dlls/gdi32/dc.c
+++ b/dlls/gdi32/dc.c
@@ -163,9 +163,8 @@ DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
BOOL free_dc_ptr( DC *dc )
{
assert( dc->refcount == 1 );
- /* grab the gdi lock again */
- if (!GDI_GetObjPtr( dc->hSelf, 0 )) return FALSE; /* shouldn't happen */
- return GDI_FreeObject( dc->hSelf, dc );
+ if (free_gdi_handle( dc->hSelf ) != dc) return FALSE; /* shouldn't happen */
+ return HeapFree( GetProcessHeap(), 0, dc );
}
diff --git a/dlls/gdi32/enhmetafile.c b/dlls/gdi32/enhmetafile.c
index f77237b..9ca8517 100644
--- a/dlls/gdi32/enhmetafile.c
+++ b/dlls/gdi32/enhmetafile.c
@@ -276,7 +276,7 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk )
*/
static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
{
- ENHMETAFILEOBJ *metaObj = GDI_GetObjPtr( hmf, OBJ_ENHMETAFILE );
+ ENHMETAFILEOBJ *metaObj = free_gdi_handle( hmf );
if(!metaObj) return FALSE;
@@ -284,7 +284,7 @@ static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
UnmapViewOfFile( metaObj->emh );
else
HeapFree( GetProcessHeap(), 0, metaObj->emh );
- return GDI_FreeObject( hmf, metaObj );
+ return HeapFree( GetProcessHeap(), 0, metaObj );
}
/******************************************************************
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 2941f2c..409761a 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -559,10 +559,12 @@ static INT FONT_GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer )
*/
static BOOL FONT_DeleteObject( HGDIOBJ handle )
{
- FONTOBJ *obj = GDI_GetObjPtr( handle, OBJ_FONT ); /* to grab the GDI lock (FIXME) */
- if (!obj) return FALSE;
+ FONTOBJ *obj;
+
WineEngDestroyFontInstance( handle );
- return GDI_FreeObject( handle, obj );
+
+ if (!(obj = free_gdi_handle( handle ))) return FALSE;
+ return HeapFree( GetProcessHeap(), 0, obj );
}
diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h
index f2d3830..e78e496 100644
--- a/dlls/gdi32/gdi_private.h
+++ b/dlls/gdi32/gdi_private.h
@@ -439,7 +439,7 @@ extern BOOL WineEngRemoveFontResourceEx(LPCWSTR, DWORD, PVOID) DECLSPEC_HIDDEN;
extern BOOL GDI_Init(void) DECLSPEC_HIDDEN;
extern HGDIOBJ alloc_gdi_handle( GDIOBJHDR *obj, WORD type, const struct gdi_obj_funcs *funcs ) DECLSPEC_HIDDEN;
extern void *GDI_ReallocObject( WORD, HGDIOBJ, void *obj ) DECLSPEC_HIDDEN;
-extern BOOL GDI_FreeObject( HGDIOBJ, void *obj ) DECLSPEC_HIDDEN;
+extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern void *GDI_GetObjPtr( HGDIOBJ, WORD ) DECLSPEC_HIDDEN;
extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN;
extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN;
diff --git a/dlls/gdi32/gdiobj.c b/dlls/gdi32/gdiobj.c
index 647dcb8..cc87c6e 100644
--- a/dlls/gdi32/gdiobj.c
+++ b/dlls/gdi32/gdiobj.c
@@ -689,25 +689,29 @@ void *GDI_ReallocObject( WORD size, HGDIOBJ handle, void *object )
/***********************************************************************
- * GDI_FreeObject
+ * free_gdi_handle
+ *
+ * Free a GDI handle and return a pointer to the object.
*/
-BOOL GDI_FreeObject( HGDIOBJ handle, void *ptr )
+void *free_gdi_handle( HGDIOBJ handle )
{
- GDIOBJHDR *object = ptr;
+ GDIOBJHDR *object = NULL;
int i;
- object->type = 0; /* Mark it as invalid */
- object->funcs = NULL;
i = ((ULONG_PTR)handle >> 2) - FIRST_LARGE_HANDLE;
if (i >= 0 && i < MAX_LARGE_HANDLES)
{
- HeapFree( GetProcessHeap(), 0, large_handles[i] );
+ _EnterSysLevel( &GDI_level );
+ object = large_handles[i];
large_handles[i] = NULL;
+ _LeaveSysLevel( &GDI_level );
}
- else ERR( "Invalid handle %p\n", handle );
- TRACE("(%p): leave %d\n", handle, GDI_level.crst.RecursionCount);
- _LeaveSysLevel( &GDI_level );
- return TRUE;
+ if (object)
+ {
+ object->type = 0; /* mark it as invalid */
+ object->funcs = NULL;
+ }
+ return object;
}
diff --git a/dlls/gdi32/metafile.c b/dlls/gdi32/metafile.c
index bfa4bdd..ea75ae8 100644
--- a/dlls/gdi32/metafile.c
+++ b/dlls/gdi32/metafile.c
@@ -163,11 +163,10 @@ static POINT *convert_points( UINT count, POINT16 *pt16 )
BOOL WINAPI DeleteMetaFile( HMETAFILE hmf )
{
- METAFILEOBJ * metaObj = GDI_GetObjPtr( hmf, OBJ_METAFILE );
+ METAFILEOBJ * metaObj = free_gdi_handle( hmf );
if (!metaObj) return FALSE;
HeapFree( GetProcessHeap(), 0, metaObj->mh );
- GDI_FreeObject( hmf, metaObj );
- return TRUE;
+ return HeapFree( GetProcessHeap(), 0, metaObj );
}
/******************************************************************
diff --git a/dlls/gdi32/palette.c b/dlls/gdi32/palette.c
index 8f1c84a..a658440 100644
--- a/dlls/gdi32/palette.c
+++ b/dlls/gdi32/palette.c
@@ -679,8 +679,8 @@ static BOOL PALETTE_DeleteObject( HGDIOBJ handle )
PALETTEOBJ *obj;
PALETTE_UnrealizeObject( handle );
- if (!(obj = GDI_GetObjPtr( handle, OBJ_PAL ))) return FALSE;
- return GDI_FreeObject( handle, obj );
+ if (!(obj = free_gdi_handle( handle ))) return FALSE;
+ return HeapFree( GetProcessHeap(), 0, obj );
}
diff --git a/dlls/gdi32/pen.c b/dlls/gdi32/pen.c
index 52e6d8c..a130b1f 100644
--- a/dlls/gdi32/pen.c
+++ b/dlls/gdi32/pen.c
@@ -254,10 +254,10 @@ static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc )
*/
static BOOL PEN_DeleteObject( HGDIOBJ handle )
{
- PENOBJ *pen = GDI_GetObjPtr( handle, 0 );
+ PENOBJ *pen = free_gdi_handle( handle );
if (!pen) return FALSE;
- return GDI_FreeObject( handle, pen );
+ return HeapFree( GetProcessHeap(), 0, pen );
}
diff --git a/dlls/gdi32/region.c b/dlls/gdi32/region.c
index 92ea70b..b957bb8 100644
--- a/dlls/gdi32/region.c
+++ b/dlls/gdi32/region.c
@@ -542,11 +542,12 @@ static void REGION_DestroyWineRegion( WINEREGION* pReg )
*/
static BOOL REGION_DeleteObject( HGDIOBJ handle )
{
- RGNOBJ *rgn = GDI_GetObjPtr( handle, OBJ_REGION );
+ RGNOBJ *rgn = free_gdi_handle( handle );
if (!rgn) return FALSE;
REGION_DestroyWineRegion( rgn->rgn );
- return GDI_FreeObject( handle, rgn );
+ HeapFree( GetProcessHeap(), 0, rgn );
+ return TRUE;
}
/***********************************************************************
@@ -2820,7 +2821,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
if (! (pETEs = HeapAlloc( GetProcessHeap(), 0, sizeof(EdgeTableEntry) * total )))
{
REGION_DestroyWineRegion( region );
- GDI_FreeObject( hrgn, obj );
+ free_gdi_handle( hrgn );
+ HeapFree( GetProcessHeap(), 0, obj );
return 0;
}
pts = FirstPtBlock.pts;
@@ -2911,8 +2913,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
if(!tmpPtBlock) {
WARN("Can't alloc tPB\n");
REGION_DestroyWineRegion( region );
- GDI_FreeObject( hrgn, obj );
- HeapFree( GetProcessHeap(), 0, pETEs );
+ free_gdi_handle( hrgn );
+ HeapFree( GetProcessHeap(), 0, obj );
return 0;
}
curPtBlock->next = tmpPtBlock;
More information about the wine-cvs
mailing list