mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-12 13:24:19 +00:00
Fix double borrow error in Window::on_close callbacks when quitting app
The simplest solution I could come up with was to make quitting the app asynchronous. Calling mac::Platform::quit enqueues a request to quit the app and then allows the call stack to fully return. This ensures we aren't holding a borrow when we quit and invoke all the Window::on_close callbacks. Seems like it should be fine to be async on quitting.
This commit is contained in:
parent
b292baf334
commit
2c74d75687
2 changed files with 22 additions and 6 deletions
|
@ -347,7 +347,20 @@ impl platform::Platform for MacPlatform {
|
|||
}
|
||||
|
||||
fn quit(&self) {
|
||||
// Quitting the app causes us to close windows, which invokes `Window::on_close` callbacks
|
||||
// synchronously before this method terminates. If we call `Platform::quit` while holding a
|
||||
// borrow of the app state (which most of the time we will do), we will end up
|
||||
// double-borrowing the app state in the `on_close` callbacks for our open windows. To solve
|
||||
// this, we make quitting the application asynchronous so that we aren't holding borrows to
|
||||
// the app state on the stack when we actually terminate the app.
|
||||
|
||||
use super::dispatcher::{dispatch_async_f, dispatch_get_main_queue};
|
||||
|
||||
unsafe {
|
||||
dispatch_async_f(dispatch_get_main_queue(), ptr::null_mut(), Some(quit));
|
||||
}
|
||||
|
||||
unsafe extern "C" fn quit(_: *mut c_void) {
|
||||
let app = NSApplication::sharedApplication(nil);
|
||||
let _: () = msg_send![app, terminate: nil];
|
||||
}
|
||||
|
|
|
@ -380,12 +380,15 @@ extern "C" fn send_event(this: &Object, _: Sel, native_event: id) {
|
|||
|
||||
extern "C" fn close_window(this: &Object, _: Sel) {
|
||||
unsafe {
|
||||
let window_state = get_window_state(this);
|
||||
let close_callback = window_state
|
||||
.as_ref()
|
||||
.try_borrow_mut()
|
||||
.ok()
|
||||
.and_then(|mut window_state| window_state.close_callback.take());
|
||||
let close_callback = {
|
||||
let window_state = get_window_state(this);
|
||||
window_state
|
||||
.as_ref()
|
||||
.try_borrow_mut()
|
||||
.ok()
|
||||
.and_then(|mut window_state| window_state.close_callback.take())
|
||||
};
|
||||
|
||||
if let Some(callback) = close_callback {
|
||||
callback();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue