From 333ed78529943390ce710b21408c91e275e19f8b Mon Sep 17 00:00:00 2001 From: teoxoy <28601907+teoxoy@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:52:32 +0200 Subject: [PATCH] [gl] reorder `program_cache` & `context` lock acquisition We are using `program_cache.try_lock()` when creting pipelines which is covered by a guard gotten from `context.lock()`. For the `.try_lock()` to always succeed we need to make sure that the other lock acquisitions are also covered by a `context.lock()`. The `wgpu_examples::hello_compute::tests::multithreaded_compute` test has been failing intermittently in CI due to this. --- wgpu-hal/src/gles/device.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wgpu-hal/src/gles/device.rs b/wgpu-hal/src/gles/device.rs index 34201fcbdb..66b34bcd13 100644 --- a/wgpu-hal/src/gles/device.rs +++ b/wgpu-hal/src/gles/device.rs @@ -1409,17 +1409,17 @@ impl crate::Device for super::Device { } unsafe fn destroy_render_pipeline(&self, pipeline: super::RenderPipeline) { - let mut program_cache = self.shared.program_cache.lock(); // If the pipeline only has 2 strong references remaining, they're `pipeline` and `program_cache` // This is safe to assume as long as: // - `RenderPipeline` can't be cloned // - The only place that we can get a new reference is during `program_cache.lock()` if Arc::strong_count(&pipeline.inner) == 2 { + let gl = &self.shared.context.lock(); + let mut program_cache = self.shared.program_cache.lock(); program_cache.retain(|_, v| match *v { Ok(ref p) => p.program != pipeline.inner.program, Err(_) => false, }); - let gl = &self.shared.context.lock(); unsafe { gl.delete_program(pipeline.inner.program) }; } @@ -1441,17 +1441,17 @@ impl crate::Device for super::Device { } unsafe fn destroy_compute_pipeline(&self, pipeline: super::ComputePipeline) { - let mut program_cache = self.shared.program_cache.lock(); // If the pipeline only has 2 strong references remaining, they're `pipeline` and `program_cache`` // This is safe to assume as long as: // - `ComputePipeline` can't be cloned // - The only place that we can get a new reference is during `program_cache.lock()` if Arc::strong_count(&pipeline.inner) == 2 { + let gl = &self.shared.context.lock(); + let mut program_cache = self.shared.program_cache.lock(); program_cache.retain(|_, v| match *v { Ok(ref p) => p.program != pipeline.inner.program, Err(_) => false, }); - let gl = &self.shared.context.lock(); unsafe { gl.delete_program(pipeline.inner.program) }; }