From 5d56eddb7c17db867817def582e8f8316d7a6c20 Mon Sep 17 00:00:00 2001 From: Allan Tong Date: Sat, 26 Sep 2009 09:56:16 -0400 Subject: [PATCH] d3d9: Don't release the parent device before destroying its children. Releasing the device earlier may cause the underlying wineD3D device to be freed before the child object has had a chance to clean up. --- dlls/d3d9/cubetexture.c | 6 +++++- dlls/d3d9/indexbuffer.c | 6 +++++- dlls/d3d9/pixelshader.c | 6 +++++- dlls/d3d9/surface.c | 6 +++++- dlls/d3d9/swapchain.c | 6 +++++- dlls/d3d9/texture.c | 6 +++++- dlls/d3d9/vertexbuffer.c | 6 +++++- dlls/d3d9/vertexdeclaration.c | 6 +++++- dlls/d3d9/vertexshader.c | 6 +++++- dlls/d3d9/volumetexture.c | 6 +++++- 10 files changed, 50 insertions(+), 10 deletions(-) diff --git a/dlls/d3d9/cubetexture.c b/dlls/d3d9/cubetexture.c index 4bab9dfd021..10336b51dd8 100644 --- a/dlls/d3d9/cubetexture.c +++ b/dlls/d3d9/cubetexture.c @@ -67,12 +67,16 @@ static ULONG WINAPI IDirect3DCubeTexture9Impl_Release(LPDIRECT3DCUBETEXTURE9 ifa TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { + IDirect3DDevice9Ex *parentDevice = This->parentDevice; + TRACE("Releasing child %p\n", This->wineD3DCubeTexture); - IDirect3DDevice9Ex_Release(This->parentDevice); wined3d_mutex_lock(); IWineD3DCubeTexture_Release(This->wineD3DCubeTexture); wined3d_mutex_unlock(); + + /* Release the device last, as it may cause the device to be destroyed. */ + IDirect3DDevice9Ex_Release(parentDevice); } return ref; } diff --git a/dlls/d3d9/indexbuffer.c b/dlls/d3d9/indexbuffer.c index e089beaddc0..2748abb9fd6 100644 --- a/dlls/d3d9/indexbuffer.c +++ b/dlls/d3d9/indexbuffer.c @@ -65,10 +65,14 @@ static ULONG WINAPI IDirect3DIndexBuffer9Impl_Release(LPDIRECT3DINDEXBUFFER9 ifa TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { - IDirect3DDevice9Ex_Release(This->parentDevice); + IDirect3DDevice9Ex *parentDevice = This->parentDevice; + wined3d_mutex_lock(); IWineD3DBuffer_Release(This->wineD3DIndexBuffer); wined3d_mutex_unlock(); + + /* Release the device last, as it may cause the device to be destroyed. */ + IDirect3DDevice9Ex_Release(parentDevice); } return ref; } diff --git a/dlls/d3d9/pixelshader.c b/dlls/d3d9/pixelshader.c index 547dc746496..1c4214212c0 100644 --- a/dlls/d3d9/pixelshader.c +++ b/dlls/d3d9/pixelshader.c @@ -64,10 +64,14 @@ static ULONG WINAPI IDirect3DPixelShader9Impl_Release(LPDIRECT3DPIXELSHADER9 ifa TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { - IDirect3DDevice9Ex_Release(This->parentDevice); + IDirect3DDevice9Ex *parentDevice = This->parentDevice; + wined3d_mutex_lock(); IWineD3DPixelShader_Release(This->wineD3DPixelShader); wined3d_mutex_unlock(); + + /* Release the device last, as it may cause the device to be destroyed. */ + IDirect3DDevice9Ex_Release(parentDevice); } return ref; } diff --git a/dlls/d3d9/surface.c b/dlls/d3d9/surface.c index f9b2794a25c..0c277b91634 100644 --- a/dlls/d3d9/surface.c +++ b/dlls/d3d9/surface.c @@ -82,10 +82,14 @@ static ULONG WINAPI IDirect3DSurface9Impl_Release(LPDIRECT3DSURFACE9 iface) { TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { - if (This->parentDevice) IDirect3DDevice9Ex_Release(This->parentDevice); + IDirect3DDevice9Ex *parentDevice = This->parentDevice; + wined3d_mutex_lock(); IWineD3DSurface_Release(This->wineD3DSurface); wined3d_mutex_unlock(); + + /* Release the device last, as it may cause the device to be destroyed. */ + if (parentDevice) IDirect3DDevice9Ex_Release(parentDevice); } return ref; diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c index e63e3435b60..461db37fcd2 100644 --- a/dlls/d3d9/swapchain.c +++ b/dlls/d3d9/swapchain.c @@ -60,7 +60,8 @@ static ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface) TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { - if (This->parentDevice) IDirect3DDevice9Ex_Release(This->parentDevice); + IDirect3DDevice9Ex *parentDevice = This->parentDevice; + if (!This->isImplicit) { wined3d_mutex_lock(); IWineD3DSwapChain_Destroy(This->wineD3DSwapChain); @@ -68,6 +69,9 @@ static ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface) HeapFree(GetProcessHeap(), 0, This); } + + /* Release the device last, as it may cause the device to be destroyed. */ + if (parentDevice) IDirect3DDevice9Ex_Release(parentDevice); } return ref; } diff --git a/dlls/d3d9/texture.c b/dlls/d3d9/texture.c index 9818c2698b9..c63bb25456d 100644 --- a/dlls/d3d9/texture.c +++ b/dlls/d3d9/texture.c @@ -67,10 +67,14 @@ static ULONG WINAPI IDirect3DTexture9Impl_Release(LPDIRECT3DTEXTURE9 iface) { TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { - IDirect3DDevice9Ex_Release(This->parentDevice); + IDirect3DDevice9Ex *parentDevice = This->parentDevice; + wined3d_mutex_lock(); IWineD3DTexture_Release(This->wineD3DTexture); wined3d_mutex_unlock(); + + /* Release the device last, as it may cause the device to be destroyed. */ + IDirect3DDevice9Ex_Release(parentDevice); } return ref; } diff --git a/dlls/d3d9/vertexbuffer.c b/dlls/d3d9/vertexbuffer.c index c46f8b3f003..d1d7b548dc2 100644 --- a/dlls/d3d9/vertexbuffer.c +++ b/dlls/d3d9/vertexbuffer.c @@ -66,10 +66,14 @@ static ULONG WINAPI IDirect3DVertexBuffer9Impl_Release(LPDIRECT3DVERTEXBUFFER9 i TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { - IDirect3DDevice9Ex_Release(This->parentDevice); + IDirect3DDevice9Ex *parentDevice = This->parentDevice; + wined3d_mutex_lock(); IWineD3DBuffer_Release(This->wineD3DVertexBuffer); wined3d_mutex_unlock(); + + /* Release the device last, as it may cause the device to be destroyed. */ + IDirect3DDevice9Ex_Release(parentDevice); } return ref; } diff --git a/dlls/d3d9/vertexdeclaration.c b/dlls/d3d9/vertexdeclaration.c index 1234bffbe10..63b257c1e43 100644 --- a/dlls/d3d9/vertexdeclaration.c +++ b/dlls/d3d9/vertexdeclaration.c @@ -248,10 +248,14 @@ static ULONG WINAPI IDirect3DVertexDeclaration9Impl_Release(LPDIRECT3DVERTEXDECL TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { - IDirect3DDevice9Ex_Release(This->parentDevice); + IDirect3DDevice9Ex *parentDevice = This->parentDevice; + if(!This->convFVF) { IDirect3DVertexDeclaration9Impl_Destroy(iface); } + + /* Release the device last, as it may cause the device to be destroyed. */ + IDirect3DDevice9Ex_Release(parentDevice); } return ref; } diff --git a/dlls/d3d9/vertexshader.c b/dlls/d3d9/vertexshader.c index 8b775dedfb0..9293c204199 100644 --- a/dlls/d3d9/vertexshader.c +++ b/dlls/d3d9/vertexshader.c @@ -64,10 +64,14 @@ static ULONG WINAPI IDirect3DVertexShader9Impl_Release(LPDIRECT3DVERTEXSHADER9 i TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { - IDirect3DDevice9Ex_Release(This->parentDevice); + IDirect3DDevice9Ex *parentDevice = This->parentDevice; + wined3d_mutex_lock(); IWineD3DVertexShader_Release(This->wineD3DVertexShader); wined3d_mutex_unlock(); + + /* Release the device last, as it may cause the device to be destroyed. */ + IDirect3DDevice9Ex_Release(parentDevice); } return ref; } diff --git a/dlls/d3d9/volumetexture.c b/dlls/d3d9/volumetexture.c index 3adab632813..7a47e4ade6d 100644 --- a/dlls/d3d9/volumetexture.c +++ b/dlls/d3d9/volumetexture.c @@ -66,10 +66,14 @@ static ULONG WINAPI IDirect3DVolumeTexture9Impl_Release(LPDIRECT3DVOLUMETEXTURE9 TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { - IDirect3DDevice9Ex_Release(This->parentDevice); + IDirect3DDevice9Ex *parentDevice = This->parentDevice; + wined3d_mutex_lock(); IWineD3DVolumeTexture_Release(This->wineD3DVolumeTexture); wined3d_mutex_unlock(); + + /* Release the device last, as it may cause the device to be destroyed. */ + IDirect3DDevice9Ex_Release(parentDevice); } return ref; }