aboutsummaryrefslogtreecommitdiffstats
path: root/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
diff options
context:
space:
mode:
authorjakob <jakob@eggerapps.at>2010-04-16 17:18:54 +0000
committerjakob <jakob@eggerapps.at>2010-04-16 17:18:54 +0000
commitf5f15a660b5663865347e2b2b162fba7ad86566f (patch)
tree5c8f1093381e02563f4b816c96a6848bf9efac3d /Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
parent4c7dbcd724e9ac6fbd5943f147b15472833dceeb (diff)
downloadsequelpro-f5f15a660b5663865347e2b2b162fba7ad86566f.tar.gz
sequelpro-f5f15a660b5663865347e2b2b162fba7ad86566f.tar.bz2
sequelpro-f5f15a660b5663865347e2b2b162fba7ad86566f.zip
- changed the query locking mechanism for MCPConnection to be more thread safe. From now on, always use [self lockConnection] rather than [queryLock lock], independent of what thread you are running on
- A warning is written to the console when the connection is unlocked multiple times (to identify potential race conditions) - modified MCPStreamingResult to ensure it only closes the connection once - added a check to prevent arrow key navigation past the last row
Diffstat (limited to 'Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m')
-rw-r--r--Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m44
1 files changed, 32 insertions, 12 deletions
diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
index f6371b03..60917380 100644
--- a/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
+++ b/Frameworks/MCPKit/MCPFoundationKit/MCPStreamingResult.m
@@ -85,7 +85,9 @@
[mNames release];
mNames = nil;
}
-
+
+
+
mResult = mysql_use_result(mySQLPtr);
if (mResult) {
@@ -98,7 +100,7 @@
// 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) {
@@ -131,9 +133,14 @@
*/
- (void) dealloc
{
- [self cancelResultLoad];
- if (!connectionUnlocked) [parentConnection unlockConnection];
-
+ [self cancelResultLoad]; //this should close the connection if it is still open
+
+ if (!connectionUnlocked) {
+ //this should NEVER happen
+ NSLog(@"MCPStreamingResult: The connection has not been unlocked.");
+ [parentConnection unlockConnection];
+ }
+
if (!fullyStreaming) {
pthread_mutex_destroy(&dataFreeLock);
pthread_mutex_destroy(&dataCreationLock);
@@ -162,8 +169,14 @@
if (fullyStreaming) {
theRow = mysql_fetch_row(mResult);
- // If no data was returned, we're at the end of the result set - return nil.
- if (theRow == NULL) return nil;
+ // If no data was returned, we're at the end of the result set - unlock the connection and return nil
+ if (theRow == NULL) {
+ if (!connectionUnlocked) {
+ [parentConnection unlockConnection];
+ connectionUnlocked = YES;
+ }
+ return nil;
+ }
// Retrieve the lengths of the returned data
fieldLengths = mysql_fetch_lengths(mResult);
@@ -333,6 +346,7 @@
/*
* Ensure the result set is fully processed and freed without any processing
+ * This method ensures that the connection is unlocked.
*/
- (void) cancelResultLoad
{
@@ -345,7 +359,13 @@
theRow = mysql_fetch_row(mResult);
// If no data was returned, we're at the end of the result set - return.
- if (theRow == NULL) return;
+ if (theRow == NULL) {
+ if (!connectionUnlocked) {
+ [parentConnection unlockConnection];
+ connectionUnlocked = YES;
+ }
+ return;
+ }
}
// If in cached-streaming/fast download mode, loop until all data is fetched and freed
@@ -361,8 +381,8 @@
// once all memory has been freed
if (processedRowCount == downloadedRowCount) {
while (!dataFreed) usleep(1000);
- [parentConnection unlockConnection];
- connectionUnlocked = YES;
+ // we don't need to unlock the connection because
+ // the data loading thread already did that
return;
}
processedRowCount++;
@@ -459,8 +479,8 @@
}
// Unlock the parent connection now data has been retrieved
- connectionUnlocked = YES;
- [parentConnection unlockConnection];
+ [parentConnection unlockConnection];
+ connectionUnlocked = YES;
dataDownloaded = YES;
[downloadPool drain];