Fix double borrow error in Window::on_close callbacks when quitting app
Nathan Sobo
created
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.
@@ -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];
}