debugger: Fix deadlock in on_app_quit with debugger running (#29372)
This fixes a deadlock that would occur when `DapStore` had its on quit handler called. The deadlock was caused by `DapStore` spawning on the main thread while `App::shutdown` blocks the main thread. We added a debug_panic in GPUI that panics if a foreground task is spawned while the App context is shutting down. This will help tests catch hangs in `cx.on_app_quit` calls. Release Notes: - N/A --------- Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
parent
c3570fbcf3
commit
c3177e6f5b
10 changed files with 26 additions and 162 deletions
|
@ -28,7 +28,7 @@ use http_client::HttpClient;
|
|||
use smallvec::SmallVec;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub use test_context::*;
|
||||
use util::ResultExt;
|
||||
use util::{ResultExt, debug_panic};
|
||||
|
||||
use crate::{
|
||||
Action, ActionBuildError, ActionRegistry, Any, AnyView, AnyWindowHandle, AppContext, Asset,
|
||||
|
@ -271,6 +271,7 @@ pub struct App {
|
|||
pub(crate) tracked_entities: FxHashMap<WindowId, FxHashSet<EntityId>>,
|
||||
#[cfg(any(test, feature = "test-support", debug_assertions))]
|
||||
pub(crate) name: Option<&'static str>,
|
||||
quitting: bool,
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
@ -332,6 +333,7 @@ impl App {
|
|||
layout_id_buffer: Default::default(),
|
||||
propagate_event: true,
|
||||
prompt_builder: Some(PromptBuilder::Default),
|
||||
quitting: false,
|
||||
|
||||
#[cfg(any(test, feature = "test-support", debug_assertions))]
|
||||
name: None,
|
||||
|
@ -375,6 +377,7 @@ impl App {
|
|||
self.windows.clear();
|
||||
self.window_handles.clear();
|
||||
self.flush_effects();
|
||||
self.quitting = true;
|
||||
|
||||
let futures = futures::future::join_all(futures);
|
||||
if self
|
||||
|
@ -384,6 +387,8 @@ impl App {
|
|||
{
|
||||
log::error!("timed out waiting on app_will_quit");
|
||||
}
|
||||
|
||||
self.quitting = false;
|
||||
}
|
||||
|
||||
/// Get the id of the current keyboard layout
|
||||
|
@ -1049,6 +1054,9 @@ impl App {
|
|||
|
||||
/// Obtains a reference to the executor, which can be used to spawn futures.
|
||||
pub fn foreground_executor(&self) -> &ForegroundExecutor {
|
||||
if self.quitting {
|
||||
panic!("Can't spawn on main thread after on_app_quit")
|
||||
};
|
||||
&self.foreground_executor
|
||||
}
|
||||
|
||||
|
@ -1060,7 +1068,12 @@ impl App {
|
|||
AsyncFn: AsyncFnOnce(&mut AsyncApp) -> R + 'static,
|
||||
R: 'static,
|
||||
{
|
||||
if self.quitting {
|
||||
debug_panic!("Can't spawn on main thread after on_app_quit")
|
||||
};
|
||||
|
||||
let mut cx = self.to_async();
|
||||
|
||||
self.foreground_executor
|
||||
.spawn(async move { f(&mut cx).await })
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue