Renaming the `LOCK`, `UNLOCK` with SD prefix to avoid overriding user-defined macro. Remove `LOCKBLOCK` with paired macro instead to make it easy to debug

This commit is contained in:
DreamPiggy 2018-09-17 17:11:15 +08:00
parent a8c3fb84bb
commit 1ec61ad567
9 changed files with 105 additions and 111 deletions

View File

@ -104,9 +104,9 @@ static NSArray *SDBundlePreferredScales() {
}
- (void)didReceiveMemoryWarning:(NSNotification *)notification {
LOCKBLOCK({
[self.imageTable removeAllObjects];
});
SD_LOCK(_lock);
[self.imageTable removeAllObjects];
SD_UNLOCK(_lock);
}
- (NSString *)getPathForName:(NSString *)name bundle:(NSBundle *)bundle preferredScale:(CGFloat *)scale {
@ -174,18 +174,18 @@ static NSArray *SDBundlePreferredScales() {
- (UIImage *)imageForName:(NSString *)name {
NSParameterAssert(name);
UIImage *image;
LOCKBLOCK({
image = [self.imageTable objectForKey:name];
});
SD_LOCK(_lock);
image = [self.imageTable objectForKey:name];
SD_UNLOCK(_lock);
return image;
}
- (void)storeImage:(UIImage *)image forName:(NSString *)name {
NSParameterAssert(image);
NSParameterAssert(name);
LOCKBLOCK({
[self.imageTable setObject:image forKey:name];
});
SD_LOCK(_lock);
[self.imageTable setObject:image forKey:name];
SD_UNLOCK(_lock);
}
@end

View File

@ -238,10 +238,10 @@ static NSUInteger SDDeviceFreeMemory() {
self.animatedImageScale = 1;
[_fetchQueue cancelAllOperations];
_fetchQueue = nil;
LOCKBLOCK({
[_frameBuffer removeAllObjects];
_frameBuffer = nil;
});
SD_LOCK(self.lock);
[_frameBuffer removeAllObjects];
_frameBuffer = nil;
SD_UNLOCK(self.lock);
}
- (void)resetProgressiveImage
@ -299,9 +299,9 @@ static NSUInteger SDDeviceFreeMemory() {
self.animatedImageScale = image.scale;
if (!self.isProgressive) {
self.currentFrame = image;
LOCKBLOCK({
self.frameBuffer[@(self.currentFrameIndex)] = self.currentFrame;
});
SD_LOCK(self.lock);
self.frameBuffer[@(self.currentFrameIndex)] = self.currentFrame;
SD_UNLOCK(self.lock);
}
// Ensure disabled highlighting; it's not supported (see `-setHighlighted:`).
@ -420,15 +420,15 @@ static NSUInteger SDDeviceFreeMemory() {
[_fetchQueue cancelAllOperations];
[_fetchQueue addOperationWithBlock:^{
NSNumber *currentFrameIndex = @(self.currentFrameIndex);
LOCKBLOCK({
NSArray *keys = self.frameBuffer.allKeys;
// only keep the next frame for later rendering
for (NSNumber * key in keys) {
if (![key isEqualToNumber:currentFrameIndex]) {
[self.frameBuffer removeObjectForKey:key];
}
SD_LOCK(self.lock);
NSArray *keys = self.frameBuffer.allKeys;
// only keep the next frame for later rendering
for (NSNumber * key in keys) {
if (![key isEqualToNumber:currentFrameIndex]) {
[self.frameBuffer removeObjectForKey:key];
}
});
}
SD_UNLOCK(self.lock);
}];
}
@ -690,22 +690,22 @@ static NSUInteger SDDeviceFreeMemory() {
// Update the current frame
UIImage *currentFrame;
UIImage *fetchFrame;
LOCKBLOCK({
currentFrame = self.frameBuffer[@(currentFrameIndex)];
fetchFrame = currentFrame ? self.frameBuffer[@(nextFrameIndex)] : nil;
});
SD_LOCK(self.lock);
currentFrame = self.frameBuffer[@(currentFrameIndex)];
fetchFrame = currentFrame ? self.frameBuffer[@(nextFrameIndex)] : nil;
SD_UNLOCK(self.lock);
BOOL bufferFull = NO;
if (currentFrame) {
LOCKBLOCK({
// Remove the frame buffer if need
if (self.frameBuffer.count > self.maxBufferCount) {
self.frameBuffer[@(currentFrameIndex)] = nil;
}
// Check whether we can stop fetch
if (self.frameBuffer.count == totalFrameCount) {
bufferFull = YES;
}
});
SD_LOCK(self.lock);
// Remove the frame buffer if need
if (self.frameBuffer.count > self.maxBufferCount) {
self.frameBuffer[@(currentFrameIndex)] = nil;
}
// Check whether we can stop fetch
if (self.frameBuffer.count == totalFrameCount) {
bufferFull = YES;
}
SD_UNLOCK(self.lock);
self.currentFrame = currentFrame;
self.currentFrameIndex = nextFrameIndex;
self.bufferMiss = NO;
@ -720,9 +720,9 @@ static NSUInteger SDDeviceFreeMemory() {
if (self.isProgressive) {
// Recovery the current frame index and removed frame buffer (See above)
self.currentFrameIndex = currentFrameIndex;
LOCKBLOCK({
self.frameBuffer[@(currentFrameIndex)] = self.currentFrame;
});
SD_LOCK(self.lock);
self.frameBuffer[@(currentFrameIndex)] = self.currentFrame;
SD_UNLOCK(self.lock);
[self stopAnimating];
return;
}
@ -751,9 +751,9 @@ static NSUInteger SDDeviceFreeMemory() {
UIImage<SDAnimatedImage> *animatedImage = self.animatedImage;
NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
UIImage *frame = [animatedImage animatedImageFrameAtIndex:fetchFrameIndex];
LOCKBLOCK({
self.frameBuffer[@(fetchFrameIndex)] = frame;
});
SD_LOCK(self.lock);
self.frameBuffer[@(fetchFrameIndex)] = frame;
SD_UNLOCK(self.lock);
}];
[self.fetchQueue addOperation:operation];
}

View File

@ -44,32 +44,32 @@
if (![coder conformsToProtocol:@protocol(SDImageCoder)]) {
return;
}
LOCK(self.codersLock);
SD_LOCK(self.codersLock);
NSMutableArray<id<SDImageCoder>> *mutableCoders = [self.coders mutableCopy];
if (!mutableCoders) {
mutableCoders = [NSMutableArray array];
}
[mutableCoders addObject:coder];
self.coders = [mutableCoders copy];
UNLOCK(self.codersLock);
SD_UNLOCK(self.codersLock);
}
- (void)removeCoder:(nonnull id<SDImageCoder>)coder {
if (![coder conformsToProtocol:@protocol(SDImageCoder)]) {
return;
}
LOCK(self.codersLock);
SD_LOCK(self.codersLock);
NSMutableArray<id<SDImageCoder>> *mutableCoders = [self.coders mutableCopy];
[mutableCoders removeObject:coder];
self.coders = [mutableCoders copy];
UNLOCK(self.codersLock);
SD_UNLOCK(self.codersLock);
}
#pragma mark - SDImageCoder
- (BOOL)canDecodeFromData:(NSData *)data {
LOCK(self.codersLock);
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders;
UNLOCK(self.codersLock);
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canDecodeFromData:data]) {
return YES;
@ -79,9 +79,9 @@
}
- (BOOL)canEncodeToFormat:(SDImageFormat)format {
LOCK(self.codersLock);
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders;
UNLOCK(self.codersLock);
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canEncodeToFormat:format]) {
return YES;
@ -95,9 +95,9 @@
return nil;
}
UIImage *image;
LOCK(self.codersLock);
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders;
UNLOCK(self.codersLock);
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canDecodeFromData:data]) {
image = [coder decodedImageWithData:data options:options];
@ -112,9 +112,9 @@
if (!image) {
return nil;
}
LOCK(self.codersLock);
SD_LOCK(self.codersLock);
NSArray<id<SDImageCoder>> *coders = self.coders;
UNLOCK(self.codersLock);
SD_UNLOCK(self.codersLock);
for (id<SDImageCoder> coder in coders.reverseObjectEnumerator) {
if ([coder canEncodeToFormat:format]) {
return [coder encodedDataWithImage:image format:format options:nil];

View File

@ -42,33 +42,33 @@
if (![loader conformsToProtocol:@protocol(SDImageLoader)]) {
return;
}
LOCK(self.loadersLock);
SD_LOCK(self.loadersLock);
NSMutableArray<id<SDImageLoader>> *mutableLoaders = [self.loaders mutableCopy];
if (!mutableLoaders) {
mutableLoaders = [NSMutableArray array];
}
[mutableLoaders addObject:loader];
self.loaders = [mutableLoaders copy];
UNLOCK(self.loadersLock);
SD_UNLOCK(self.loadersLock);
}
- (void)removeLoader:(id<SDImageLoader>)loader {
if (![loader conformsToProtocol:@protocol(SDImageLoader)]) {
return;
}
LOCK(self.loadersLock);
SD_LOCK(self.loadersLock);
NSMutableArray<id<SDImageLoader>> *mutableLoaders = [self.loaders mutableCopy];
[mutableLoaders removeObject:loader];
self.loaders = [mutableLoaders copy];
UNLOCK(self.loadersLock);
SD_UNLOCK(self.loadersLock);
}
#pragma mark - SDImageLoader
- (BOOL)canLoadWithURL:(nullable NSURL *)url {
LOCK(self.loadersLock);
SD_LOCK(self.loadersLock);
NSArray<id<SDImageLoader>> *loaders = self.loaders;
UNLOCK(self.loadersLock);
SD_UNLOCK(self.loadersLock);
for (id<SDImageLoader> loader in loaders.reverseObjectEnumerator) {
if ([loader canLoadWithURL:url]) {
return YES;
@ -81,9 +81,9 @@
if (!url) {
return nil;
}
LOCK(self.loadersLock);
SD_LOCK(self.loadersLock);
NSArray<id<SDImageLoader>> *loaders = self.loaders;
UNLOCK(self.loadersLock);
SD_UNLOCK(self.loadersLock);
for (id<SDImageLoader> loader in loaders.reverseObjectEnumerator) {
if ([loader canLoadWithURL:url]) {
return [loader loadImageWithURL:url options:options context:context progress:progressBlock completed:completedBlock];

View File

@ -89,9 +89,9 @@ static void * SDMemoryCacheContext = &SDMemoryCacheContext;
}
if (key && obj) {
// Store weak cache
LOCK(self.weakCacheLock);
SD_LOCK(self.weakCacheLock);
[self.weakCache setObject:obj forKey:key];
UNLOCK(self.weakCacheLock);
SD_UNLOCK(self.weakCacheLock);
}
}
@ -102,9 +102,9 @@ static void * SDMemoryCacheContext = &SDMemoryCacheContext;
}
if (key && !obj) {
// Check weak cache
LOCK(self.weakCacheLock);
SD_LOCK(self.weakCacheLock);
obj = [self.weakCache objectForKey:key];
UNLOCK(self.weakCacheLock);
SD_UNLOCK(self.weakCacheLock);
if (obj) {
// Sync cache
NSUInteger cost = 0;
@ -124,9 +124,9 @@ static void * SDMemoryCacheContext = &SDMemoryCacheContext;
}
if (key) {
// Remove weak cache
LOCK(self.weakCacheLock);
SD_LOCK(self.weakCacheLock);
[self.weakCache removeObjectForKey:key];
UNLOCK(self.weakCacheLock);
SD_UNLOCK(self.weakCacheLock);
}
}
@ -136,9 +136,9 @@ static void * SDMemoryCacheContext = &SDMemoryCacheContext;
return;
}
// Manually remove should also remove weak cache
LOCK(self.weakCacheLock);
SD_LOCK(self.weakCacheLock);
[self.weakCache removeAllObjects];
UNLOCK(self.weakCacheLock);
SD_UNLOCK(self.weakCacheLock);
}
#endif

View File

@ -94,16 +94,10 @@
}
#endif
#ifndef LOCK
#define LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#ifndef SD_LOCK
#define SD_LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#endif
#ifndef UNLOCK
#define UNLOCK(lock) dispatch_semaphore_signal(lock);
#endif
#ifndef LOCKBLOCK
#define LOCKBLOCK(...) dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER); \
__VA_ARGS__; \
dispatch_semaphore_signal(self->_lock);
#ifndef SD_UNLOCK
#define SD_UNLOCK(lock) dispatch_semaphore_signal(lock);
#endif

View File

@ -184,13 +184,13 @@ static void * SDWebImageDownloaderContext = &SDWebImageDownloaderContext;
return nil;
}
LOCK(self.operationsLock);
SD_LOCK(self.operationsLock);
NSOperation<SDWebImageDownloaderOperation> *operation = [self.URLOperations objectForKey:url];
if (!operation || operation.isFinished) {
// There is a case that the operation may be marked as finished, but not been removed from `self.URLOperations`.
operation = [self createDownloaderOperationWithUrl:url options:options context:context];
if (!operation) {
UNLOCK(self.operationsLock);
SD_UNLOCK(self.operationsLock);
if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidDownloadOperation userInfo:@{NSLocalizedDescriptionKey : @"Downloader operation is nil"}];
completedBlock(nil, nil, error, YES);
@ -203,16 +203,16 @@ static void * SDWebImageDownloaderContext = &SDWebImageDownloaderContext;
if (!sself) {
return;
}
LOCK(sself.operationsLock);
SD_LOCK(sself.operationsLock);
[sself.URLOperations removeObjectForKey:url];
UNLOCK(sself.operationsLock);
SD_UNLOCK(sself.operationsLock);
};
self.URLOperations[url] = operation;
// Add operation to operation queue only after all configuration done according to Apple's doc.
// `addOperation:` does not synchronously execute the `operation.completionBlock` so this will not cause deadlock.
[self.downloadQueue addOperation:operation];
}
UNLOCK(self.operationsLock);
SD_UNLOCK(self.operationsLock);
id downloadOperationCancelToken = [operation addHandlersForProgress:progressBlock completed:completedBlock];
@ -300,7 +300,7 @@ static void * SDWebImageDownloaderContext = &SDWebImageDownloaderContext;
if (!url) {
return;
}
LOCK(self.operationsLock);
SD_LOCK(self.operationsLock);
NSOperation<SDWebImageDownloaderOperation> *operation = [self.URLOperations objectForKey:url];
if (operation) {
BOOL canceled = [operation cancel:token.downloadOperationCancelToken];
@ -308,7 +308,7 @@ static void * SDWebImageDownloaderContext = &SDWebImageDownloaderContext;
[self.URLOperations removeObjectForKey:url];
}
}
UNLOCK(self.operationsLock);
SD_UNLOCK(self.operationsLock);
}
- (void)cancelAllDownloads {

View File

@ -97,16 +97,16 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
SDCallbacksDictionary *callbacks = [NSMutableDictionary new];
if (progressBlock) callbacks[kProgressCallbackKey] = [progressBlock copy];
if (completedBlock) callbacks[kCompletedCallbackKey] = [completedBlock copy];
LOCK(self.callbacksLock);
SD_LOCK(self.callbacksLock);
[self.callbackBlocks addObject:callbacks];
UNLOCK(self.callbacksLock);
SD_UNLOCK(self.callbacksLock);
return callbacks;
}
- (nullable NSArray<id> *)callbacksForKey:(NSString *)key {
LOCK(self.callbacksLock);
SD_LOCK(self.callbacksLock);
NSMutableArray<id> *callbacks = [[self.callbackBlocks valueForKey:key] mutableCopy];
UNLOCK(self.callbacksLock);
SD_UNLOCK(self.callbacksLock);
// We need to remove [NSNull null] because there might not always be a progress block for each callback
[callbacks removeObjectIdenticalTo:[NSNull null]];
return [callbacks copy]; // strip mutability here
@ -114,12 +114,12 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
- (BOOL)cancel:(nullable id)token {
BOOL shouldCancel = NO;
LOCK(self.callbacksLock);
SD_LOCK(self.callbacksLock);
[self.callbackBlocks removeObjectIdenticalTo:token];
if (self.callbackBlocks.count == 0) {
shouldCancel = YES;
}
UNLOCK(self.callbacksLock);
SD_UNLOCK(self.callbacksLock);
if (shouldCancel) {
[self cancel];
}
@ -259,9 +259,9 @@ typedef NSMutableDictionary<NSString *, id> SDCallbacksDictionary;
}
- (void)reset {
LOCK(self.callbacksLock);
SD_LOCK(self.callbacksLock);
[self.callbackBlocks removeAllObjects];
UNLOCK(self.callbacksLock);
SD_UNLOCK(self.callbacksLock);
self.dataTask = nil;
if (self.ownedSession) {

View File

@ -136,9 +136,9 @@ static id<SDImageLoader> _defaultImageLoader;
BOOL isFailedUrl = NO;
if (url) {
LOCK(self.failedURLsLock);
SD_LOCK(self.failedURLsLock);
isFailedUrl = [self.failedURLs containsObject:url];
UNLOCK(self.failedURLsLock);
SD_UNLOCK(self.failedURLsLock);
}
if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) {
@ -146,9 +146,9 @@ static id<SDImageLoader> _defaultImageLoader;
return operation;
}
LOCK(self.runningOperationsLock);
SD_LOCK(self.runningOperationsLock);
[self.runningOperations addObject:operation];
UNLOCK(self.runningOperationsLock);
SD_UNLOCK(self.runningOperationsLock);
// Preprocess the context arg to provide the default value from manager
context = [self processedContextWithContext:context];
@ -160,17 +160,17 @@ static id<SDImageLoader> _defaultImageLoader;
}
- (void)cancelAll {
LOCK(self.runningOperationsLock);
SD_LOCK(self.runningOperationsLock);
NSSet<SDWebImageCombinedOperation *> *copiedOperations = [self.runningOperations copy];
UNLOCK(self.runningOperationsLock);
SD_UNLOCK(self.runningOperationsLock);
[copiedOperations makeObjectsPerformSelector:@selector(cancel)]; // This will call `safelyRemoveOperationFromRunning:` and remove from the array
}
- (BOOL)isRunning {
BOOL isRunning = NO;
LOCK(self.runningOperationsLock);
SD_LOCK(self.runningOperationsLock);
isRunning = (self.runningOperations.count > 0);
UNLOCK(self.runningOperationsLock);
SD_UNLOCK(self.runningOperationsLock);
return isRunning;
}
@ -261,15 +261,15 @@ static id<SDImageLoader> _defaultImageLoader;
}
if (shouldBlockFailedURL) {
LOCK(self.failedURLsLock);
SD_LOCK(self.failedURLsLock);
[self.failedURLs addObject:url];
UNLOCK(self.failedURLsLock);
SD_UNLOCK(self.failedURLsLock);
}
} else {
if ((options & SDWebImageRetryFailed)) {
LOCK(self.failedURLsLock);
SD_LOCK(self.failedURLsLock);
[self.failedURLs removeObject:url];
UNLOCK(self.failedURLsLock);
SD_UNLOCK(self.failedURLsLock);
}
SDImageCacheType storeCacheType = SDImageCacheTypeAll;
@ -338,9 +338,9 @@ static id<SDImageLoader> _defaultImageLoader;
if (!operation) {
return;
}
LOCK(self.runningOperationsLock);
SD_LOCK(self.runningOperationsLock);
[self.runningOperations removeObject:operation];
UNLOCK(self.runningOperationsLock);
SD_UNLOCK(self.runningOperationsLock);
}
- (void)callCompletionBlockForOperation:(nullable SDWebImageCombinedOperation*)operation