From a634ce37a6f634aa51278eef3eae5e9ba64ffdce Mon Sep 17 00:00:00 2001 From: James Liu Date: Sat, 22 Jul 2023 18:06:25 -0700 Subject: [PATCH] Stop using unwrap in the pipelined rendering thread (#9052) # Objective Fix #8936. ## Solution Stop using `unwrap` in the core pipelined rendering logic flow. Separately also scoped the `sub app` span to just running the render app instead of including the blocking send. Current unknowns: should we use `std::panic::catch_unwind` around running the render app? Other engine threads use it defensively, but we're letting it bubble up here, and a user-created panic could cause a deadlock if it kills the thread. --- ## Changelog Fixed: Pipelined rendering should no longer have spurious panics upon app exit. --- crates/bevy_render/src/pipelined_rendering.rs | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/crates/bevy_render/src/pipelined_rendering.rs b/crates/bevy_render/src/pipelined_rendering.rs index c96d936b85..0e2417e51d 100644 --- a/crates/bevy_render/src/pipelined_rendering.rs +++ b/crates/bevy_render/src/pipelined_rendering.rs @@ -103,21 +103,29 @@ impl Plugin for PipelinedRenderingPlugin { #[cfg(feature = "trace")] let _span = bevy_utils::tracing::info_span!("render thread").entered(); + let compute_task_pool = ComputeTaskPool::get(); loop { // run a scope here to allow main world to use this thread while it's waiting for the render app - let mut render_app = ComputeTaskPool::get() + let sent_app = compute_task_pool .scope(|s| { - s.spawn(async { app_to_render_receiver.recv().await.unwrap() }); + s.spawn(async { app_to_render_receiver.recv().await }); }) - .pop() - .unwrap(); + .pop(); + let Some(Ok(mut render_app)) = sent_app else { break }; - #[cfg(feature = "trace")] - let _sub_app_span = - bevy_utils::tracing::info_span!("sub app", name = ?RenderApp).entered(); - render_app.run(); - render_to_app_sender.send_blocking(render_app).unwrap(); + { + #[cfg(feature = "trace")] + let _sub_app_span = + bevy_utils::tracing::info_span!("sub app", name = ?RenderApp).entered(); + render_app.run(); + } + + if render_to_app_sender.send_blocking(render_app).is_err() { + break; + } } + + bevy_utils::tracing::debug!("exiting pipelined rendering thread"); }); } }