Commit 7480bd32 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Don't hold the gdi lock while creating a DC.

parent fa5230fb
...@@ -71,9 +71,9 @@ static inline DC *get_dc_obj( HDC hdc ) ...@@ -71,9 +71,9 @@ static inline DC *get_dc_obj( HDC hdc )
/*********************************************************************** /***********************************************************************
* DC_AllocDC * alloc_dc_ptr
*/ */
DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic ) DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic )
{ {
HDC hdc; HDC hdc;
DC *dc; DC *dc;
...@@ -149,6 +149,7 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic ) ...@@ -149,6 +149,7 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
dc->BoundsRect.bottom = 0; dc->BoundsRect.bottom = 0;
dc->saved_visrgn = NULL; dc->saved_visrgn = NULL;
PATH_InitGdiPath(&dc->path); PATH_InitGdiPath(&dc->path);
GDI_ReleaseObj( dc->hSelf );
return dc; return dc;
} }
...@@ -189,11 +190,13 @@ void DC_ReleaseDCPtr( DC *dc ) ...@@ -189,11 +190,13 @@ void DC_ReleaseDCPtr( DC *dc )
/*********************************************************************** /***********************************************************************
* DC_FreeDCPtr * free_dc_ptr
*/ */
BOOL DC_FreeDCPtr( DC *dc ) BOOL free_dc_ptr( DC *dc )
{ {
assert( dc->refcount == 1 ); assert( dc->refcount == 1 );
/* grab the gdi lock again */
if (!GDI_GetObjPtr( dc->hSelf, MAGIC_DONTCARE )) return FALSE; /* shouldn't happen */
return GDI_FreeObject( dc->hSelf, dc ); return GDI_FreeObject( dc->hSelf, dc );
} }
...@@ -704,7 +707,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, ...@@ -704,7 +707,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
ERR( "no driver found for %s\n", debugstr_w(buf) ); ERR( "no driver found for %s\n", debugstr_w(buf) );
return 0; return 0;
} }
if (!(dc = DC_AllocDC( funcs, DC_MAGIC ))) goto error; if (!(dc = alloc_dc_ptr( funcs, DC_MAGIC ))) goto error;
hdc = dc->hSelf; hdc = dc->hSelf;
dc->hBitmap = GetStockObject( DEFAULT_BITMAP ); dc->hBitmap = GetStockObject( DEFAULT_BITMAP );
...@@ -724,12 +727,12 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, ...@@ -724,12 +727,12 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
GetDeviceCaps( hdc, DESKTOPHORZRES ), GetDeviceCaps( hdc, DESKTOPVERTRES ) ); GetDeviceCaps( hdc, DESKTOPHORZRES ), GetDeviceCaps( hdc, DESKTOPVERTRES ) );
DC_InitDC( dc ); DC_InitDC( dc );
DC_ReleaseDCPtr( dc ); release_dc_ptr( dc );
return hdc; return hdc;
error: error:
if (dc && dc->hVisRgn) DeleteObject( dc->hVisRgn ); if (dc && dc->hVisRgn) DeleteObject( dc->hVisRgn );
if (dc) DC_FreeDCPtr( dc ); if (dc) free_dc_ptr( dc );
DRIVER_release_driver( funcs ); DRIVER_release_driver( funcs );
return 0; return 0;
} }
...@@ -805,20 +808,20 @@ HDC WINAPI CreateCompatibleDC( HDC hdc ) ...@@ -805,20 +808,20 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
GDI_CheckNotLock(); GDI_CheckNotLock();
if ((origDC = DC_GetDCPtr( hdc ))) if ((origDC = get_dc_ptr( hdc )))
{ {
if (GetObjectType( hdc ) == OBJ_DC) if (GetObjectType( hdc ) == OBJ_DC)
{ {
funcs = origDC->funcs; funcs = origDC->funcs;
physDev = origDC->physDev; physDev = origDC->physDev;
} }
DC_ReleaseDCPtr( origDC ); /* can't hold the lock while loading the driver */ release_dc_ptr( origDC );
if (funcs) funcs = DRIVER_get_driver( funcs ); if (funcs) funcs = DRIVER_get_driver( funcs );
} }
if (!funcs && !(funcs = DRIVER_load_driver( displayW ))) return 0; if (!funcs && !(funcs = DRIVER_load_driver( displayW ))) return 0;
if (!(dc = DC_AllocDC( funcs, MEMORY_DC_MAGIC ))) goto error; if (!(dc = alloc_dc_ptr( funcs, MEMORY_DC_MAGIC ))) goto error;
TRACE("(%p): returning %p\n", hdc, dc->hSelf ); TRACE("(%p): returning %p\n", hdc, dc->hSelf );
...@@ -838,12 +841,12 @@ HDC WINAPI CreateCompatibleDC( HDC hdc ) ...@@ -838,12 +841,12 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
} }
DC_InitDC( dc ); DC_InitDC( dc );
DC_ReleaseDCPtr( dc ); release_dc_ptr( dc );
return dc->hSelf; return dc->hSelf;
error: error:
if (dc && dc->hVisRgn) DeleteObject( dc->hVisRgn ); if (dc && dc->hVisRgn) DeleteObject( dc->hVisRgn );
if (dc) DC_FreeDCPtr( dc ); if (dc) free_dc_ptr( dc );
DRIVER_release_driver( funcs ); DRIVER_release_driver( funcs );
return 0; return 0;
} }
...@@ -861,29 +864,26 @@ BOOL WINAPI DeleteDC( HDC hdc ) ...@@ -861,29 +864,26 @@ BOOL WINAPI DeleteDC( HDC hdc )
GDI_CheckNotLock(); GDI_CheckNotLock();
if (!(dc = DC_GetDCPtr( hdc ))) return FALSE; if (!(dc = get_dc_ptr( hdc ))) return FALSE;
if (dc->refcount != 1) if (dc->refcount != 1)
{ {
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount ); FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
DC_ReleaseDCPtr( dc ); release_dc_ptr( dc );
return FALSE; return FALSE;
} }
/* Call hook procedure to check whether is it OK to delete this DC */ /* Call hook procedure to check whether is it OK to delete this DC */
if (dc->hookThunk) if (dc->hookThunk && !dc->hookThunk( hdc, DCHC_DELETEDC, dc->dwHookData, 0 ))
{ {
DCHOOKPROC proc = dc->hookThunk; release_dc_ptr( dc );
DWORD_PTR data = dc->dwHookData; return FALSE;
DC_ReleaseDCPtr( dc );
if (!proc( hdc, DCHC_DELETEDC, data, 0 )) return FALSE;
if (!(dc = DC_GetDCPtr( hdc ))) return TRUE; /* deleted by the hook */
} }
while (dc->saveLevel) while (dc->saveLevel)
{ {
DC * dcs; DC * dcs;
HDC hdcs = dc->saved_dc; HDC hdcs = dc->saved_dc;
if (!(dcs = DC_GetDCPtr( hdcs ))) break; if (!(dcs = get_dc_ptr( hdcs ))) break;
dc->saved_dc = dcs->saved_dc; dc->saved_dc = dcs->saved_dc;
dc->saveLevel--; dc->saveLevel--;
if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn ); if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn );
...@@ -891,7 +891,7 @@ BOOL WINAPI DeleteDC( HDC hdc ) ...@@ -891,7 +891,7 @@ BOOL WINAPI DeleteDC( HDC hdc )
if (dcs->hMetaClipRgn) DeleteObject( dcs->hMetaClipRgn ); if (dcs->hMetaClipRgn) DeleteObject( dcs->hMetaClipRgn );
if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn ); if (dcs->hVisRgn) DeleteObject( dcs->hVisRgn );
PATH_DestroyGdiPath(&dcs->path); PATH_DestroyGdiPath(&dcs->path);
DC_FreeDCPtr( dcs ); free_dc_ptr( dcs );
} }
if (!(dc->flags & DC_SAVED)) if (!(dc->flags & DC_SAVED))
...@@ -918,7 +918,7 @@ BOOL WINAPI DeleteDC( HDC hdc ) ...@@ -918,7 +918,7 @@ BOOL WINAPI DeleteDC( HDC hdc )
if (dc->hVisRgn) DeleteObject( dc->hVisRgn ); if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
PATH_DestroyGdiPath(&dc->path); PATH_DestroyGdiPath(&dc->path);
DC_FreeDCPtr( dc ); free_dc_ptr( dc );
if (funcs) DRIVER_release_driver( funcs ); /* do that after releasing the GDI lock */ if (funcs) DRIVER_release_driver( funcs ); /* do that after releasing the GDI lock */
return TRUE; return TRUE;
} }
......
...@@ -171,7 +171,7 @@ static BOOL EMFDRV_DeleteDC( DC *dc ) ...@@ -171,7 +171,7 @@ static BOOL EMFDRV_DeleteDC( DC *dc )
HeapFree( GetProcessHeap(), 0, physDev->handles ); HeapFree( GetProcessHeap(), 0, physDev->handles );
HeapFree( GetProcessHeap(), 0, physDev ); HeapFree( GetProcessHeap(), 0, physDev );
dc->physDev = NULL; dc->physDev = NULL;
DC_FreeDCPtr( dc ); free_dc_ptr( dc );
return TRUE; return TRUE;
} }
...@@ -314,11 +314,11 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -314,11 +314,11 @@ HDC WINAPI CreateEnhMetaFileW(
TRACE("%s\n", debugstr_w(filename) ); TRACE("%s\n", debugstr_w(filename) );
if (!(dc = DC_AllocDC( &EMFDRV_Funcs, ENHMETAFILE_DC_MAGIC ))) return 0; if (!(dc = alloc_dc_ptr( &EMFDRV_Funcs, ENHMETAFILE_DC_MAGIC ))) return 0;
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev)); physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
if (!physDev) { if (!physDev) {
DC_FreeDCPtr( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
dc->physDev = (PHYSDEV)physDev; dc->physDev = (PHYSDEV)physDev;
...@@ -334,7 +334,7 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -334,7 +334,7 @@ HDC WINAPI CreateEnhMetaFileW(
if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) { if (!(physDev->emh = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size))) {
HeapFree( GetProcessHeap(), 0, physDev ); HeapFree( GetProcessHeap(), 0, physDev );
DC_FreeDCPtr( dc ); free_dc_ptr( dc );
return 0; return 0;
} }
...@@ -415,7 +415,7 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -415,7 +415,7 @@ HDC WINAPI CreateEnhMetaFileW(
TRACE("returning %p\n", dc->hSelf); TRACE("returning %p\n", dc->hSelf);
ret = dc->hSelf; ret = dc->hSelf;
DC_ReleaseDCPtr( dc ); release_dc_ptr( dc );
if( !hdc ) if( !hdc )
DeleteDC( hRefDC ); DeleteDC( hRefDC );
...@@ -436,16 +436,16 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */ ...@@ -436,16 +436,16 @@ HENHMETAFILE WINAPI CloseEnhMetaFile(HDC hdc) /* [in] metafile DC */
TRACE("(%p)\n", hdc ); TRACE("(%p)\n", hdc );
if (!(dc = DC_GetDCPtr( hdc ))) return NULL; if (!(dc = get_dc_ptr( hdc ))) return NULL;
if (GDIMAGIC(dc->header.wMagic) != ENHMETAFILE_DC_MAGIC) if (GDIMAGIC(dc->header.wMagic) != ENHMETAFILE_DC_MAGIC)
{ {
DC_ReleaseDCPtr( dc ); release_dc_ptr( dc );
return NULL; return NULL;
} }
if (dc->refcount != 1) if (dc->refcount != 1)
{ {
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount ); FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
DC_ReleaseDCPtr( dc ); release_dc_ptr( dc );
return NULL; return NULL;
} }
physDev = (EMFDRV_PDEVICE *)dc->physDev; physDev = (EMFDRV_PDEVICE *)dc->physDev;
......
...@@ -393,11 +393,11 @@ extern INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp ); ...@@ -393,11 +393,11 @@ extern INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp );
extern void CLIPPING_UpdateGCRegion( DC * dc ); extern void CLIPPING_UpdateGCRegion( DC * dc );
/* dc.c */ /* dc.c */
extern DC * DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic ); extern DC *alloc_dc_ptr( const DC_FUNCTIONS *funcs, WORD magic );
extern DC * DC_GetDCUpdate( HDC hdc ); extern DC * DC_GetDCUpdate( HDC hdc );
extern DC * DC_GetDCPtr( HDC hdc ); extern DC * DC_GetDCPtr( HDC hdc );
extern void DC_ReleaseDCPtr( DC *dc ); extern void DC_ReleaseDCPtr( DC *dc );
extern BOOL DC_FreeDCPtr( DC *dc ); extern BOOL free_dc_ptr( DC *dc );
extern DC *get_dc_ptr( HDC hdc ); extern DC *get_dc_ptr( HDC hdc );
extern void release_dc_ptr( DC *dc ); extern void release_dc_ptr( DC *dc );
extern void update_dc( DC *dc ); extern void update_dc( DC *dc );
......
...@@ -165,12 +165,12 @@ static DC *MFDRV_AllocMetaFile(void) ...@@ -165,12 +165,12 @@ static DC *MFDRV_AllocMetaFile(void)
DC *dc; DC *dc;
METAFILEDRV_PDEVICE *physDev; METAFILEDRV_PDEVICE *physDev;
if (!(dc = DC_AllocDC( &MFDRV_Funcs, METAFILE_DC_MAGIC ))) return NULL; if (!(dc = alloc_dc_ptr( &MFDRV_Funcs, METAFILE_DC_MAGIC ))) return NULL;
physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev)); physDev = HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
if (!physDev) if (!physDev)
{ {
DC_FreeDCPtr( dc ); free_dc_ptr( dc );
return NULL; return NULL;
} }
dc->physDev = (PHYSDEV)physDev; dc->physDev = (PHYSDEV)physDev;
...@@ -179,7 +179,7 @@ static DC *MFDRV_AllocMetaFile(void) ...@@ -179,7 +179,7 @@ static DC *MFDRV_AllocMetaFile(void)
if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) ))) if (!(physDev->mh = HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev->mh) )))
{ {
HeapFree( GetProcessHeap(), 0, physDev ); HeapFree( GetProcessHeap(), 0, physDev );
DC_FreeDCPtr( dc ); free_dc_ptr( dc );
return NULL; return NULL;
} }
...@@ -215,7 +215,7 @@ static BOOL MFDRV_DeleteDC( DC *dc ) ...@@ -215,7 +215,7 @@ static BOOL MFDRV_DeleteDC( DC *dc )
HeapFree( GetProcessHeap(), 0, physDev->handles ); HeapFree( GetProcessHeap(), 0, physDev->handles );
HeapFree( GetProcessHeap(), 0, physDev ); HeapFree( GetProcessHeap(), 0, physDev );
dc->physDev = NULL; dc->physDev = NULL;
DC_FreeDCPtr( dc ); free_dc_ptr( dc );
return TRUE; return TRUE;
} }
...@@ -267,7 +267,7 @@ HDC WINAPI CreateMetaFileW( LPCWSTR filename ) ...@@ -267,7 +267,7 @@ HDC WINAPI CreateMetaFileW( LPCWSTR filename )
TRACE("returning %p\n", dc->hSelf); TRACE("returning %p\n", dc->hSelf);
ret = dc->hSelf; ret = dc->hSelf;
DC_ReleaseDCPtr( dc ); release_dc_ptr( dc );
return ret; return ret;
} }
...@@ -306,16 +306,16 @@ static DC *MFDRV_CloseMetaFile( HDC hdc ) ...@@ -306,16 +306,16 @@ static DC *MFDRV_CloseMetaFile( HDC hdc )
TRACE("(%p)\n", hdc ); TRACE("(%p)\n", hdc );
if (!(dc = DC_GetDCPtr( hdc ))) return NULL; if (!(dc = get_dc_ptr( hdc ))) return NULL;
if (GDIMAGIC(dc->header.wMagic) != METAFILE_DC_MAGIC) if (GDIMAGIC(dc->header.wMagic) != METAFILE_DC_MAGIC)
{ {
DC_ReleaseDCPtr( dc ); release_dc_ptr( dc );
return NULL; return NULL;
} }
if (dc->refcount != 1) if (dc->refcount != 1)
{ {
FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount ); FIXME( "not deleting busy DC %p refcount %u\n", dc->hSelf, dc->refcount );
DC_ReleaseDCPtr( dc ); release_dc_ptr( dc );
return NULL; return NULL;
} }
physDev = (METAFILEDRV_PDEVICE *)dc->physDev; physDev = (METAFILEDRV_PDEVICE *)dc->physDev;
......
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