Module: wine Branch: master Commit: de831f334c8a2b09a96bc881f8359a6f1c766729 URL: http://source.winehq.org/git/wine.git/?a=commit;h=de831f334c8a2b09a96bc881f8...
Author: Alexandre Julliard julliard@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;