Commit de831f33 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Release GDI handles before freeing the object.

This makes it unnecessary to hold the GDI lock during destruction.
parent 311c53db
...@@ -628,12 +628,16 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc ) ...@@ -628,12 +628,16 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
*/ */
static BOOL BITMAP_DeleteObject( HGDIOBJ handle ) static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
{ {
const DC_FUNCTIONS *funcs;
BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP ); BITMAPOBJ *bmp = GDI_GetObjPtr( handle, OBJ_BITMAP );
if (!bmp) return FALSE; if (!bmp) return FALSE;
funcs = bmp->funcs;
GDI_ReleaseObj( handle );
if (funcs && funcs->pDeleteBitmap) funcs->pDeleteBitmap( handle );
if (bmp->funcs && bmp->funcs->pDeleteBitmap) if (!(bmp = free_gdi_handle( handle ))) return FALSE;
bmp->funcs->pDeleteBitmap( handle );
HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits ); HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits );
...@@ -665,7 +669,7 @@ static BOOL BITMAP_DeleteObject( HGDIOBJ handle ) ...@@ -665,7 +669,7 @@ static BOOL BITMAP_DeleteObject( HGDIOBJ handle )
} }
HeapFree(GetProcessHeap(), 0, bmp->color_table); HeapFree(GetProcessHeap(), 0, bmp->color_table);
} }
return GDI_FreeObject( handle, bmp ); return HeapFree( GetProcessHeap(), 0, bmp );
} }
......
...@@ -416,7 +416,7 @@ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc ) ...@@ -416,7 +416,7 @@ static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, HDC hdc )
*/ */
static BOOL BRUSH_DeleteObject( HGDIOBJ handle ) static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
{ {
BRUSHOBJ *brush = GDI_GetObjPtr( handle, OBJ_BRUSH ); BRUSHOBJ *brush = free_gdi_handle( handle );
if (!brush) return FALSE; if (!brush) return FALSE;
switch(brush->logbrush.lbStyle) switch(brush->logbrush.lbStyle)
...@@ -428,7 +428,7 @@ static BOOL BRUSH_DeleteObject( HGDIOBJ handle ) ...@@ -428,7 +428,7 @@ static BOOL BRUSH_DeleteObject( HGDIOBJ handle )
GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch ); GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
break; break;
} }
return GDI_FreeObject( handle, brush ); return HeapFree( GetProcessHeap(), 0, brush );
} }
......
...@@ -163,9 +163,8 @@ DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic ) ...@@ -163,9 +163,8 @@ DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
BOOL free_dc_ptr( DC *dc ) BOOL free_dc_ptr( DC *dc )
{ {
assert( dc->refcount == 1 ); assert( dc->refcount == 1 );
/* grab the gdi lock again */ if (free_gdi_handle( dc->hSelf ) != dc) return FALSE; /* shouldn't happen */
if (!GDI_GetObjPtr( dc->hSelf, 0 )) return FALSE; /* shouldn't happen */ return HeapFree( GetProcessHeap(), 0, dc );
return GDI_FreeObject( dc->hSelf, dc );
} }
......
...@@ -276,7 +276,7 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk ) ...@@ -276,7 +276,7 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk )
*/ */
static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf ) static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
{ {
ENHMETAFILEOBJ *metaObj = GDI_GetObjPtr( hmf, OBJ_ENHMETAFILE ); ENHMETAFILEOBJ *metaObj = free_gdi_handle( hmf );
if(!metaObj) return FALSE; if(!metaObj) return FALSE;
...@@ -284,7 +284,7 @@ static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf ) ...@@ -284,7 +284,7 @@ static BOOL EMF_Delete_HENHMETAFILE( HENHMETAFILE hmf )
UnmapViewOfFile( metaObj->emh ); UnmapViewOfFile( metaObj->emh );
else else
HeapFree( GetProcessHeap(), 0, metaObj->emh ); HeapFree( GetProcessHeap(), 0, metaObj->emh );
return GDI_FreeObject( hmf, metaObj ); return HeapFree( GetProcessHeap(), 0, metaObj );
} }
/****************************************************************** /******************************************************************
......
...@@ -559,10 +559,12 @@ static INT FONT_GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer ) ...@@ -559,10 +559,12 @@ static INT FONT_GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer )
*/ */
static BOOL FONT_DeleteObject( HGDIOBJ handle ) static BOOL FONT_DeleteObject( HGDIOBJ handle )
{ {
FONTOBJ *obj = GDI_GetObjPtr( handle, OBJ_FONT ); /* to grab the GDI lock (FIXME) */ FONTOBJ *obj;
if (!obj) return FALSE;
WineEngDestroyFontInstance( handle ); WineEngDestroyFontInstance( handle );
return GDI_FreeObject( handle, obj );
if (!(obj = free_gdi_handle( handle ))) return FALSE;
return HeapFree( GetProcessHeap(), 0, obj );
} }
......
...@@ -439,7 +439,7 @@ extern BOOL WineEngRemoveFontResourceEx(LPCWSTR, DWORD, PVOID) DECLSPEC_HIDDEN; ...@@ -439,7 +439,7 @@ extern BOOL WineEngRemoveFontResourceEx(LPCWSTR, DWORD, PVOID) DECLSPEC_HIDDEN;
extern BOOL GDI_Init(void) 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 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 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_GetObjPtr( HGDIOBJ, WORD ) DECLSPEC_HIDDEN;
extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN; extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN;
extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN; extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN;
......
...@@ -689,25 +689,29 @@ void *GDI_ReallocObject( WORD size, HGDIOBJ handle, void *object ) ...@@ -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; int i;
object->type = 0; /* Mark it as invalid */
object->funcs = NULL;
i = ((ULONG_PTR)handle >> 2) - FIRST_LARGE_HANDLE; i = ((ULONG_PTR)handle >> 2) - FIRST_LARGE_HANDLE;
if (i >= 0 && i < MAX_LARGE_HANDLES) if (i >= 0 && i < MAX_LARGE_HANDLES)
{ {
HeapFree( GetProcessHeap(), 0, large_handles[i] ); _EnterSysLevel( &GDI_level );
object = large_handles[i];
large_handles[i] = NULL; large_handles[i] = NULL;
_LeaveSysLevel( &GDI_level );
} }
else ERR( "Invalid handle %p\n", handle ); if (object)
TRACE("(%p): leave %d\n", handle, GDI_level.crst.RecursionCount); {
_LeaveSysLevel( &GDI_level ); object->type = 0; /* mark it as invalid */
return TRUE; object->funcs = NULL;
}
return object;
} }
......
...@@ -163,11 +163,10 @@ static POINT *convert_points( UINT count, POINT16 *pt16 ) ...@@ -163,11 +163,10 @@ static POINT *convert_points( UINT count, POINT16 *pt16 )
BOOL WINAPI DeleteMetaFile( HMETAFILE hmf ) BOOL WINAPI DeleteMetaFile( HMETAFILE hmf )
{ {
METAFILEOBJ * metaObj = GDI_GetObjPtr( hmf, OBJ_METAFILE ); METAFILEOBJ * metaObj = free_gdi_handle( hmf );
if (!metaObj) return FALSE; if (!metaObj) return FALSE;
HeapFree( GetProcessHeap(), 0, metaObj->mh ); HeapFree( GetProcessHeap(), 0, metaObj->mh );
GDI_FreeObject( hmf, metaObj ); return HeapFree( GetProcessHeap(), 0, metaObj );
return TRUE;
} }
/****************************************************************** /******************************************************************
......
...@@ -679,8 +679,8 @@ static BOOL PALETTE_DeleteObject( HGDIOBJ handle ) ...@@ -679,8 +679,8 @@ static BOOL PALETTE_DeleteObject( HGDIOBJ handle )
PALETTEOBJ *obj; PALETTEOBJ *obj;
PALETTE_UnrealizeObject( handle ); PALETTE_UnrealizeObject( handle );
if (!(obj = GDI_GetObjPtr( handle, OBJ_PAL ))) return FALSE; if (!(obj = free_gdi_handle( handle ))) return FALSE;
return GDI_FreeObject( handle, obj ); return HeapFree( GetProcessHeap(), 0, obj );
} }
......
...@@ -254,10 +254,10 @@ static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc ) ...@@ -254,10 +254,10 @@ static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, HDC hdc )
*/ */
static BOOL PEN_DeleteObject( HGDIOBJ handle ) static BOOL PEN_DeleteObject( HGDIOBJ handle )
{ {
PENOBJ *pen = GDI_GetObjPtr( handle, 0 ); PENOBJ *pen = free_gdi_handle( handle );
if (!pen) return FALSE; if (!pen) return FALSE;
return GDI_FreeObject( handle, pen ); return HeapFree( GetProcessHeap(), 0, pen );
} }
......
...@@ -542,11 +542,12 @@ static void REGION_DestroyWineRegion( WINEREGION* pReg ) ...@@ -542,11 +542,12 @@ static void REGION_DestroyWineRegion( WINEREGION* pReg )
*/ */
static BOOL REGION_DeleteObject( HGDIOBJ handle ) static BOOL REGION_DeleteObject( HGDIOBJ handle )
{ {
RGNOBJ *rgn = GDI_GetObjPtr( handle, OBJ_REGION ); RGNOBJ *rgn = free_gdi_handle( handle );
if (!rgn) return FALSE; if (!rgn) return FALSE;
REGION_DestroyWineRegion( rgn->rgn ); 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, ...@@ -2820,7 +2821,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
if (! (pETEs = HeapAlloc( GetProcessHeap(), 0, sizeof(EdgeTableEntry) * total ))) if (! (pETEs = HeapAlloc( GetProcessHeap(), 0, sizeof(EdgeTableEntry) * total )))
{ {
REGION_DestroyWineRegion( region ); REGION_DestroyWineRegion( region );
GDI_FreeObject( hrgn, obj ); free_gdi_handle( hrgn );
HeapFree( GetProcessHeap(), 0, obj );
return 0; return 0;
} }
pts = FirstPtBlock.pts; pts = FirstPtBlock.pts;
...@@ -2911,8 +2913,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count, ...@@ -2911,8 +2913,8 @@ HRGN WINAPI CreatePolyPolygonRgn(const POINT *Pts, const INT *Count,
if(!tmpPtBlock) { if(!tmpPtBlock) {
WARN("Can't alloc tPB\n"); WARN("Can't alloc tPB\n");
REGION_DestroyWineRegion( region ); REGION_DestroyWineRegion( region );
GDI_FreeObject( hrgn, obj ); free_gdi_handle( hrgn );
HeapFree( GetProcessHeap(), 0, pETEs ); HeapFree( GetProcessHeap(), 0, obj );
return 0; return 0;
} }
curPtBlock->next = tmpPtBlock; curPtBlock->next = tmpPtBlock;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment