Skip to content

Commit a97d502

Browse files
authored
Merge pull request SDWebImage#3439 from dreampiggy/bugfix/thread_safe_callback
Fix the missing lock for callbackTokens which may cause thread-safe issue
2 parents bc3f09c + 736f3f4 commit a97d502

File tree

4 files changed

+35
-29
lines changed

4 files changed

+35
-29
lines changed

SDWebImage/Core/SDImageCache.m

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,13 @@ - (void)cancel {
4040
}
4141
self.cancelled = YES;
4242

43-
dispatch_main_async_safe(^{
44-
if (self.doneBlock) {
45-
self.doneBlock(nil, nil, SDImageCacheTypeNone);
46-
self.doneBlock = nil;
47-
}
48-
});
43+
SDImageCacheQueryCompletionBlock doneBlock = self.doneBlock;
44+
self.doneBlock = nil;
45+
if (doneBlock) {
46+
dispatch_main_async_safe(^{
47+
doneBlock(nil, nil, SDImageCacheTypeNone);
48+
});
49+
}
4950
}
5051
}
5152

SDWebImage/Core/SDWebImageDownloaderOperation.m

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,11 @@ - (BOOL)cancel:(nullable id)token {
158158
[self.callbackTokens removeObjectIdenticalTo:token];
159159
}
160160
SDWebImageDownloaderCompletedBlock completedBlock = ((SDWebImageDownloaderOperationToken *)token).completedBlock;
161-
dispatch_main_async_safe(^{
162-
if (completedBlock) {
161+
if (completedBlock) {
162+
dispatch_main_async_safe(^{
163163
completedBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during sending the request"}], YES);
164-
}
165-
});
164+
});
165+
}
166166
}
167167
return shouldCancel;
168168
}
@@ -244,7 +244,10 @@ - (void)start {
244244
self.coderQueue.qualityOfService = NSQualityOfServiceDefault;
245245
}
246246
[self.dataTask resume];
247-
NSArray<SDWebImageDownloaderOperationToken *> *tokens = [self.callbackTokens copy];
247+
NSArray<SDWebImageDownloaderOperationToken *> *tokens;
248+
@synchronized (self) {
249+
tokens = [self.callbackTokens copy];
250+
}
248251
for (SDWebImageDownloaderOperationToken *token in tokens) {
249252
if (token.progressBlock) {
250253
token.progressBlock(0, NSURLResponseUnknownLength, self.request.URL);
@@ -694,11 +697,12 @@ - (void)callCompletionBlocksWithImage:(nullable UIImage *)image
694697
tokens = [self.callbackTokens copy];
695698
}
696699
for (SDWebImageDownloaderOperationToken *token in tokens) {
697-
dispatch_main_async_safe(^{
698-
if (token.completedBlock) {
699-
token.completedBlock(image, imageData, error, finished);
700-
}
701-
});
700+
SDWebImageDownloaderCompletedBlock completedBlock = token.completedBlock;
701+
if (completedBlock) {
702+
dispatch_main_async_safe(^{
703+
completedBlock(image, imageData, error, finished);
704+
});
705+
}
702706
}
703707
}
704708

@@ -707,11 +711,12 @@ - (void)callCompletionBlockWithToken:(nonnull SDWebImageDownloaderOperationToken
707711
imageData:(nullable NSData *)imageData
708712
error:(nullable NSError *)error
709713
finished:(BOOL)finished {
710-
dispatch_main_async_safe(^{
711-
if (token.completedBlock) {
712-
token.completedBlock(image, imageData, error, finished);
713-
}
714-
});
714+
SDWebImageDownloaderCompletedBlock completedBlock = token.completedBlock;
715+
if (completedBlock) {
716+
dispatch_main_async_safe(^{
717+
completedBlock(image, imageData, error, finished);
718+
});
719+
}
715720
}
716721

717722
@end

SDWebImage/Core/SDWebImageManager.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -672,11 +672,11 @@ - (void)callCompletionBlockForOperation:(nullable SDWebImageCombinedOperation*)o
672672
cacheType:(SDImageCacheType)cacheType
673673
finished:(BOOL)finished
674674
url:(nullable NSURL *)url {
675-
dispatch_main_async_safe(^{
676-
if (completionBlock) {
675+
if (completionBlock) {
676+
dispatch_main_async_safe(^{
677677
completionBlock(image, data, error, cacheType, finished, url);
678-
}
679-
});
678+
});
679+
}
680680
}
681681

682682
- (BOOL)shouldBlockFailedURLWithURL:(nonnull NSURL *)url

SDWebImage/Core/UIView+WebCache.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,12 +229,12 @@ - (void)setSd_imageProgress:(NSProgress *)sd_imageProgress {
229229
#if SD_UIKIT || SD_MAC
230230
[self sd_stopImageIndicator];
231231
#endif
232-
dispatch_main_async_safe(^{
233-
if (completedBlock) {
232+
if (completedBlock) {
233+
dispatch_main_async_safe(^{
234234
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey : @"Image url is nil"}];
235235
completedBlock(nil, nil, error, SDImageCacheTypeNone, YES, url);
236-
}
237-
});
236+
});
237+
}
238238
}
239239

240240
return operation;

0 commit comments

Comments
 (0)