From e1b881b8f893803c4949a69055c4e8106562327d Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 18 Apr 2017 00:33:14 +0200 Subject: Move some code to a place where it makes more sense to be (part of #2770) (This should not cause any behavioral changes) --- Source/SPCustomQuery.h | 1 - Source/SPCustomQuery.m | 11 +---------- Source/SPDataStorage.h | 7 +++++++ Source/SPDataStorage.m | 12 ++++++++++++ 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Source/SPCustomQuery.h b/Source/SPCustomQuery.h index e976f716..b63de32f 100644 --- a/Source/SPCustomQuery.h +++ b/Source/SPCustomQuery.h @@ -160,7 +160,6 @@ SPDataStorage *resultData; pthread_mutex_t resultDataLock; - NSCondition *resultLoadingCondition; NSInteger resultDataCount; NSArray *cqColumnDefinition; NSString *lastExecutedQuery; diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m index 591bcb12..38c593d1 100644 --- a/Source/SPCustomQuery.m +++ b/Source/SPCustomQuery.m @@ -993,11 +993,7 @@ // Set up the table updates timer and wait for it to notify this thread about completion [[self onMainThread] initQueryLoadTimer]; - [resultLoadingCondition lock]; - while (![resultData dataDownloaded]) { - [resultLoadingCondition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.05]]; - } - [resultLoadingCondition unlock]; + [resultData awaitDataDownloaded]; // If the final column autoresize wasn't performed, perform it if (queryLoadLastRowCount < 200) [[self onMainThread] autosizeColumns]; @@ -1500,10 +1496,7 @@ } if ([resultData dataDownloaded]) { - [resultLoadingCondition lock]; - [resultLoadingCondition signal]; [self clearQueryLoadTimer]; - [resultLoadingCondition unlock]; } // Check whether a table update is required, based on whether new rows are @@ -3787,7 +3780,6 @@ runPrimaryActionButtonAsSelection = nil; queryLoadTimer = nil; - resultLoadingCondition = [NSCondition new]; prefs = [NSUserDefaults standardUserDefaults]; @@ -4070,7 +4062,6 @@ [NSObject cancelPreviousPerformRequestsWithTarget:customQueryView]; [self clearQueryLoadTimer]; - SPClear(resultLoadingCondition); SPClear(usedQuery); SPClear(lastExecutedQuery); SPClear(resultData); diff --git a/Source/SPDataStorage.h b/Source/SPDataStorage.h index bb45f71b..23c7e124 100644 --- a/Source/SPDataStorage.h +++ b/Source/SPDataStorage.h @@ -44,6 +44,7 @@ SPMySQLStreamingResultStore *dataStorage; NSPointerArray *editedRows; BOOL *unloadedColumns; + NSCondition *dataDownloadedLock; NSUInteger numberOfColumns; NSUInteger editedRowCount; @@ -75,6 +76,12 @@ - (NSUInteger) columnCount; - (BOOL) dataDownloaded; +/** + * This method will block the caller until -dataDownloaded returns YES. + * Multiple parallel calls from different threads are possible. + */ +- (void) awaitDataDownloaded; + /* Delegate callback methods */ - (void)resultStoreDidFinishLoadingData:(SPMySQLStreamingResultStore *)resultStore; diff --git a/Source/SPDataStorage.m b/Source/SPDataStorage.m index fca33c0a..44c2dc9d 100644 --- a/Source/SPDataStorage.m +++ b/Source/SPDataStorage.m @@ -468,6 +468,13 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore } } +- (void) awaitDataDownloaded +{ + [dataDownloadedLock lock]; + while(![self dataDownloaded]) [dataDownloadedLock wait]; + [dataDownloadedLock unlock]; +} + #pragma mark - Delegate callback methods /** @@ -479,6 +486,9 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore [editedRows setCount:(NSUInteger)[resultStore numberOfRows]]; editedRowCount = [editedRows count]; } + [dataDownloadedLock lock]; + [dataDownloadedLock broadcast]; + [dataDownloadedLock unlock]; } /** @@ -492,6 +502,7 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore dataStorage = nil; editedRows = nil; unloadedColumns = NULL; + dataDownloadedLock = [NSCondition new]; numberOfColumns = 0; editedRowCount = 0; @@ -504,6 +515,7 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore @synchronized(self) { SPClear(dataStorage); SPClear(editedRows); + SPClear(dataDownloadedLock); if (unloadedColumns) { free(unloadedColumns), unloadedColumns = NULL; } -- cgit v1.2.3 From dfab0cd76c54ba3f78284a57c89a7585a6042a38 Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 18 Apr 2017 01:25:42 +0200 Subject: Remove a superfluous ivar and the unholy intermingling of UI and data code it has caused (part of #2770) --- Source/SPCustomQuery.h | 1 - Source/SPCustomQuery.m | 41 ++++++++++++++++++----------------------- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/Source/SPCustomQuery.h b/Source/SPCustomQuery.h index b63de32f..fe31be6d 100644 --- a/Source/SPCustomQuery.h +++ b/Source/SPCustomQuery.h @@ -160,7 +160,6 @@ SPDataStorage *resultData; pthread_mutex_t resultDataLock; - NSInteger resultDataCount; NSArray *cqColumnDefinition; NSString *lastExecutedQuery; NSInteger editedRow; diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m index 38c593d1..3cbd6a4d 100644 --- a/Source/SPCustomQuery.m +++ b/Source/SPCustomQuery.m @@ -61,6 +61,7 @@ #import "SPAppController.h" #import "SPBundleHTMLOutputController.h" #endif +#import "SPFunctions.h" #import #import @@ -884,7 +885,7 @@ (long)totalAffectedRows ]; } - if(resultDataCount) { + if([resultData count]) { // we were running a query that returns a result set (ie. SELECT). // TODO: mysql_query() returns as soon as the first result row is found (which might be pretty soon when using indexes / not doing aggregations) // and that makes our query time measurement pretty useless (see #264) @@ -905,7 +906,7 @@ #endif // If no results were returned, redraw the empty table and post notifications before returning. - if ( !resultDataCount ) { + if ( ![resultData count] ) { [customQueryView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES]; // Notify any listeners that the query has completed @@ -931,8 +932,6 @@ return; } - [[customQueryView onMainThread] reloadData]; - // Restore the result view origin if appropriate if (!NSEqualRects(selectionViewportToRestore, NSZeroRect)) { @@ -976,12 +975,12 @@ */ - (void)updateResultStore:(SPMySQLStreamingResultStore *)theResultStore { - - // Remove all items from the table - resultDataCount = 0; - [customQueryView performSelectorOnMainThread:@selector(noteNumberOfRowsChanged) withObject:nil waitUntilDone:YES]; pthread_mutex_lock(&resultDataLock); - [resultData removeAllRows]; + // Remove all items from the table + SPMainQSync(^{ + [resultData removeAllRows]; + [customQueryView noteNumberOfRowsChanged]; + }); // Add the new store [resultData setDataStorage:theResultStore updatingExisting:NO]; @@ -994,11 +993,8 @@ [[self onMainThread] initQueryLoadTimer]; [resultData awaitDataDownloaded]; - - // If the final column autoresize wasn't performed, perform it - if (queryLoadLastRowCount < 200) [[self onMainThread] autosizeColumns]; - - [customQueryView performSelectorOnMainThread:@selector(noteNumberOfRowsChanged) withObject:nil waitUntilDone:NO]; + + // Any further UI updates are the responsibility of the timer callback } /** @@ -1488,8 +1484,8 @@ */ - (void) queryLoadUpdate:(NSTimer *)theTimer { - resultDataCount = [resultData count]; - + NSUInteger resultDataCount = [resultData count]; + if (queryLoadTimerTicksSinceLastUpdate < queryLoadInterfaceUpdateInterval) { queryLoadTimerTicksSinceLastUpdate++; return; @@ -1501,7 +1497,7 @@ // Check whether a table update is required, based on whether new rows are // available to display. - if (resultDataCount == (NSInteger)queryLoadLastRowCount) { + if (resultDataCount == queryLoadLastRowCount) { return; } @@ -1548,7 +1544,7 @@ */ - (NSUInteger)currentResultRowCount { - return resultDataCount; + return [resultData count]; } /** @@ -2077,7 +2073,7 @@ */ - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView { - return (aTableView == customQueryView) ? (resultData == nil) ? 0 : resultDataCount : 0; + return (aTableView == customQueryView) ? (resultData == nil) ? 0 : [resultData count] : 0; } /** @@ -2102,7 +2098,7 @@ if (isWorking) { pthread_mutex_lock(&resultDataLock); - if (rowIndex < resultDataCount && columnIndex < [resultData columnCount]) { + if (SPIntS2U(rowIndex) < [resultData count] && columnIndex < [resultData columnCount]) { showCellAsGray = [resultData cellIsNullOrUnloadedAtRow:rowIndex column:columnIndex]; } else { showCellAsGray = YES; @@ -2403,7 +2399,7 @@ // cases. if (isWorking) { pthread_mutex_lock(&resultDataLock); - if (row < resultDataCount && (NSUInteger)[[aTableColumn identifier] integerValue] < [resultData columnCount]) { + if (SPIntS2U(row) < [resultData count] && (NSUInteger)[[aTableColumn identifier] integerValue] < [resultData columnCount]) { theValue = [[SPDataStorageObjectAtRowAndColumn(resultData, row, [[aTableColumn identifier] integerValue]) copy] autorelease]; } pthread_mutex_unlock(&resultDataLock); @@ -3769,7 +3765,6 @@ #endif // init tableView's data source - resultDataCount = 0; resultData = [[SPDataStorage alloc] init]; editedRow = -1; @@ -4022,7 +4017,7 @@ if (isWorking) { pthread_mutex_lock(&resultDataLock); - if (row < resultDataCount && column < [resultData columnCount]) { + if (SPIntS2U(row) < [resultData count] && column < [resultData columnCount]) { value = SPDataStoragePreviewAtRowAndColumn(resultData, row, column, 150); } -- cgit v1.2.3