Don't allow strong view handles to be read/updated with an AsyncAppContext

This avoids an invitation to hold strong view handles across async await
points, which is a common source of leaks.

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2023-04-26 13:36:13 +02:00
parent 689e878bd8
commit 6317e885c7
14 changed files with 129 additions and 163 deletions

View file

@ -1,28 +1,24 @@
use std::{
path::{Path, PathBuf},
sync::Arc,
use crate::{
dock::DockPosition, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId,
};
use anyhow::{Context, Result};
use anyhow::{anyhow, Context, Result};
use async_recursion::async_recursion;
use gpui::{
platform::WindowBounds, AsyncAppContext, Axis, ModelHandle, Task, ViewHandle, WeakViewHandle,
};
use db::sqlez::{
bindable::{Bind, Column, StaticColumnCount},
statement::Statement,
};
use gpui::{
platform::WindowBounds, AsyncAppContext, Axis, ModelHandle, Task, ViewHandle, WeakViewHandle,
};
use project::Project;
use settings::DockAnchor;
use std::{
path::{Path, PathBuf},
sync::Arc,
};
use util::ResultExt;
use uuid::Uuid;
use crate::{
dock::DockPosition, ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WorkspaceLocation(Arc<Vec<PathBuf>>);
@ -134,7 +130,7 @@ impl SerializedPaneGroup {
}
SerializedPaneGroup::Pane(serialized_pane) => {
let pane = workspace
.update(cx, |workspace, cx| workspace.add_pane(cx))
.update(cx, |workspace, cx| workspace.add_pane(cx).downgrade())
.log_err()?;
let active = serialized_pane.active;
serialized_pane
@ -146,8 +142,10 @@ impl SerializedPaneGroup {
.read_with(cx, |pane, _| pane.items_len() != 0)
.log_err()?
{
let pane = pane.upgrade(cx)?;
Some((Member::Pane(pane.clone()), active.then(|| pane)))
} else {
let pane = pane.upgrade(cx)?;
workspace
.update(cx, |workspace, cx| workspace.remove_pane(pane, cx))
.log_err()?;
@ -172,7 +170,7 @@ impl SerializedPane {
pub async fn deserialize_to(
&self,
project: &ModelHandle<Project>,
pane_handle: &ViewHandle<Pane>,
pane_handle: &WeakViewHandle<Pane>,
workspace_id: WorkspaceId,
workspace: &WeakViewHandle<Workspace>,
cx: &mut AsyncAppContext,
@ -196,8 +194,12 @@ impl SerializedPane {
if let Some(item_handle) = item_handle {
workspace.update(cx, |workspace, cx| {
let pane_handle = pane_handle
.upgrade(cx)
.ok_or_else(|| anyhow!("pane was dropped"))?;
Pane::add_item(workspace, &pane_handle, item_handle, false, false, None, cx);
})?;
anyhow::Ok(())
})??;
}
if item.active {