aboutsummaryrefslogtreecommitdiffstats
path: root/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
diff options
context:
space:
mode:
Diffstat (limited to 'Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m')
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m278
1 files changed, 135 insertions, 143 deletions
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
index 73cadd6e..70894d05 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
@@ -735,185 +735,181 @@ asm(".desc ___crashreporter_info__, 0x10");
if (userTriggeredDisconnect) return NO;
BOOL reconnectSucceeded = NO;
- NSAutoreleasePool *reconnectionPool = [[NSAutoreleasePool alloc] init];
-
- // Check whether a reconnection attempt is already being made - if so, wait
- // and return the status of that reconnection attempt. This improves threaded
- // use of the connection by preventing reconnect races.
- if (reconnectingThread && !pthread_equal(reconnectingThread, pthread_self())) {
-
- // Loop in a panel runloop mode until the reconnection has processed; if an iteration
- // takes less than the requested 0.1s, sleep instead.
- while (reconnectingThread) {
- uint64_t loopIterationStart_t = mach_absolute_time();
+ @autoreleasepool {
+ // Check whether a reconnection attempt is already being made - if so, wait
+ // and return the status of that reconnection attempt. This improves threaded
+ // use of the connection by preventing reconnect races.
+ if (reconnectingThread && !pthread_equal(reconnectingThread, pthread_self())) {
+
+ // Loop in a panel runloop mode until the reconnection has processed; if an iteration
+ // takes less than the requested 0.1s, sleep instead.
+ while (reconnectingThread) {
+ uint64_t loopIterationStart_t = mach_absolute_time();
+
+ [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
+ if (_elapsedSecondsSinceAbsoluteTime(loopIterationStart_t) < 0.1) {
+ usleep(100000 - (useconds_t)(1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t)));
+ }
+ }
- [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
- if (_elapsedSecondsSinceAbsoluteTime(loopIterationStart_t) < 0.1) {
- usleep(100000 - (useconds_t)(1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t)));
+ // Continue only if the reconnection being waited on was a background attempt
+ if (!(state == SPMySQLConnectionLostInBackground && canRetry)) {
+ return (state == SPMySQLConnected);
}
}
- // Continue only if the reconnection being waited on was a background attempt
- if (!(state == SPMySQLConnectionLostInBackground && canRetry)) {
- [reconnectionPool drain];
- return (state == SPMySQLConnected);
+ if ([[NSThread currentThread] isCancelled]) {
+ return NO;
}
- }
- if ([[NSThread currentThread] isCancelled]) {
- [reconnectionPool release];
- return NO;
- }
+ reconnectingThread = pthread_self();
- reconnectingThread = pthread_self();
+ // Store certain details about the connection, so that if the reconnection is successful
+ // they can be restored. This has to be treated separately from _restoreConnectionDetails
+ // as a full connection reinitialises certain values from the server.
+ if (!encodingToRestore) {
+ encodingToRestore = [encoding copy];
+ encodingUsesLatin1TransportToRestore = encodingUsesLatin1Transport;
+ databaseToRestore = [database copy];
+ }
- // Store certain details about the connection, so that if the reconnection is successful
- // they can be restored. This has to be treated separately from _restoreConnectionDetails
- // as a full connection reinitialises certain values from the server.
- if (!encodingToRestore) {
- encodingToRestore = [encoding copy];
- encodingUsesLatin1TransportToRestore = encodingUsesLatin1Transport;
- databaseToRestore = [database copy];
- }
+ // If there is a connection proxy, temporarily disassociate the state change action
+ if (proxy) proxyStateChangeNotificationsIgnored = YES;
- // If there is a connection proxy, temporarily disassociate the state change action
- if (proxy) proxyStateChangeNotificationsIgnored = YES;
+ // Close the connection if it's active
+ [self _disconnect];
- // Close the connection if it's active
- [self _disconnect];
+ // Lock the connection while waiting for network and proxy
+ [self _lockConnection];
- // Lock the connection while waiting for network and proxy
- [self _lockConnection];
+ // If no network is present, wait for a short time for one to become available
+ [self _waitForNetworkConnectionWithTimeout:10];
- // If no network is present, wait for a short time for one to become available
- [self _waitForNetworkConnectionWithTimeout:10];
+ if ([[NSThread currentThread] isCancelled]) {
+ [self _unlockConnection];
+ reconnectingThread = NULL;
+ return NO;
+ }
- if ([[NSThread currentThread] isCancelled]) {
- [self _unlockConnection];
- reconnectingThread = NULL;
- [reconnectionPool release];
- return NO;
- }
+ // If there is a proxy, attempt to reconnect it in blocking fashion
+ if (proxy) {
+ uint64_t loopIterationStart_t, proxyWaitStart_t;
- // If there is a proxy, attempt to reconnect it in blocking fashion
- if (proxy) {
- uint64_t loopIterationStart_t, proxyWaitStart_t;
+ // If the proxy is not yet idle after requesting a disconnect, wait for a short time
+ // to allow it to disconnect.
+ if ([proxy state] != SPMySQLProxyIdle) {
- // If the proxy is not yet idle after requesting a disconnect, wait for a short time
- // to allow it to disconnect.
- if ([proxy state] != SPMySQLProxyIdle) {
+ proxyWaitStart_t = mach_absolute_time();
+ while ([proxy state] != SPMySQLProxyIdle) {
+ loopIterationStart_t = mach_absolute_time();
+ // If the connection timeout has passed, break out of the loop
+ if (_elapsedSecondsSinceAbsoluteTime(proxyWaitStart_t) > timeout) break;
+
+ // Allow events to process for 0.25s, sleeping to completion on early return
+ [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
+ if (_elapsedSecondsSinceAbsoluteTime(loopIterationStart_t) < 0.25) {
+ usleep(250000 - (useconds_t)(1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t)));
+ }
+ }
+ }
+
+ // Request that the proxy re-establishes its connection
+ [proxy connect];
+
+ // Wait while the proxy connects
proxyWaitStart_t = mach_absolute_time();
- while ([proxy state] != SPMySQLProxyIdle) {
+ while (1) {
loopIterationStart_t = mach_absolute_time();
- // If the connection timeout has passed, break out of the loop
- if (_elapsedSecondsSinceAbsoluteTime(proxyWaitStart_t) > timeout) break;
+ // If the proxy has connected, record the new local port and break out of the loop
+ if ([proxy state] == SPMySQLProxyConnected) {
+ port = [proxy localPort];
+ break;
+ }
+
+ // If the proxy connection attempt time has exceeded the timeout, break of of the loop.
+ if (_elapsedSecondsSinceAbsoluteTime(proxyWaitStart_t) > (timeout + 1)) {
+ [proxy disconnect];
+ break;
+ }
- // Allow events to process for 0.25s, sleeping to completion on early return
+ // Process events for a short time, allowing dialogs to be shown but waiting for
+ // the proxy. Capture how long this interface action took, standardising the
+ // overall time.
[[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
if (_elapsedSecondsSinceAbsoluteTime(loopIterationStart_t) < 0.25) {
- usleep(250000 - (useconds_t)(1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t)));
+ usleep((useconds_t)(250000 - (1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t))));
+ }
+
+ // Extend the connection timeout by any interface time
+ if ([proxy state] == SPMySQLProxyWaitingForAuth) {
+ proxyWaitStart_t += mach_absolute_time() - loopIterationStart_t;
}
}
- }
- // Request that the proxy re-establishes its connection
- [proxy connect];
+ // Having in theory performed the proxy connect, update state
+ previousProxyState = [proxy state];
+ proxyStateChangeNotificationsIgnored = NO;
+ }
- // Wait while the proxy connects
- proxyWaitStart_t = mach_absolute_time();
- while (1) {
- loopIterationStart_t = mach_absolute_time();
+ // Unlock the connection
+ [self _unlockConnection];
- // If the proxy has connected, record the new local port and break out of the loop
- if ([proxy state] == SPMySQLProxyConnected) {
- port = [proxy localPort];
- break;
- }
+ // If not using a proxy, or if the proxy successfully connected, trigger a connection
+ if (!proxy || [proxy state] == SPMySQLProxyConnected) {
+ [self _connect];
+ }
- // If the proxy connection attempt time has exceeded the timeout, break of of the loop.
- if (_elapsedSecondsSinceAbsoluteTime(proxyWaitStart_t) > (timeout + 1)) {
- [proxy disconnect];
- break;
+ // If the reconnection succeeded, restore the connection state as appropriate
+ if (state == SPMySQLConnected && ![[NSThread currentThread] isCancelled]) {
+ reconnectSucceeded = YES;
+ if (databaseToRestore) {
+ [self selectDatabase:databaseToRestore];
+ [databaseToRestore release], databaseToRestore = nil;
}
-
- // Process events for a short time, allowing dialogs to be shown but waiting for
- // the proxy. Capture how long this interface action took, standardising the
- // overall time.
- [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
- if (_elapsedSecondsSinceAbsoluteTime(loopIterationStart_t) < 0.25) {
- usleep((useconds_t)(250000 - (1000000 * _elapsedSecondsSinceAbsoluteTime(loopIterationStart_t))));
- }
-
- // Extend the connection timeout by any interface time
- if ([proxy state] == SPMySQLProxyWaitingForAuth) {
- proxyWaitStart_t += mach_absolute_time() - loopIterationStart_t;
+ if (encodingToRestore) {
+ [self setEncoding:encodingToRestore];
+ [self setEncodingUsesLatin1Transport:encodingUsesLatin1TransportToRestore];
+ [encodingToRestore release], encodingToRestore = nil;
}
}
+ // If the connection failed and the connection is permitted to retry,
+ // then retry the reconnection.
+ else if (canRetry && ![[NSThread currentThread] isCancelled]) {
- // Having in theory performed the proxy connect, update state
- previousProxyState = [proxy state];
- proxyStateChangeNotificationsIgnored = NO;
- }
-
- // Unlock the connection
- [self _unlockConnection];
-
- // If not using a proxy, or if the proxy successfully connected, trigger a connection
- if (!proxy || [proxy state] == SPMySQLProxyConnected) {
- [self _connect];
- }
+ // Default to attempting another reconnect
+ SPMySQLConnectionLostDecision connectionLostDecision = SPMySQLConnectionLostReconnect;
- // If the reconnection succeeded, restore the connection state as appropriate
- if (state == SPMySQLConnected && ![[NSThread currentThread] isCancelled]) {
- reconnectSucceeded = YES;
- if (databaseToRestore) {
- [self selectDatabase:databaseToRestore];
- [databaseToRestore release], databaseToRestore = nil;
- }
- if (encodingToRestore) {
- [self setEncoding:encodingToRestore];
- [self setEncodingUsesLatin1Transport:encodingUsesLatin1TransportToRestore];
- [encodingToRestore release], encodingToRestore = nil;
- }
- }
- // If the connection failed and the connection is permitted to retry,
- // then retry the reconnection.
- else if (canRetry && ![[NSThread currentThread] isCancelled]) {
+ // If the delegate supports the decision process, ask it how to proceed
+ if (delegateSupportsConnectionLost) {
+ connectionLostDecision = [self _delegateDecisionForLostConnection];
+ }
+ // Otherwise default to reconnect, but only a set number of times to prevent a runaway loop
+ else {
+ if (reconnectionRetryAttempts < 5) {
+ connectionLostDecision = SPMySQLConnectionLostReconnect;
+ } else {
+ connectionLostDecision = SPMySQLConnectionLostDisconnect;
+ }
+ reconnectionRetryAttempts++;
+ }
- // Default to attempting another reconnect
- SPMySQLConnectionLostDecision connectionLostDecision = SPMySQLConnectionLostReconnect;
+ switch (connectionLostDecision) {
+ case SPMySQLConnectionLostDisconnect:
+ [self _updateLastErrorMessage:NSLocalizedString(@"User triggered disconnection", @"User triggered disconnection")];
+ userTriggeredDisconnect = YES;
+ break;
- // If the delegate supports the decision process, ask it how to proceed
- if (delegateSupportsConnectionLost) {
- connectionLostDecision = [self _delegateDecisionForLostConnection];
- }
- // Otherwise default to reconnect, but only a set number of times to prevent a runaway loop
- else {
- if (reconnectionRetryAttempts < 5) {
- connectionLostDecision = SPMySQLConnectionLostReconnect;
- } else {
- connectionLostDecision = SPMySQLConnectionLostDisconnect;
+ // By default attempt a reconnect
+ default:
+ reconnectingThread = NULL;
+ reconnectSucceeded = [self _reconnectAllowingRetries:YES];
}
- reconnectionRetryAttempts++;
- }
-
- switch (connectionLostDecision) {
- case SPMySQLConnectionLostDisconnect:
- [self _updateLastErrorMessage:NSLocalizedString(@"User triggered disconnection", @"User triggered disconnection")];
- userTriggeredDisconnect = YES;
- break;
-
- // By default attempt a reconnect
- default:
- reconnectingThread = NULL;
- reconnectSucceeded = [self _reconnectAllowingRetries:YES];
}
}
reconnectingThread = NULL;
- [reconnectionPool release];
return reconnectSucceeded;
}
@@ -923,14 +919,10 @@ asm(".desc ___crashreporter_info__, 0x10");
*/
- (BOOL)_reconnectAfterBackgroundConnectionLoss
{
- NSAutoreleasePool *reconnectionPool = [[NSAutoreleasePool alloc] init];
-
if (![self _reconnectAllowingRetries:NO]) {
state = SPMySQLConnectionLostInBackground;
}
- [reconnectionPool release];
-
return (state == SPMySQLConnected);
}