gpui: Fix update_window to borrow_mut will crash on Windows (#24545)

Release Notes:

- N/A

---


When we use `window_handle` to draw WebView on Windows, this will crash
by:

This error caused by when used WebView2.

```
thread 'main' panicked at crates\gpui\src\app\async_context.rs:91:28:
already borrowed: BorrowMutError
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread 'main' panicked at library\core\src\panicking.rs:221:5:
panic in a function that cannot unwind
```

Try this https://github.com/tauri-apps/wry/pull/1383 on Windows can
replay the crash.

In fact, we had done [a similar fix around August last
year](https://github.com/huacnlee/zed/pull/6), but we used the unsafe
method to avoid crashes in that version, we felt that it was not a good
change, so we do not make PR.

Today @sunli829 thought about it again and changed the method. Now using
`try_borrow_mut` is similar to the previous `borrow_mut`.


691de6b4b3/crates/gpui/src/app.rs (L70-L78)

I have tested to start Zed by those changes, it is looks no problem.

Co-authored-by: Sunli <scott_s829@163.com>
This commit is contained in:
Jason Lee 2025-05-20 22:17:16 +08:00 committed by GitHub
parent 051f49ce9a
commit 0fa9f05313
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 12 additions and 2 deletions

View file

@ -1,6 +1,6 @@
use std::{
any::{TypeId, type_name},
cell::{Ref, RefCell, RefMut},
cell::{BorrowMutError, Ref, RefCell, RefMut},
marker::PhantomData,
mem,
ops::{Deref, DerefMut},
@ -79,6 +79,16 @@ impl AppCell {
}
AppRefMut(self.app.borrow_mut())
}
#[doc(hidden)]
#[track_caller]
pub fn try_borrow_mut(&self) -> Result<AppRefMut, BorrowMutError> {
if option_env!("TRACK_THREAD_BORROWS").is_some() {
let thread_id = std::thread::current().id();
eprintln!("borrowed {thread_id:?}");
}
Ok(AppRefMut(self.app.try_borrow_mut()?))
}
}
#[doc(hidden)]

View file

@ -88,7 +88,7 @@ impl AppContext for AsyncApp {
F: FnOnce(AnyView, &mut Window, &mut App) -> T,
{
let app = self.app.upgrade().context("app was released")?;
let mut lock = app.borrow_mut();
let mut lock = app.try_borrow_mut()?;
lock.update_window(window, f)
}