aboutsummaryrefslogtreecommitdiffstats
path: root/Frameworks/MCPKit/MCPFoundationKit
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2010-03-16 02:04:50 +0000
committerrowanbeentje <rowan@beent.je>2010-03-16 02:04:50 +0000
commit332f6201ce607a6622fadfd3e6426e4571dc035f (patch)
tree4e86f4ac81a9b13487482a8ec95dd2dc273f71d3 /Frameworks/MCPKit/MCPFoundationKit
parent1bfe991970009b1e7011823a00e676271fc04055 (diff)
downloadsequelpro-332f6201ce607a6622fadfd3e6426e4571dc035f.tar.gz
sequelpro-332f6201ce607a6622fadfd3e6426e4571dc035f.tar.bz2
sequelpro-332f6201ce607a6622fadfd3e6426e4571dc035f.zip
- Make a number of changes to attempt to improve disconnection/quit crashes: prevent multiple disconnects, add more checks, cancel current queries, and add a tiny delay to allow mysql cleanup.
- Alter MCPStreamingResult to no longer return a retained instance, setting up correct result disposal on autorelease but changing callers to retain as soon as they receive. - Review and change a number of local variables shadowing/shielding other local or global variables.
Diffstat (limited to 'Frameworks/MCPKit/MCPFoundationKit')
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h1
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m20
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.h2
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m7
4 files changed, 22 insertions, 8 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h
index f04fb26e..8e5a60f9 100644
--- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h
+++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.h
@@ -82,6 +82,7 @@ static inline NSData* NSStringDataUsingLossyEncoding(NSString* self, NSInteger e
NSLock *queryLock; /* Anything that performs a mysql_net_read is not thread-safe: mysql queries, pings */
BOOL useKeepAlive;
+ BOOL isDisconnecting;
NSInteger connectionTimeout;
CGFloat keepAliveInterval;
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m
index f04fe226..607e1b8e 100644
--- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m
+++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m
@@ -106,6 +106,7 @@ static BOOL sTruncateLongFieldInLogs = YES;
queryCancelUsedReconnect = NO;
serverVersionString = nil;
mTimeZone = nil;
+ isDisconnecting = NO;
// Initialize ivar defaults
connectionTimeout = 10;
@@ -298,7 +299,7 @@ static BOOL sTruncateLongFieldInLogs = YES;
if (mConnected && newState == PROXY_STATE_IDLE && currentProxyState == PROXY_STATE_CONNECTED) {
currentProxyState = newState;
[connectionProxy setConnectionStateChangeSelector:nil delegate:nil];
- [self reconnect];
+ if (!isDisconnecting) [self reconnect];
return;
}
@@ -404,14 +405,22 @@ static BOOL sTruncateLongFieldInLogs = YES;
*/
- (void)disconnect
{
+ if (isDisconnecting) return;
+ isDisconnecting = YES;
+
[self stopKeepAliveTimer];
if (mConnected) {
+ [self cancelCurrentQuery];
+ mConnected = NO;
+
+ // Small pause for cleanup.
+ usleep(100000);
mysql_close(mConnection);
mConnection = NULL;
}
- mConnected = NO;
+ isDisconnecting = NO;
if (connectionProxy) {
[connectionProxy performSelectorOnMainThread:@selector(disconnect) withObject:nil waitUntilDone:YES];
@@ -457,6 +466,7 @@ static BOOL sTruncateLongFieldInLogs = YES;
}
mConnected = NO;
+ isDisconnecting = NO;
// If there is a tunnel, ensure it's disconnected and attempt to reconnect it in blocking fashion
if (connectionProxy) {
@@ -1290,7 +1300,6 @@ void performThreadedKeepAlive(void *ptr)
/**
* Takes a query string and returns an MCPStreamingResult representing the result of the query.
- * The returned MCPStreamingResult is retained and the client is responsible for releasing it.
* If no fields are present in the result, nil will be returned.
* Uses safe/fast mode, which may use more memory as results are downloaded.
*/
@@ -1301,7 +1310,6 @@ void performThreadedKeepAlive(void *ptr)
/**
* Takes a query string and returns an MCPStreamingResult representing the result of the query.
- * The returned MCPStreamingResult is retained and the client is responsible for releasing it.
* If no fields are present in the result, nil will be returned.
* Can be used in either fast/safe mode, where data is downloaded as fast as possible to avoid
* blocking the server, or in full streaming mode for lowest memory usage but potentially blocking
@@ -1316,7 +1324,6 @@ void performThreadedKeepAlive(void *ptr)
* Error checks connection extensively - if this method fails due to a connection error, it will ask how to
* proceed and loop depending on the status, not returning control until either the query has been executed
* and the result can be returned or the connection and document have been closed.
- * If using streamingResult, the caller is responsible for releasing the result set.
*/
- (id)queryString:(NSString *) query usingEncoding:(NSStringEncoding) encoding streamingResult:(NSInteger) streamResultType
{
@@ -1516,7 +1523,6 @@ void performThreadedKeepAlive(void *ptr)
(void)(*startKeepAliveTimerPtr)(self, startKeepAliveTimerSEL, YES);
if (!theResult) return nil;
- if (streamResultType != MCP_NO_STREAMING) return theResult;
return [theResult autorelease];
}
@@ -1618,7 +1624,7 @@ void performThreadedKeepAlive(void *ptr)
// Reset the connection
[self unlockConnection];
- [self reconnect];
+ if (!isDisconnecting) [self reconnect];
// Set queryCancelled again to handle requery cleanups, and return.
queryCancelled = YES;
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.h b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.h
index 2f5ec638..65ee6423 100644
--- a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.h
+++ b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.h
@@ -53,6 +53,8 @@ typedef struct SP_MYSQL_ROWS {
unsigned long freedRowCount;
pthread_mutex_t dataCreationLock;
pthread_mutex_t dataFreeLock;
+ IMP isConnectedPtr;
+ SEL isConnectedSEL;
}
- (id)initWithMySQLPtr:(MYSQL *)mySQLPtr encoding:(NSStringEncoding)theEncoding timeZone:(NSTimeZone *)theTimeZone connection:(MCPConnection *)theConnection;
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
index 624f132c..fd7d181b 100644
--- a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
+++ b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
@@ -95,6 +95,10 @@
mNumOfFields = 0;
}
+ // Obtain SEL references and pointer
+ isConnectedSEL = @selector(isConnected);
+ isConnectedPtr = [parentConnection methodForSelector:isConnectedSEL];
+
// If the result is opened in download-data-fast safe mode, set up the additional variables
// and threads required.
if (!fullyStreaming) {
@@ -127,6 +131,7 @@
*/
- (void) dealloc
{
+ [self cancelResultLoad];
if (!connectionUnlocked) [parentConnection unlockConnection];
if (!fullyStreaming) {
@@ -406,7 +411,7 @@
size_t sizeOfDataLengths = (size_t)(sizeof(unsigned long) * mNumOfFields);
// Loop through the rows until the end of the data is reached - indicated via a NULL
- while (theRow = mysql_fetch_row(mResult)) {
+ while ( (BOOL)(*isConnectedPtr)(parentConnection, isConnectedSEL) && (theRow = mysql_fetch_row(mResult))) {
// Retrieve the lengths of the returned data
fieldLengths = mysql_fetch_lengths(mResult);