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 )
*/
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 );
}
......
......@@ -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 );
}
......
......@@ -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 );
}
......
......@@ -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 );
}
/******************************************************************
......
......@@ -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 );
}
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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 );
}
/******************************************************************
......
......@@ -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 );
}
......
......@@ -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 );
}
......
......@@ -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;
......
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