Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Trying to fix a range of crashes when closing a connection window
Caused by a use-after-free of an unretained ivar
  • Loading branch information
dmoagx committed Oct 5, 2015
1 parent 80f8cae commit d4641ec
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 6 deletions.
1 change: 1 addition & 0 deletions Source/SPDatabaseDocument.m
Expand Up @@ -6290,6 +6290,7 @@ - (void)_processDatabaseChangedBundleTriggerActions

- (void)dealloc
{
NSAssert([NSThread isMainThread], @"Calling %s from a background thread is not supported!",__func__);
#ifndef SP_CODA /* Unregister observers */
// Unregister observers
[prefs removeObserver:self forKeyPath:SPDisplayTableViewVerticalGridlines];
Expand Down
6 changes: 5 additions & 1 deletion Source/SPFunctions.h
Expand Up @@ -28,6 +28,10 @@
//
// More info at <https://github.com/sequelpro/sequelpro>


/**
* Synchronously execute a block on the main thread.
* This function can be called from a background thread as well as from
* the main thread.
*/
void SPMainQSync(void (^block)(void));

10 changes: 10 additions & 0 deletions Source/SPWindowController.h
Expand Up @@ -49,7 +49,17 @@
// Database connection management
- (IBAction)addNewConnection:(id)sender;
- (IBAction)moveSelectedTabInNewWindow:(id)sender;

/**
* @danger THIS IS NOT RETAINED!!!
*
* Ever only directly use it on the main thread!
* Do not cache it without retaining first!
* For background threads get it and retain it via the main thread!
* Release it on the main thread again.
*/
- (SPDatabaseDocument *)selectedTableDocument;

- (void)updateSelectedTableDocument;
- (void)updateAllTabTitles:(id)sender;
- (IBAction)closeTab:(id)sender;
Expand Down
34 changes: 30 additions & 4 deletions Source/SPWindowController.m
Expand Up @@ -53,7 +53,8 @@ - (void)_setUpTabBar;
- (void)_updateProgressIndicatorForItem:(NSTabViewItem *)theItem;
- (void)_createTitleBarLineHidingView;
- (void)_updateLineHidingViewState;

- (void)_switchOutSelectedTableDocument:(SPDatabaseDocument *)newDoc;
- (void)_selectedTableDocumentDeallocd:(NSNotification *)notification;
@end

@implementation SPWindowController
Expand All @@ -63,7 +64,7 @@ @implementation SPWindowController

- (void)awakeFromNib
{
selectedTableDocument = nil;
[self _switchOutSelectedTableDocument:nil];

[[self window] setCollectionBehavior:[[self window] collectionBehavior] | NSWindowCollectionBehaviorFullScreenPrimary];

Expand Down Expand Up @@ -141,7 +142,7 @@ - (SPDatabaseDocument *)selectedTableDocument
*/
- (void)updateSelectedTableDocument
{
selectedTableDocument = [[tabView selectedTabViewItem] identifier];
[self _switchOutSelectedTableDocument:[[tabView selectedTabViewItem] identifier]];

[selectedTableDocument didBecomeActiveTabInWindow];
}
Expand Down Expand Up @@ -388,7 +389,7 @@ - (NSMethodSignature *)methodSignatureForSelector:(SEL)theSelector
*/
- (BOOL)respondsToSelector:(SEL)theSelector
{
return ([super respondsToSelector:theSelector] || (selectedTableDocument && [selectedTableDocument respondsToSelector:theSelector]));
return ([super respondsToSelector:theSelector] || [selectedTableDocument respondsToSelector:theSelector]);
}

/**
Expand Down Expand Up @@ -529,10 +530,35 @@ - (void)_updateLineHidingViewState
}
}


- (void)_switchOutSelectedTableDocument:(SPDatabaseDocument *)newDoc
{
NSAssert([NSThread isMainThread], @"Switching the selectedTableDocument via a background thread is not supported!");

// shortcut if there is nothing to do
if(selectedTableDocument == newDoc) return;

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
if(selectedTableDocument) {
[nc removeObserver:self name:SPDocumentWillCloseNotification object:selectedTableDocument];
selectedTableDocument = nil;
}
if(newDoc) {
[nc addObserver:self selector:@selector(_selectedTableDocumentDeallocd:) name:SPDocumentWillCloseNotification object:newDoc];
selectedTableDocument = newDoc;
}
}

- (void)_selectedTableDocumentDeallocd:(NSNotification *)notification
{
[self _switchOutSelectedTableDocument:nil];
}

#pragma mark -

- (void)dealloc
{
[self _switchOutSelectedTableDocument:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self];

[NSObject cancelPreviousPerformRequestsWithTarget:self];
Expand Down
3 changes: 2 additions & 1 deletion Source/SPWindowControllerDelegate.m
Expand Up @@ -41,6 +41,7 @@ @interface SPWindowController (SPDeclaredAPI)

- (void)_updateProgressIndicatorForItem:(NSTabViewItem *)theItem;
- (void)_updateLineHidingViewState;
- (void)_switchOutSelectedTableDocument:(SPDatabaseDocument *)newDoc;

@end

Expand Down Expand Up @@ -186,7 +187,7 @@ - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabVi
{
if ([[PSMTabDragAssistant sharedDragAssistant] isDragging]) return;

selectedTableDocument = [tabViewItem identifier];
[self _switchOutSelectedTableDocument:[tabViewItem identifier]];
[selectedTableDocument didBecomeActiveTabInWindow];

if ([[self window] isKeyWindow]) [selectedTableDocument tabDidBecomeKey];
Expand Down

0 comments on commit d4641ec

Please sign in to comment.