From 9065e4c1cbe918b8db586609ae6f773f510e29d7 Mon Sep 17 00:00:00 2001 From: Layl <2385329-layl@users.noreply.gitlab.com> Date: Tue, 24 Dec 2019 20:54:26 +0100 Subject: [PATCH] Hotfix deadlocks on resource cleanup --- wgpu-core/src/device.rs | 99 ++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 32 deletions(-) diff --git a/wgpu-core/src/device.rs b/wgpu-core/src/device.rs index 2c7a16e40c..40ffe200d0 100644 --- a/wgpu-core/src/device.rs +++ b/wgpu-core/src/device.rs @@ -940,12 +940,19 @@ impl> Global { pub fn buffer_destroy(&self, buffer_id: BufferId) { let hub = B::hub(self); let mut token = Token::root(); - let (device_guard, mut token) = hub.devices.read(&mut token); - let (buffer_guard, _) = hub.buffers.read(&mut token); - let buffer = &buffer_guard[buffer_id]; - device_guard[buffer.device_id.value].pending.lock().destroy( + + // Deadlock hotfix, pending doesn't have a token + let (device_id, ref_count) = { + let (buffer_guard, _) = hub.buffers.read(&mut token); + let buffer = &buffer_guard[buffer_id]; + + (buffer.device_id.value, buffer.life_guard.ref_count.clone()) + }; + + let (device_guard, _) = hub.devices.read(&mut token); + device_guard[device_id].pending.lock().destroy( ResourceId::Buffer(buffer_id), - buffer.life_guard.ref_count.clone(), + ref_count, ); } } @@ -981,15 +988,21 @@ impl> Global { let hub = B::hub(self); let mut token = Token::root(); - let (device_guard, mut token) = hub.devices.read(&mut token); - let (texture_guard, _) = hub.textures.read(&mut token); - let texture = &texture_guard[texture_id]; - device_guard[texture.device_id.value] + // Deadlock hotfix, pending doesn't have a token + let (device_id, ref_count) = { + let (texture_guard, _) = hub.textures.read(&mut token); + let texture = &texture_guard[texture_id]; + + (texture.device_id.value, texture.life_guard.ref_count.clone()) + }; + + let (device_guard, _) = hub.devices.read(&mut token); + device_guard[device_id] .pending .lock() .destroy( ResourceId::Texture(texture_id), - texture.life_guard.ref_count.clone(), + ref_count, ); } } @@ -1087,21 +1100,29 @@ impl> Global { pub fn texture_view_destroy(&self, texture_view_id: TextureViewId) { let hub = B::hub(self); let mut token = Token::root(); - let (device_guard, mut token) = hub.devices.read(&mut token); - let (texture_guard, mut token) = hub.textures.read(&mut token); - let (texture_view_guard, _) = hub.texture_views.read(&mut token); - let view = &texture_view_guard[texture_view_id]; - let device_id = match view.inner { - resource::TextureViewInner::Native { ref source_id, .. } => { - texture_guard[source_id.value].device_id.value - } - resource::TextureViewInner::SwapChain { .. } => { - panic!("Can't destroy a swap chain image") - } + + // Deadlock hotfix, pending doesn't have a token + let (device_id, ref_count) = { + let (texture_guard, mut token) = hub.textures.read(&mut token); + let (texture_view_guard, _) = hub.texture_views.read(&mut token); + + let view = &texture_view_guard[texture_view_id]; + let device_id = match view.inner { + resource::TextureViewInner::Native { ref source_id, .. } => { + texture_guard[source_id.value].device_id.value + } + resource::TextureViewInner::SwapChain { .. } => { + panic!("Can't destroy a swap chain image") + } + }; + + (device_id, view.life_guard.ref_count.clone()) }; + + let (device_guard, _) = hub.devices.read(&mut token); device_guard[device_id].pending.lock().destroy( ResourceId::TextureView(texture_view_id), - view.life_guard.ref_count.clone(), + ref_count, ); } } @@ -1158,15 +1179,22 @@ impl> Global { pub fn sampler_destroy(&self, sampler_id: SamplerId) { let hub = B::hub(self); let mut token = Token::root(); - let (device_guard, mut token) = hub.devices.read(&mut token); - let (sampler_guard, _) = hub.samplers.read(&mut token); - let sampler = &sampler_guard[sampler_id]; - device_guard[sampler.device_id.value] + + // Deadlock hotfix, pending doesn't have a token + let (device_id, ref_count) = { + let (sampler_guard, _) = hub.samplers.read(&mut token); + let sampler = &sampler_guard[sampler_id]; + + (sampler.device_id.value, sampler.life_guard.ref_count.clone()) + }; + + let (device_guard, _) = hub.devices.read(&mut token); + device_guard[device_id] .pending .lock() .destroy( ResourceId::Sampler(sampler_id), - sampler.life_guard.ref_count.clone(), + ref_count, ); } } @@ -1461,15 +1489,22 @@ impl> Global { pub fn bind_group_destroy(&self, bind_group_id: BindGroupId) { let hub = B::hub(self); let mut token = Token::root(); - let (device_guard, mut token) = hub.devices.read(&mut token); - let (bind_group_guard, _) = hub.bind_groups.read(&mut token); - let bind_group = &bind_group_guard[bind_group_id]; - device_guard[bind_group.device_id.value] + + // Deadlock hotfix, pending doesn't have a token + let (device_id, ref_count) = { + let (bind_group_guard, _) = hub.bind_groups.read(&mut token); + let bind_group = &bind_group_guard[bind_group_id]; + + (bind_group.device_id.value, bind_group.life_guard.ref_count.clone()) + }; + + let (device_guard, _) = hub.devices.read(&mut token); + device_guard[device_id] .pending .lock() .destroy( ResourceId::BindGroup(bind_group_id), - bind_group.life_guard.ref_count.clone(), + ref_count, ); } }