Jan Sikorski : wined3d: Make reference count decrementing functions thread safe.

Alexandre Julliard julliard at winehq.org
Fri Oct 15 15:40:05 CDT 2021


Module: wine
Branch: master
Commit: 90cd8b0764638bffe2f50fccf989189016b1359f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=90cd8b0764638bffe2f50fccf989189016b1359f

Author: Jan Sikorski <jsikorski at codeweavers.com>
Date:   Fri Oct 15 14:25:57 2021 +0200

wined3d: Make reference count decrementing functions thread safe.

Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/buffer.c            |  2 ++
 dlls/wined3d/cs.c                |  2 +-
 dlls/wined3d/device.c            |  2 ++
 dlls/wined3d/directx.c           |  2 ++
 dlls/wined3d/palette.c           |  4 ++++
 dlls/wined3d/query.c             |  2 ++
 dlls/wined3d/sampler.c           |  2 ++
 dlls/wined3d/shader.c            |  2 ++
 dlls/wined3d/state.c             |  6 ++++++
 dlls/wined3d/stateblock.c        |  2 ++
 dlls/wined3d/texture.c           |  7 +++++++
 dlls/wined3d/vertexdeclaration.c |  2 ++
 dlls/wined3d/view.c              | 12 ++++++++++++
 13 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 3430b8b1e97..d259b64bfaf 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -708,8 +708,10 @@ ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer)
 
     if (!refcount)
     {
+        wined3d_mutex_lock();
         buffer->resource.parent_ops->wined3d_object_destroyed(buffer->resource.parent);
         buffer->resource.device->adapter->adapter_ops->adapter_destroy_buffer(buffer);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 5934f36e1e9..f266e59b4b5 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -99,7 +99,6 @@ ULONG CDECL wined3d_command_list_decref(struct wined3d_command_list *list)
     {
         SIZE_T i;
 
-        wined3d_mutex_lock();
         for (i = 0; i < list->command_list_count; ++i)
             wined3d_command_list_decref(list->command_lists[i]);
         for (i = 0; i < list->resource_count; ++i)
@@ -109,6 +108,7 @@ ULONG CDECL wined3d_command_list_decref(struct wined3d_command_list *list)
         for (i = 0; i < list->query_count; ++i)
             wined3d_query_decref(list->queries[i].query);
 
+        wined3d_mutex_lock();
         wined3d_cs_destroy_object(device->cs, wined3d_command_list_destroy_object, list);
         wined3d_mutex_unlock();
     }
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index b8c1630ee25..6b2f18c6996 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -263,8 +263,10 @@ ULONG CDECL wined3d_device_decref(struct wined3d_device *device)
 
     if (!refcount)
     {
+        wined3d_mutex_lock();
         device->adapter->adapter_ops->adapter_destroy_device(device);
         TRACE("Destroyed device %p.\n", device);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 58aaf44fc45..c265bdc8c95 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -187,6 +187,7 @@ ULONG CDECL wined3d_decref(struct wined3d *wined3d)
     {
         unsigned int i;
 
+        wined3d_mutex_lock();
         for (i = 0; i < wined3d->adapter_count; ++i)
         {
             struct wined3d_adapter *adapter = wined3d->adapters[i];
@@ -194,6 +195,7 @@ ULONG CDECL wined3d_decref(struct wined3d *wined3d)
             adapter->adapter_ops->adapter_destroy(adapter);
         }
         heap_free(wined3d);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
diff --git a/dlls/wined3d/palette.c b/dlls/wined3d/palette.c
index 85105d1f8de..4bc453bde79 100644
--- a/dlls/wined3d/palette.c
+++ b/dlls/wined3d/palette.c
@@ -47,7 +47,11 @@ ULONG CDECL wined3d_palette_decref(struct wined3d_palette *palette)
     TRACE("%p decreasing refcount to %u.\n", palette, refcount);
 
     if (!refcount)
+    {
+        wined3d_mutex_lock();
         wined3d_cs_destroy_object(palette->device->cs, wined3d_palette_destroy_object, palette);
+        wined3d_mutex_unlock();
+    }
 
     return refcount;
 }
diff --git a/dlls/wined3d/query.c b/dlls/wined3d/query.c
index 8ee7ae07886..1b38eb5e311 100644
--- a/dlls/wined3d/query.c
+++ b/dlls/wined3d/query.c
@@ -444,9 +444,11 @@ ULONG CDECL wined3d_query_decref(struct wined3d_query *query)
     {
         struct wined3d_device *device = query->device;
 
+        wined3d_mutex_lock();
         query->parent_ops->wined3d_object_destroyed(query->parent);
         wined3d_cs_destroy_object(device->cs, wined3d_query_destroy_object, query);
         device->adapter->adapter_ops->adapter_destroy_query(query);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
diff --git a/dlls/wined3d/sampler.c b/dlls/wined3d/sampler.c
index 7eb3a2ae0be..bba3165316e 100644
--- a/dlls/wined3d/sampler.c
+++ b/dlls/wined3d/sampler.c
@@ -41,8 +41,10 @@ ULONG CDECL wined3d_sampler_decref(struct wined3d_sampler *sampler)
 
     if (!refcount)
     {
+        wined3d_mutex_lock();
         sampler->parent_ops->wined3d_object_destroyed(sampler->parent);
         sampler->device->adapter->adapter_ops->adapter_destroy_sampler(sampler);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index fb7115a26dd..957710dbd43 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -3439,8 +3439,10 @@ ULONG CDECL wined3d_shader_decref(struct wined3d_shader *shader)
 
     if (!refcount)
     {
+        wined3d_mutex_lock();
         shader->parent_ops->wined3d_object_destroyed(shader->parent);
         wined3d_cs_destroy_object(shader->device->cs, wined3d_shader_destroy_object, shader);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 8316269afcf..c7f041066d1 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -62,8 +62,10 @@ ULONG CDECL wined3d_blend_state_decref(struct wined3d_blend_state *state)
 
     if (!refcount)
     {
+        wined3d_mutex_lock();
         state->parent_ops->wined3d_object_destroyed(state->parent);
         wined3d_cs_destroy_object(device->cs, wined3d_blend_state_destroy_object, state);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
@@ -136,8 +138,10 @@ ULONG CDECL wined3d_depth_stencil_state_decref(struct wined3d_depth_stencil_stat
 
     if (!refcount)
     {
+        wined3d_mutex_lock();
         state->parent_ops->wined3d_object_destroyed(state->parent);
         wined3d_cs_destroy_object(device->cs, wined3d_depth_stencil_state_destroy_object, state);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
@@ -199,8 +203,10 @@ ULONG CDECL wined3d_rasterizer_state_decref(struct wined3d_rasterizer_state *sta
 
     if (!refcount)
     {
+        wined3d_mutex_lock();
         state->parent_ops->wined3d_object_destroyed(state->parent);
         wined3d_cs_destroy_object(device->cs, wined3d_rasterizer_state_destroy_object, state);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 39a19984498..8590a2a1c1f 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -585,8 +585,10 @@ ULONG CDECL wined3d_stateblock_decref(struct wined3d_stateblock *stateblock)
 
     if (!refcount)
     {
+        wined3d_mutex_lock();
         wined3d_stateblock_state_cleanup(&stateblock->stateblock_state);
         heap_free(stateblock);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 339bf4e205a..f031daef373 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1536,6 +1536,11 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture)
 
     if (!refcount)
     {
+        bool in_cs_thread = GetCurrentThreadId() == texture->resource.device->cs->thread_id;
+
+        /* This is called from the CS thread to destroy temporary textures. */
+        if (!in_cs_thread)
+            wined3d_mutex_lock();
         /* Wait for the texture to become idle if it's using user memory,
          * since the application is allowed to free that memory once the
          * texture is destroyed. Note that this implies that
@@ -1550,6 +1555,8 @@ ULONG CDECL wined3d_texture_decref(struct wined3d_texture *texture)
             }
         }
         texture->resource.device->adapter->adapter_ops->adapter_destroy_texture(texture);
+        if (!in_cs_thread)
+            wined3d_mutex_unlock();
     }
 
     return refcount;
diff --git a/dlls/wined3d/vertexdeclaration.c b/dlls/wined3d/vertexdeclaration.c
index 45a01f4bdd4..a778352d2cf 100644
--- a/dlls/wined3d/vertexdeclaration.c
+++ b/dlls/wined3d/vertexdeclaration.c
@@ -68,9 +68,11 @@ ULONG CDECL wined3d_vertex_declaration_decref(struct wined3d_vertex_declaration
 
     if (!refcount)
     {
+        wined3d_mutex_lock();
         declaration->parent_ops->wined3d_object_destroyed(declaration->parent);
         wined3d_cs_destroy_object(declaration->device->cs,
                 wined3d_vertex_declaration_destroy_object, declaration);
+        wined3d_mutex_unlock();
     }
 
     return refcount;
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index a8b3a7b4f75..94bbe27bd5c 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -376,7 +376,11 @@ ULONG CDECL wined3d_rendertarget_view_decref(struct wined3d_rendertarget_view *v
     TRACE("%p decreasing refcount to %u.\n", view, refcount);
 
     if (!refcount)
+    {
+        wined3d_mutex_lock();
         view->resource->device->adapter->adapter_ops->adapter_destroy_rendertarget_view(view);
+        wined3d_mutex_unlock();
+    }
 
     return refcount;
 }
@@ -923,7 +927,11 @@ ULONG CDECL wined3d_shader_resource_view_decref(struct wined3d_shader_resource_v
     TRACE("%p decreasing refcount to %u.\n", view, refcount);
 
     if (!refcount)
+    {
+        wined3d_mutex_lock();
         view->resource->device->adapter->adapter_ops->adapter_destroy_shader_resource_view(view);
+        wined3d_mutex_unlock();
+    }
 
     return refcount;
 }
@@ -1441,7 +1449,11 @@ ULONG CDECL wined3d_unordered_access_view_decref(struct wined3d_unordered_access
     TRACE("%p decreasing refcount to %u.\n", view, refcount);
 
     if (!refcount)
+    {
+        wined3d_mutex_lock();
         view->resource->device->adapter->adapter_ops->adapter_destroy_unordered_access_view(view);
+        wined3d_mutex_unlock();
+    }
 
     return refcount;
 }




More information about the wine-cvs mailing list