Use non-recursive lock for runningOperations in SDWebImageManager

This commit is contained in:
Lizhen Hu 2018-05-28 23:10:40 +08:00
parent a6e3907f26
commit 7dc38751e9
1 changed files with 12 additions and 22 deletions

View File

@ -30,12 +30,11 @@
@property (strong, nonatomic, nonnull) NSMutableSet<NSURL *> *failedURLs; @property (strong, nonatomic, nonnull) NSMutableSet<NSURL *> *failedURLs;
@property (strong, nonatomic, nonnull) dispatch_semaphore_t failedURLsLock; // a lock to keep the access to `failedURLs` thread-safe @property (strong, nonatomic, nonnull) dispatch_semaphore_t failedURLsLock; // a lock to keep the access to `failedURLs` thread-safe
@property (strong, nonatomic, nonnull) NSMutableArray<SDWebImageCombinedOperation *> *runningOperations; @property (strong, nonatomic, nonnull) NSMutableArray<SDWebImageCombinedOperation *> *runningOperations;
@property (strong, nonatomic, nonnull) dispatch_semaphore_t runningOperationsLock; // a lock to keep the access to `runningOperations` thread-safe
@end @end
@implementation SDWebImageManager { @implementation SDWebImageManager
pthread_mutex_t _runningOperationsLock; // a lock to keep the access to `runningOperations` thread-safe
}
+ (nonnull instancetype)sharedManager { + (nonnull instancetype)sharedManager {
static dispatch_once_t once; static dispatch_once_t once;
@ -46,10 +45,6 @@
return instance; return instance;
} }
- (void)dealloc {
pthread_mutex_destroy(&_runningOperationsLock);
}
- (nonnull instancetype)init { - (nonnull instancetype)init {
SDImageCache *cache = [SDImageCache sharedImageCache]; SDImageCache *cache = [SDImageCache sharedImageCache];
SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader]; SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
@ -63,11 +58,7 @@
_failedURLs = [NSMutableSet new]; _failedURLs = [NSMutableSet new];
_failedURLsLock = dispatch_semaphore_create(1); _failedURLsLock = dispatch_semaphore_create(1);
_runningOperations = [NSMutableArray new]; _runningOperations = [NSMutableArray new];
_runningOperationsLock = dispatch_semaphore_create(1);
pthread_mutexattr_t attribute;
pthread_mutexattr_init(&attribute);
pthread_mutexattr_settype(&attribute, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&_runningOperationsLock, &attribute);
} }
return self; return self;
} }
@ -157,9 +148,9 @@
return operation; return operation;
} }
pthread_mutex_lock(&_runningOperationsLock); LOCK(self.runningOperationsLock);
[self.runningOperations addObject:operation]; [self.runningOperations addObject:operation];
pthread_mutex_unlock(&_runningOperationsLock); UNLOCK(self.runningOperationsLock);
NSString *key = [self cacheKeyForURL:url]; NSString *key = [self cacheKeyForURL:url];
SDImageCacheOptions cacheOptions = 0; SDImageCacheOptions cacheOptions = 0;
@ -309,27 +300,26 @@
} }
- (void)cancelAll { - (void)cancelAll {
pthread_mutex_lock(&_runningOperationsLock); LOCK(self.runningOperationsLock);
NSArray<SDWebImageCombinedOperation *> *copiedOperations = [self.runningOperations copy]; NSArray<SDWebImageCombinedOperation *> *copiedOperations = [self.runningOperations copy];
[copiedOperations makeObjectsPerformSelector:@selector(cancel)]; UNLOCK(self.runningOperationsLock);
[self.runningOperations removeObjectsInArray:copiedOperations]; [copiedOperations makeObjectsPerformSelector:@selector(cancel)]; // This will call `safelyRemoveOperationFromRunning:` and remove from the array
pthread_mutex_unlock(&_runningOperationsLock);
} }
- (BOOL)isRunning { - (BOOL)isRunning {
BOOL isRunning = NO; BOOL isRunning = NO;
pthread_mutex_lock(&_runningOperationsLock); LOCK(self.runningOperationsLock);
isRunning = (self.runningOperations.count > 0); isRunning = (self.runningOperations.count > 0);
pthread_mutex_unlock(&_runningOperationsLock); UNLOCK(self.runningOperationsLock);
return isRunning; return isRunning;
} }
- (void)safelyRemoveOperationFromRunning:(nullable SDWebImageCombinedOperation*)operation { - (void)safelyRemoveOperationFromRunning:(nullable SDWebImageCombinedOperation*)operation {
pthread_mutex_lock(&_runningOperationsLock); LOCK(self.runningOperationsLock);
if (operation) { if (operation) {
[self.runningOperations removeObject:operation]; [self.runningOperations removeObject:operation];
} }
pthread_mutex_unlock(&_runningOperationsLock); UNLOCK(self.runningOperationsLock);
} }
- (void)callCompletionBlockForOperation:(nullable SDWebImageCombinedOperation*)operation - (void)callCompletionBlockForOperation:(nullable SDWebImageCombinedOperation*)operation