From ee2c2b33fbe04f0c2bc8d8362b943ac839e44f11 Mon Sep 17 00:00:00 2001 From: Allan Odgaard Date: Thu, 7 Mar 2013 22:00:18 +0100 Subject: [PATCH] Fix potential deadlock when opening find window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Find object is assigned to a variable with (guarded) static storage, so the initializer of the Find object will run with a lock on the guarded variable, which turns out to be shared with all other guarded variables. When setting up the window controller, from the Find object’s initializer, we create a “recent folders” menu which hold icons with SCM badges. When creating these SCM icons, blocks are scheduled (asynchronously) to “fetch status”. These asynchronous blocks will need to lock the same mutex as we currently have locked (because we haven’t yet left the initializer). The issue is that we also schedule synchronous blocks on the same queue, and that’s why we get a deadlock, because those can’t run before the asynchronous blocks have finished, yet those are waiting on the global lock that our main thread has currently obtained. Fixes #874. --- Frameworks/Find/src/Find.mm | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Frameworks/Find/src/Find.mm b/Frameworks/Find/src/Find.mm index 14f250287..4de849381 100644 --- a/Frameworks/Find/src/Find.mm +++ b/Frameworks/Find/src/Find.mm @@ -45,11 +45,10 @@ + (Find*)sharedInstance return instance; } -- (id)init +- (FindWindowController*)windowController { - if(self = [super init]) + if(!_windowController) { - D(DBF_Find_Base, bug("\n");); self.windowController = [FindWindowController new]; self.windowController.nextResponder = self; self.windowController.resultsOutlineView.action = @selector(didSingleClickResultsOutlineView:); @@ -60,7 +59,7 @@ - (id)init [self.windowController.window addObserver:self forKeyPath:@"firstResponder" options:0 context:NULL]; } - return self; + return _windowController; } // ====================================