From 048306cb814ea2d77a6846acb8cc041d8802b69b Mon Sep 17 00:00:00 2001 From: Thomas Rasch <thomas@fook.de> Date: Wed, 27 Jun 2012 16:00:37 +0200 Subject: [PATCH] o Added proper locking to RMTileSourcesContainer --- MapView/Map/RMTileSourcesContainer.m | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/MapView/Map/RMTileSourcesContainer.m b/MapView/Map/RMTileSourcesContainer.m index 553f425..b4f376d 100644 --- a/MapView/Map/RMTileSourcesContainer.m +++ b/MapView/Map/RMTileSourcesContainer.m @@ -31,6 +31,7 @@ @implementation RMTileSourcesContainer { NSMutableArray *_tileSources; + NSRecursiveLock *_tileSourcesLock; RMProjection *_projection; RMFractalTileProjection *_mercatorToTileProjection; @@ -47,6 +48,7 @@ return nil; _tileSources = [NSMutableArray new]; + _tileSourcesLock = [NSRecursiveLock new]; _projection = nil; _mercatorToTileProjection = nil; @@ -66,6 +68,7 @@ - (void)dealloc { [_tileSources release]; _tileSources = nil; + [_tileSourcesLock release]; _tileSourcesLock = nil; [_projection release]; _projection = nil; [_mercatorToTileProjection release]; _mercatorToTileProjection = nil; [super dealloc]; @@ -75,13 +78,27 @@ - (NSArray *)tileSources { - return [[_tileSources copy] autorelease]; + NSArray *tileSources = nil; + + [_tileSourcesLock lock]; + tileSources = [_tileSources copy]; + [_tileSourcesLock unlock]; + + return [tileSources autorelease]; } - (BOOL)setTileSource:(id <RMTileSource>)tileSource { + BOOL result; + + [_tileSourcesLock lock]; + [self removeAllTileSources]; - return [self addTileSource:tileSource]; + result = [self addTileSource:tileSource]; + + [_tileSourcesLock unlock]; + + return result; } - (BOOL)addTileSource:(id <RMTileSource>)tileSource @@ -91,6 +108,8 @@ - (BOOL)addTileSource:(id<RMTileSource>)tileSource atIndex:(NSUInteger)index { + [_tileSourcesLock lock]; + RMProjection *newProjection = [tileSource projection]; RMFractalTileProjection *newFractalTileProjection = [tileSource mercatorToTileProjection]; @@ -101,12 +120,15 @@ else if (_projection != newProjection) { NSLog(@"The tilesource '%@' has a different projection than the tilesource container", [tileSource shortName]); + [_tileSourcesLock unlock]; return NO; } if ( ! _mercatorToTileProjection) _mercatorToTileProjection = [newFractalTileProjection retain]; + // FIXME: This should be the min and max values of all tile sources, so that individual tilesources + // could have a smaller zoom level range _minZoom = MAX(_minZoom, [tileSource minZoom]); _maxZoom = MIN(_maxZoom, [tileSource maxZoom]); @@ -117,6 +139,7 @@ else if (_tileSideLength != [tileSource tileSideLength]) { NSLog(@"The tilesource '%@' has a different tile side length than the tilesource container", [tileSource shortName]); + [_tileSourcesLock unlock]; return NO; } @@ -137,6 +160,8 @@ else [_tileSources insertObject:tileSource atIndex:index]; + [_tileSourcesLock unlock]; + RMLog(@"Added the tilesource '%@' to the container", [tileSource shortName]); return YES; @@ -145,26 +170,38 @@ - (void)removeTileSource:(id <RMTileSource>)tileSource { [tileSource cancelAllDownloads]; - [_tileSources removeObject:tileSource]; + + [_tileSourcesLock lock]; RMLog(@"Removed the tilesource '%@' from the container", [tileSource shortName]); + [_tileSources removeObject:tileSource]; + if ([_tileSources count] == 0) { [self removeAllTileSources]; // cleanup } + + [_tileSourcesLock unlock]; } - (void)removeTileSourceAtIndex:(NSUInteger)index { + [_tileSourcesLock lock]; + if (index >= [_tileSources count]) + { + [_tileSourcesLock unlock]; return; + } id <RMTileSource> tileSource = [_tileSources objectAtIndex:index]; [tileSource cancelAllDownloads]; [_tileSources removeObject:tileSource]; RMLog(@"Removed the tilesource '%@' from the container", [tileSource shortName]); + + [_tileSourcesLock unlock]; } - (void)moveTileSourceAtIndex:(NSUInteger)fromIndex toIndex:(NSUInteger)toIndex @@ -172,8 +209,13 @@ if (fromIndex == toIndex) return; + [_tileSourcesLock lock]; + if (fromIndex >= [_tileSources count]) + { + [_tileSourcesLock unlock]; return; + } id tileSource = [[_tileSources objectAtIndex:fromIndex] retain]; [_tileSources removeObjectAtIndex:fromIndex]; @@ -184,10 +226,14 @@ [_tileSources insertObject:tileSource atIndex:toIndex]; [tileSource autorelease]; + + [_tileSourcesLock unlock]; } - (void)removeAllTileSources { + [_tileSourcesLock lock]; + [self cancelAllDownloads]; [_tileSources removeAllObjects]; @@ -205,12 +251,18 @@ _maxZoom = FLT_MAX; _tileSideLength = 0; } + + [_tileSourcesLock unlock]; } - (void)cancelAllDownloads { + [_tileSourcesLock lock]; + for (id <RMTileSource>tileSource in _tileSources) [tileSource cancelAllDownloads]; + + [_tileSourcesLock unlock]; } - (RMFractalTileProjection *)mercatorToTileProjection @@ -245,8 +297,12 @@ - (void)didReceiveMemoryWarning { + [_tileSourcesLock lock]; + for (id <RMTileSource>tileSource in _tileSources) [tileSource didReceiveMemoryWarning]; + + [_tileSourcesLock unlock]; } @end -- libgit2 0.24.0