Skip to content

Commit 6b25d98

Browse files
authored
Merge pull request SDWebImage#3483 from dreampiggy/bugfix/atomic_logic_fix
Fix the atomic logic between downloader and operation again
2 parents 1f48e5a + 7cec27b commit 6b25d98

File tree

2 files changed

+17
-15
lines changed

2 files changed

+17
-15
lines changed

SDWebImage/Core/SDWebImageDownloader.m

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ - (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url
223223
return nil;
224224
}
225225

226-
SD_LOCK(_operationsLock);
227226
id downloadOperationCancelToken;
228227
// When different thumbnail size download with same url, we need to make sure each callback called with desired size
229228
id<SDWebImageCacheKeyFilter> cacheKeyFilter = context[SDWebImageContextCacheKeyFilter];
@@ -234,9 +233,17 @@ - (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url
234233
cacheKey = url.absoluteString;
235234
}
236235
SDImageCoderOptions *decodeOptions = SDGetDecodeOptionsFromContext(context, [self.class imageOptionsFromDownloaderOptions:options], cacheKey);
236+
SD_LOCK(_operationsLock);
237237
NSOperation<SDWebImageDownloaderOperation> *operation = [self.URLOperations objectForKey:url];
238238
// There is a case that the operation may be marked as finished or cancelled, but not been removed from `self.URLOperations`.
239-
BOOL shouldNotReuseOperation = !operation || operation.isFinished || operation.isCancelled || SDWebImageDownloaderOperationGetCompleted(operation);
239+
BOOL shouldNotReuseOperation;
240+
if (operation) {
241+
@synchronized (operation) {
242+
shouldNotReuseOperation = operation.isFinished || operation.isCancelled || SDWebImageDownloaderOperationGetCompleted(operation);
243+
}
244+
} else {
245+
shouldNotReuseOperation = YES;
246+
}
240247
if (shouldNotReuseOperation) {
241248
operation = [self createDownloaderOperationWithUrl:url options:options context:context];
242249
if (!operation) {
@@ -269,15 +276,6 @@ - (nullable SDWebImageDownloadToken *)downloadImageWithURL:(nullable NSURL *)url
269276
@synchronized (operation) {
270277
downloadOperationCancelToken = [operation addHandlersForProgress:progressBlock completed:completedBlock decodeOptions:decodeOptions];
271278
}
272-
if (!operation.isExecuting) {
273-
if (options & SDWebImageDownloaderHighPriority) {
274-
operation.queuePriority = NSOperationQueuePriorityHigh;
275-
} else if (options & SDWebImageDownloaderLowPriority) {
276-
operation.queuePriority = NSOperationQueuePriorityLow;
277-
} else {
278-
operation.queuePriority = NSOperationQueuePriorityNormal;
279-
}
280-
}
281279
}
282280
SD_UNLOCK(_operationsLock);
283281

@@ -518,8 +516,10 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didComp
518516
// Identify the operation that runs this task and pass it the delegate method
519517
NSOperation<SDWebImageDownloaderOperation> *dataOperation = [self operationWithTask:task];
520518
if (dataOperation) {
521-
// Mark the downloader operation `isCompleted = YES`, no longer re-use this operation when new request comes in
522-
SDWebImageDownloaderOperationSetCompleted(dataOperation, true);
519+
@synchronized (dataOperation) {
520+
// Mark the downloader operation `isCompleted = YES`, no longer re-use this operation when new request comes in
521+
SDWebImageDownloaderOperationSetCompleted(dataOperation, true);
522+
}
523523
}
524524
if ([dataOperation respondsToSelector:@selector(URLSession:task:didCompleteWithError:)]) {
525525
[dataOperation URLSession:session task:task didCompleteWithError:error];

SDWebImage/Core/SDWebImageDownloaderOperation.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,10 @@ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)data
477477
return;
478478
}
479479
// When cancelled or transfer finished (`didCompleteWithError`), cancel the progress callback, only completed block is called and enough
480-
if (self.isCancelled || SDWebImageDownloaderOperationGetCompleted(self)) {
481-
return;
480+
@synchronized (self) {
481+
if (self.isCancelled || SDWebImageDownloaderOperationGetCompleted(self)) {
482+
return;
483+
}
482484
}
483485
UIImage *image = SDImageLoaderDecodeProgressiveImageData(imageData, self.request.URL, NO, self, [[self class] imageOptionsFromDownloaderOptions:self.options], self.context);
484486
if (image) {

0 commit comments

Comments
 (0)