From 938e8654b76383396ee187ab751bb8fa6d67f37a Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Tue, 10 Nov 2009 21:29:19 +0000 Subject: - Add safeguards to ensure sequential runs when holding down run all/run selected keys in Custom Query, preventing NSLock deadlocks - Revery MCPConnection to locking on the *current* thread when running non-streaming queries, fixing deadlocks in some situations on background threads where the main thread is locked up via a modal loop - eg CSV import windows --- Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m | 14 +++++++++----- Source/CustomQuery.m | 6 ++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m index 55c1ef3d..456b615d 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m @@ -1340,8 +1340,10 @@ void performThreadedKeepAlive(void *ptr) } } - // Lock the connection - [self lockConnection]; + // Lock the connection - on this thread for normal result sets (avoiding blocking issues + // when the app is in modal mode), or ensuring a lock on the main thread for streaming queries. + if (streamResultType == MCP_NO_STREAMING) [queryLock lock]; + else [self lockConnection]; // Run (or re-run) the query, timing the execution time of the query - note // that this time will include network lag. @@ -1360,7 +1362,7 @@ void performThreadedKeepAlive(void *ptr) // For normal result sets, fetch the results and unlock the connection if (streamResultType == MCP_NO_STREAMING) { theResult = [[MCPResult alloc] initWithMySQLPtr:mConnection encoding:mEncoding timeZone:mTimeZone]; - [self unlockConnection]; + [queryLock unlock]; // For streaming result sets, fetch the result pointer and leave the connection locked } else if (streamResultType == MCP_FAST_STREAMING) { @@ -1376,7 +1378,8 @@ void performThreadedKeepAlive(void *ptr) break; } } else { - [self unlockConnection]; + if (streamResultType == MCP_NO_STREAMING) [queryLock unlock]; + else [self unlockConnection]; } queryErrorMessage = [[NSString alloc] initWithString:@""]; @@ -1387,7 +1390,8 @@ void performThreadedKeepAlive(void *ptr) // On failure, set the error messages and IDs } else { - [self unlockConnection]; + if (streamResultType == MCP_NO_STREAMING) [queryLock unlock]; + else [self unlockConnection]; queryErrorMessage = [[NSString alloc] initWithString:[self stringWithCString:mysql_error(mConnection)]]; queryErrorId = mysql_errno(mConnection); diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m index 55c87129..2a1492af 100644 --- a/Source/CustomQuery.m +++ b/Source/CustomQuery.m @@ -54,6 +54,9 @@ SPSQLParser *queryParser; NSArray *queries; + // Prevent multiple runs by holding the keys down + if ([tableDocumentInstance isWorking]) return; + // Fixes bug in key equivalents. if ([[NSApp currentEvent] type] == NSKeyUp) { return; @@ -108,6 +111,9 @@ NSRange selectedRange = [textView selectedRange]; SPSQLParser *queryParser; + // Prevent multiple runs by holding the keys down + if ([tableDocumentInstance isWorking]) return; + // If the current selection is a single caret position, run the current query. if (selectedRange.length == 0) { // BOOL doLookBehind = YES; -- cgit v1.2.3