Using lock to ensure SDImageFramePool register/unregister logic in multi-thread environment

This commit is contained in:
DreamPiggy 2023-05-09 16:40:59 +08:00
parent 181f8d2183
commit 507f1b6b45
1 changed files with 15 additions and 0 deletions

View File

@ -22,6 +22,9 @@
@end @end
// Lock to ensure atomic behavior
SD_LOCK_DECLARE_STATIC(_providerFramePoolMapLock);
@implementation SDImageFramePool @implementation SDImageFramePool
+ (NSMapTable *)providerFramePoolMap { + (NSMapTable *)providerFramePoolMap {
@ -58,7 +61,14 @@
[self removeAllFrames]; [self removeAllFrames];
} }
+ (void)initialize {
// Lock to ensure atomic behavior
SD_LOCK_INIT(_providerFramePoolMapLock);
}
+ (instancetype)registerProvider:(id<SDAnimatedImageProvider>)provider { + (instancetype)registerProvider:(id<SDAnimatedImageProvider>)provider {
// Lock to ensure atomic behavior
SD_LOCK(_providerFramePoolMapLock);
SDImageFramePool *framePool = [self.providerFramePoolMap objectForKey:provider]; SDImageFramePool *framePool = [self.providerFramePoolMap objectForKey:provider];
if (!framePool) { if (!framePool) {
framePool = [[SDImageFramePool alloc] init]; framePool = [[SDImageFramePool alloc] init];
@ -66,18 +76,23 @@
[self.providerFramePoolMap setObject:framePool forKey:provider]; [self.providerFramePoolMap setObject:framePool forKey:provider];
} }
framePool.registerCount += 1; framePool.registerCount += 1;
SD_UNLOCK(_providerFramePoolMapLock);
return framePool; return framePool;
} }
+ (void)unregisterProvider:(id<SDAnimatedImageProvider>)provider { + (void)unregisterProvider:(id<SDAnimatedImageProvider>)provider {
// Lock to ensure atomic behavior
SD_LOCK(_providerFramePoolMapLock);
SDImageFramePool *framePool = [self.providerFramePoolMap objectForKey:provider]; SDImageFramePool *framePool = [self.providerFramePoolMap objectForKey:provider];
if (!framePool) { if (!framePool) {
SD_UNLOCK(_providerFramePoolMapLock);
return; return;
} }
framePool.registerCount -= 1; framePool.registerCount -= 1;
if (framePool.registerCount == 0) { if (framePool.registerCount == 0) {
[self.providerFramePoolMap removeObjectForKey:provider]; [self.providerFramePoolMap removeObjectForKey:provider];
} }
SD_UNLOCK(_providerFramePoolMapLock);
} }
- (void)prefetchFrameAtIndex:(NSUInteger)index { - (void)prefetchFrameAtIndex:(NSUInteger)index {