Authored by Olivier Poitrey

Synchronize access to SDWebImageManager's mutable structures (fix #301)

@@ -83,7 +83,10 @@ @@ -83,7 +83,10 @@
83 return operation; 83 return operation;
84 } 84 }
85 85
  86 + @synchronized(self.runningOperations)
  87 + {
86 [self.runningOperations addObject:operation]; 88 [self.runningOperations addObject:operation];
  89 + }
87 NSString *key = [self cacheKeyForURL:url]; 90 NSString *key = [self cacheKeyForURL:url];
88 91
89 [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) 92 [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType)
@@ -93,8 +96,11 @@ @@ -93,8 +96,11 @@
93 if (image) 96 if (image)
94 { 97 {
95 completedBlock(image, nil, cacheType, YES); 98 completedBlock(image, nil, cacheType, YES);
  99 + @synchronized(self.runningOperations)
  100 + {
96 [self.runningOperations removeObject:operation]; 101 [self.runningOperations removeObject:operation];
97 } 102 }
  103 + }
98 else 104 else
99 { 105 {
100 SDWebImageDownloaderOptions downloaderOptions = 0; 106 SDWebImageDownloaderOptions downloaderOptions = 0;
@@ -108,9 +114,12 @@ @@ -108,9 +114,12 @@
108 { 114 {
109 if (error.code != NSURLErrorNotConnectedToInternet) 115 if (error.code != NSURLErrorNotConnectedToInternet)
110 { 116 {
  117 + @synchronized(self.failedURLs)
  118 + {
111 [self.failedURLs addObject:url]; 119 [self.failedURLs addObject:url];
112 } 120 }
113 } 121 }
  122 + }
114 else if (downloadedImage && finished) 123 else if (downloadedImage && finished)
115 { 124 {
116 const BOOL cacheOnDisk = !(options & SDWebImageCacheMemoryOnly); 125 const BOOL cacheOnDisk = !(options & SDWebImageCacheMemoryOnly);
@@ -119,8 +128,11 @@ @@ -119,8 +128,11 @@
119 128
120 if (finished) 129 if (finished)
121 { 130 {
  131 + @synchronized(self.runningOperations)
  132 + {
122 [self.runningOperations removeObject:operation]; 133 [self.runningOperations removeObject:operation];
123 } 134 }
  135 + }
124 }]; 136 }];
125 operation.cancelBlock = ^{[subOperation cancel];}; 137 operation.cancelBlock = ^{[subOperation cancel];};
126 } 138 }
@@ -131,8 +143,11 @@ @@ -131,8 +143,11 @@
131 143
132 - (void)cancelAll 144 - (void)cancelAll
133 { 145 {
  146 + @synchronized(self.runningOperations)
  147 + {
134 [self.runningOperations makeObjectsPerformSelector:@selector(cancel)]; 148 [self.runningOperations makeObjectsPerformSelector:@selector(cancel)];
135 [self.runningOperations removeAllObjects]; 149 [self.runningOperations removeAllObjects];
  150 + }
136 } 151 }
137 152
138 - (BOOL)isRunning 153 - (BOOL)isRunning