gdi32: Release GDI handles before freeing the object.
This makes it unnecessary to hold the GDI lock during destruction.
This commit is contained in:
parent
311c53db4f
commit
de831f334c
|
@ -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 (bmp->funcs && bmp->funcs->pDeleteBitmap)
|
||||
bmp->funcs->pDeleteBitmap( handle );
|
||||
if (funcs && funcs->pDeleteBitmap) 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;
|
||||
|
|
Loading…
Reference in New Issue