File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -178,12 +178,7 @@ extern "C" fn release(this: &mut Object, _sel: Sel) {
178178 let retain_count_after_build = WindowState :: from_field ( this) . retain_count_after_build ;
179179
180180 if retain_count <= retain_count_after_build {
181- WindowState :: from_field ( this) . stop ( ) ;
182-
183- this. set_ivar ( BASEVIEW_STATE_IVAR , :: std:: ptr:: null ( ) as * const c_void ) ;
184-
185- // Drop WindowState
186- Box :: from_raw ( state_ptr as * mut WindowState ) ;
181+ WindowState :: stop_and_free ( this) ;
187182 }
188183 }
189184 }
Original file line number Diff line number Diff line change @@ -359,15 +359,26 @@ impl WindowState {
359359 }
360360
361361 /// Call when freeing view
362- pub ( super ) unsafe fn stop ( & mut self ) {
363- if let Some ( frame_timer) = self . frame_timer . take ( ) {
362+ pub ( super ) unsafe fn stop_and_free ( ns_view_obj : & mut Object ) {
363+ let state_ptr: * mut c_void = * ns_view_obj. get_ivar ( BASEVIEW_STATE_IVAR ) ;
364+
365+ // Take back ownership of Box<WindowState> so that it gets dropped
366+ // when it goes out of scope
367+ let mut window_state = Box :: from_raw ( state_ptr as * mut WindowState ) ;
368+
369+ if let Some ( frame_timer) = window_state. frame_timer . take ( ) {
364370 CFRunLoop :: get_current ( ) . remove_timer ( & frame_timer, kCFRunLoopDefaultMode) ;
365371 }
366372
367- self . trigger_event ( Event :: Window ( WindowEvent :: WillClose ) ) ;
373+ // Clear ivar before triggering WindowEvent::WillClose. Otherwise, if the
374+ // handler of the event causes another call to release, this function could be
375+ // called again, leading to a double free.
376+ ns_view_obj. set_ivar ( BASEVIEW_STATE_IVAR , :: std:: ptr:: null ( ) as * const c_void ) ;
377+
378+ window_state. trigger_event ( Event :: Window ( WindowEvent :: WillClose ) ) ;
368379
369380 // If in non-parented mode, we want to also quit the app altogether
370- if let Some ( app) = self . window . ns_app . take ( ) {
381+ if let Some ( app) = window_state . window . ns_app . take ( ) {
371382 app. stop_ ( app) ;
372383 }
373384 }
You can’t perform that action at this time.
0 commit comments