Merge pull request #3439 from dreampiggy/bugfix/thread_safe_callback

Fix the missing lock for callbackTokens which may cause thread-safe issue
This commit is contained in:
DreamPiggy 2022-11-11 15:30:36 +08:00 committed by GitHub
commit a97d502304
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 29 deletions

View File

@ -40,12 +40,13 @@
}
self.cancelled = YES;
dispatch_main_async_safe(^{
if (self.doneBlock) {
self.doneBlock(nil, nil, SDImageCacheTypeNone);
self.doneBlock = nil;
}
});
SDImageCacheQueryCompletionBlock doneBlock = self.doneBlock;
self.doneBlock = nil;
if (doneBlock) {
dispatch_main_async_safe(^{
doneBlock(nil, nil, SDImageCacheTypeNone);
});
}
}
}

View File

@ -158,11 +158,11 @@
[self.callbackTokens removeObjectIdenticalTo:token];
}
SDWebImageDownloaderCompletedBlock completedBlock = ((SDWebImageDownloaderOperationToken *)token).completedBlock;
dispatch_main_async_safe(^{
if (completedBlock) {
if (completedBlock) {
dispatch_main_async_safe(^{
completedBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorCancelled userInfo:@{NSLocalizedDescriptionKey : @"Operation cancelled by user during sending the request"}], YES);
}
});
});
}
}
return shouldCancel;
}
@ -244,7 +244,10 @@
self.coderQueue.qualityOfService = NSQualityOfServiceDefault;
}
[self.dataTask resume];
NSArray<SDWebImageDownloaderOperationToken *> *tokens = [self.callbackTokens copy];
NSArray<SDWebImageDownloaderOperationToken *> *tokens;
@synchronized (self) {
tokens = [self.callbackTokens copy];
}
for (SDWebImageDownloaderOperationToken *token in tokens) {
if (token.progressBlock) {
token.progressBlock(0, NSURLResponseUnknownLength, self.request.URL);
@ -694,11 +697,12 @@ didReceiveResponse:(NSURLResponse *)response
tokens = [self.callbackTokens copy];
}
for (SDWebImageDownloaderOperationToken *token in tokens) {
dispatch_main_async_safe(^{
if (token.completedBlock) {
token.completedBlock(image, imageData, error, finished);
}
});
SDWebImageDownloaderCompletedBlock completedBlock = token.completedBlock;
if (completedBlock) {
dispatch_main_async_safe(^{
completedBlock(image, imageData, error, finished);
});
}
}
}
@ -707,11 +711,12 @@ didReceiveResponse:(NSURLResponse *)response
imageData:(nullable NSData *)imageData
error:(nullable NSError *)error
finished:(BOOL)finished {
dispatch_main_async_safe(^{
if (token.completedBlock) {
token.completedBlock(image, imageData, error, finished);
}
});
SDWebImageDownloaderCompletedBlock completedBlock = token.completedBlock;
if (completedBlock) {
dispatch_main_async_safe(^{
completedBlock(image, imageData, error, finished);
});
}
}
@end

View File

@ -672,11 +672,11 @@ static id<SDImageLoader> _defaultImageLoader;
cacheType:(SDImageCacheType)cacheType
finished:(BOOL)finished
url:(nullable NSURL *)url {
dispatch_main_async_safe(^{
if (completionBlock) {
if (completionBlock) {
dispatch_main_async_safe(^{
completionBlock(image, data, error, cacheType, finished, url);
}
});
});
}
}
- (BOOL)shouldBlockFailedURLWithURL:(nonnull NSURL *)url

View File

@ -229,12 +229,12 @@ const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
#if SD_UIKIT || SD_MAC
[self sd_stopImageIndicator];
#endif
dispatch_main_async_safe(^{
if (completedBlock) {
if (completedBlock) {
dispatch_main_async_safe(^{
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey : @"Image url is nil"}];
completedBlock(nil, nil, error, SDImageCacheTypeNone, YES, url);
}
});
});
}
}
return operation;