Merge pull request #2376 from zhongwuzw/fix-race-condition
This commit is contained in:
commit
76215d7717
|
@ -18,7 +18,7 @@ typedef void(^SDExternalCompletionBlock)(UIImage * _Nullable image, NSError * _N
|
|||
|
||||
typedef void(^SDInternalCompletionBlock)(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL);
|
||||
|
||||
// A combined operation representing the cache and loader operation. You can it to cancel the load process.
|
||||
// A combined operation representing the cache and loader operation. You can use it to cancel the load process.
|
||||
@interface SDWebImageCombinedOperation : NSObject <SDWebImageOperation>
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
// These value are just used as incrementing counter, keep thread-safe using memory_order_relaxed for performance.
|
||||
atomic_ulong _skippedCount;
|
||||
atomic_ulong _finishedCount;
|
||||
atomic_ulong _totalCount;
|
||||
atomic_flag _isAllFinished;
|
||||
|
||||
unsigned long _totalCount;
|
||||
}
|
||||
|
||||
@property (nonatomic, copy, readwrite) NSArray<NSURL *> *urls;
|
||||
|
@ -78,6 +80,7 @@
|
|||
token->_skippedCount = 0;
|
||||
token->_finishedCount = 0;
|
||||
token->_totalCount = token.urls.count;
|
||||
atomic_flag_clear(&(token->_isAllFinished));
|
||||
token.operations = [NSPointerArray weakObjectsPointerArray];
|
||||
token.progressBlock = progressBlock;
|
||||
token.completionBlock = completionBlock;
|
||||
|
@ -103,10 +106,12 @@
|
|||
// Current operation finished
|
||||
[sself callProgressBlockForToken:token imageURL:imageURL];
|
||||
|
||||
if (atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed) + atomic_load_explicit(&(token->_skippedCount), memory_order_relaxed) >= atomic_load_explicit(&(token->_totalCount), memory_order_relaxed)) {
|
||||
if (atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed) == token->_totalCount) {
|
||||
// All finished
|
||||
[sself callCompletionBlockForToken:token];
|
||||
[sself removeRunningToken:token];
|
||||
if (!atomic_flag_test_and_set_explicit(&(token->_isAllFinished), memory_order_relaxed)) {
|
||||
[sself callCompletionBlockForToken:token];
|
||||
[sself removeRunningToken:token];
|
||||
}
|
||||
}
|
||||
}];
|
||||
@synchronized (token) {
|
||||
|
@ -134,7 +139,7 @@
|
|||
NSUInteger tokenFinishedCount = [self tokenFinishedCount];
|
||||
NSUInteger tokenTotalCount = [self tokenTotalCount];
|
||||
NSUInteger finishedCount = atomic_load_explicit(&(token->_finishedCount), memory_order_relaxed);
|
||||
NSUInteger totalCount = atomic_load_explicit(&(token->_totalCount), memory_order_relaxed);
|
||||
NSUInteger totalCount = token->_totalCount;
|
||||
dispatch_async(self.delegateQueue, ^{
|
||||
if (shouldCallDelegate) {
|
||||
[self.delegate imagePrefetcher:self didPrefetchURL:url finishedCount:tokenFinishedCount totalCount:tokenTotalCount];
|
||||
|
@ -169,7 +174,7 @@
|
|||
NSUInteger tokenTotalCount = 0;
|
||||
@synchronized (self.runningTokens) {
|
||||
for (SDWebImagePrefetchToken *token in self.runningTokens) {
|
||||
tokenTotalCount += atomic_load_explicit(&(token->_totalCount), memory_order_relaxed);
|
||||
tokenTotalCount += token->_totalCount;
|
||||
}
|
||||
}
|
||||
return tokenTotalCount;
|
||||
|
|
Loading…
Reference in New Issue