From b05d20103968508fa41dc1fc1e1d8a111c93f84a Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Tue, 7 Dec 2010 23:41:45 +0000 Subject: - Fix a race condition in conditions where the network has dropped, preventing possible MySQL library crashes --- Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h | 1 + Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'Frameworks/MCPKit') diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h index ad30fa07..61ce1261 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h @@ -57,6 +57,7 @@ typedef struct { BOOL useKeepAlive; BOOL isDisconnecting; + BOOL isReconnecting; BOOL userTriggeredDisconnect; NSInteger connectionTimeout; CGFloat keepAliveInterval; diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m index af203222..03cade24 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m @@ -141,6 +141,7 @@ static BOOL sTruncateLongFieldInLogs = YES; serverVersionString = nil; mTimeZone = nil; isDisconnecting = NO; + isReconnecting = NO; userTriggeredDisconnect = NO; automaticReconnectAttempts = 0; lastPingSuccess = NO; @@ -554,6 +555,22 @@ static BOOL sTruncateLongFieldInLogs = YES; NSString *currentEncoding = [NSString stringWithString:encoding]; BOOL currentEncodingUsesLatin1Transport = encodingUsesLatin1Transport; NSString *currentDatabase = nil; + + // Check whether a reconnection attempt is already being made - if so, wait and return the status of that reconnection attempt. + if (isReconnecting) { + NSDate *reconnectLoopStartdate = [NSDate date], *eventLoopStartDate; + while (isReconnecting) { + eventLoopStartDate = [NSDate date]; + [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + if ([[NSDate date] timeIntervalSinceDate:eventLoopStartDate] < 0.1) { + usleep(100000 - (1000000 * [[NSDate date] timeIntervalSinceDate:eventLoopStartDate])); + } + } + [reconnectionPool drain]; + return mConnected; + } + + isReconnecting = YES; // Store the currently selected database so it can be re-set if reconnection was successful if (delegate && [delegate respondsToSelector:@selector(onReconnectShouldSelectDatabase:)] && [delegate onReconnectShouldSelectDatabase:self]) { @@ -689,14 +706,17 @@ static BOOL sTruncateLongFieldInLogs = YES; [self setLastErrorMessage:NSLocalizedString(@"User triggered disconnection", @"User triggered disconnection")]; userTriggeredDisconnect = YES; [reconnectionPool release]; + isReconnecting = NO; return NO; default: [reconnectionPool release]; + isReconnecting = NO; return [self reconnect]; } } [reconnectionPool release]; + isReconnecting = NO; return mConnected; } -- cgit v1.2.3