From 10ae9eb3d9aecb71853b977d66cb775697e1a57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Thu, 20 Jul 2017 14:11:00 +0200 Subject: [PATCH] d3d11: Fix race condition in d3d_depthstencil_state_create(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spotted by Kimmo Myllyvirta. Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- 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 7cc35db2de5..3048b9db40d 100644 --- a/dlls/d3d11/state.c +++ b/dlls/d3d11/state.c @@ -447,6 +447,12 @@ static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_AddRef(ID3D11DepthStenci return refcount; } +static void d3d_depthstencil_state_cleanup(struct d3d_depthstencil_state *state) +{ + wined3d_private_store_cleanup(&state->private_store); + ID3D11Device_Release(state->device); +} + static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_Release(ID3D11DepthStencilState *iface) { struct d3d_depthstencil_state *state = impl_from_ID3D11DepthStencilState(iface); @@ -459,8 +465,7 @@ static ULONG STDMETHODCALLTYPE d3d11_depthstencil_state_Release(ID3D11DepthStenc struct d3d_device *device = impl_from_ID3D11Device(state->device); wined3d_mutex_lock(); wine_rb_remove(&device->depthstencil_states, &state->entry); - ID3D11Device_Release(state->device); - wined3d_private_store_cleanup(&state->private_store); + d3d_depthstencil_state_cleanup(state); wined3d_mutex_unlock(); HeapFree(GetProcessHeap(), 0, state); } @@ -647,19 +652,9 @@ static HRESULT d3d_depthstencil_state_init(struct d3d_depthstencil_state *state, state->ID3D11DepthStencilState_iface.lpVtbl = &d3d11_depthstencil_state_vtbl; state->ID3D10DepthStencilState_iface.lpVtbl = &d3d10_depthstencil_state_vtbl; state->refcount = 1; - wined3d_mutex_lock(); wined3d_private_store_init(&state->private_store); state->desc = *desc; - if (wine_rb_put(&device->depthstencil_states, desc, &state->entry) == -1) - { - ERR("Failed to insert depthstencil 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); @@ -725,18 +720,31 @@ HRESULT d3d_depthstencil_state_create(struct d3d_device *device, const D3D11_DEP 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_depthstencil_state_init(object, device, &tmp_desc))) { WARN("Failed to initialize depthstencil state, hr %#x.\n", hr); HeapFree(GetProcessHeap(), 0, object); + wined3d_mutex_unlock(); return hr; } + if (wine_rb_put(&device->depthstencil_states, desc, &object->entry) == -1) + { + ERR("Failed to insert depthstencil state entry.\n"); + d3d_depthstencil_state_cleanup(object); + HeapFree(GetProcessHeap(), 0, object); + wined3d_mutex_unlock(); + return E_FAIL; + } + wined3d_mutex_unlock(); + TRACE("Created depthstencil state %p.\n", object); *state = object;