Module: wine Branch: master Commit: f83159d90bda496ded992ecca9d479414bb46e16 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f83159d90bda496ded992ecca9...
Author: Józef Kucia jkucia@codeweavers.com Date: Thu Jul 20 14:10:58 2017 +0200
d3d11: Fix race condition in d3d_blend_state_create().
Spotted by Kimmo Myllyvirta.
Signed-off-by: Józef Kucia jkucia@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/d3d11/state.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/dlls/d3d11/state.c b/dlls/d3d11/state.c index 39768c5..be687f3 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -67,6 +67,12 @@ static ULONG STDMETHODCALLTYPE d3d11_blend_state_AddRef(ID3D11BlendState *iface) return refcount; }
+static void d3d_blend_state_cleanup(struct d3d_blend_state *state) +{ + wined3d_private_store_cleanup(&state->private_store); + ID3D11Device_Release(state->device); +} + static ULONG STDMETHODCALLTYPE d3d11_blend_state_Release(ID3D11BlendState *iface) { struct d3d_blend_state *state = impl_from_ID3D11BlendState(iface); @@ -79,8 +85,7 @@ static ULONG STDMETHODCALLTYPE d3d11_blend_state_Release(ID3D11BlendState *iface struct d3d_device *device = impl_from_ID3D11Device(state->device); wined3d_mutex_lock(); wine_rb_remove(&device->blend_states, &state->entry); - ID3D11Device_Release(state->device); - wined3d_private_store_cleanup(&state->private_store); + d3d_blend_state_cleanup(state); wined3d_mutex_unlock(); HeapFree(GetProcessHeap(), 0, state); } @@ -289,19 +294,9 @@ static HRESULT d3d_blend_state_init(struct d3d_blend_state *state, struct d3d_de state->ID3D11BlendState_iface.lpVtbl = &d3d11_blend_state_vtbl; state->ID3D10BlendState1_iface.lpVtbl = &d3d10_blend_state_vtbl; state->refcount = 1; - wined3d_mutex_lock(); wined3d_private_store_init(&state->private_store); state->desc = *desc;
- if (wine_rb_put(&device->blend_states, desc, &state->entry) == -1) - { - ERR("Failed to insert blend state entry.\n"); - wined3d_private_store_cleanup(&state->private_store); - wined3d_mutex_unlock(); - return E_FAIL; - } - wined3d_mutex_unlock(); - state->device = &device->ID3D11Device_iface; ID3D11Device_AddRef(state->device);
@@ -361,18 +356,31 @@ HRESULT d3d_blend_state_create(struct d3d_device *device, const D3D11_BLEND_DESC
return S_OK; } - wined3d_mutex_unlock();
if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object)))) + { + wined3d_mutex_unlock(); return E_OUTOFMEMORY; + }
if (FAILED(hr = d3d_blend_state_init(object, device, &tmp_desc))) { WARN("Failed to initialize blend state, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); + wined3d_mutex_unlock(); return hr; }
+ if (wine_rb_put(&device->blend_states, desc, &object->entry) == -1) + { + ERR("Failed to insert blend state entry.\n"); + d3d_blend_state_cleanup(object); + HeapFree(GetProcessHeap(), 0, object); + wined3d_mutex_unlock(); + return E_FAIL; + } + wined3d_mutex_unlock(); + TRACE("Created blend state %p.\n", object); *state = object;