diff --git a/Source/ASImageNode.mm b/Source/ASImageNode.mm index bed6655608..097320fd65 100644 --- a/Source/ASImageNode.mm +++ b/Source/ASImageNode.mm @@ -433,11 +433,15 @@ typedef void (^ASImageNodeDrawParametersBlock)(ASWeakMapEntry *entry); } static ASWeakMap *cache = nil; -// Allocate cacheLock on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) -static auto *cacheLock = new ASDN::Mutex; + (ASWeakMapEntry *)contentsForkey:(ASImageNodeContentsKey *)key drawParameters:(id)drawParameters isCancelled:(asdisplaynode_iscancelled_block_t)isCancelled { + static dispatch_once_t onceToken; + static ASDN::Mutex *cacheLock = nil; + dispatch_once(&onceToken, ^{ + cacheLock = new ASDN::Mutex(); + }); + { ASDN::MutexLocker l(*cacheLock); if (!cache) { diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index a96f4f00f8..14c2afd93f 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -54,11 +54,11 @@ * NOTE: Be careful to copy `text` if needed. */ static NS_RETURNS_RETAINED ASTextLayout *ASTextNodeCompatibleLayoutWithContainerAndText(ASTextContainer *container, NSAttributedString *text) { - // Allocate layoutCacheLock on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) - static auto *layoutCacheLock = new ASDN::Mutex; - static NSCache *textLayoutCache; static dispatch_once_t onceToken; + static ASDN::Mutex *layoutCacheLock; + static NSCache *textLayoutCache; dispatch_once(&onceToken, ^{ + layoutCacheLock = new ASDN::Mutex(); textLayoutCache = [[NSCache alloc] init]; }); diff --git a/Source/Details/ASBasicImageDownloader.mm b/Source/Details/ASBasicImageDownloader.mm index c13fc728bc..c5c1f72b68 100644 --- a/Source/Details/ASBasicImageDownloader.mm +++ b/Source/Details/ASBasicImageDownloader.mm @@ -38,12 +38,20 @@ NSString * const kASBasicImageDownloaderContextCompletionBlock = @"kASBasicImage @implementation ASBasicImageDownloaderContext static NSMutableDictionary *currentRequests = nil; -// Allocate currentRequestsLock on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) -static auto *currentRequestsLock = new ASDN::Mutex; + ++ (ASDN::Mutex *)currentRequestLock +{ + static dispatch_once_t onceToken; + static ASDN::Mutex *currentRequestsLock; + dispatch_once(&onceToken, ^{ + currentRequestsLock = new ASDN::Mutex(); + }); + return currentRequestsLock; +} + (ASBasicImageDownloaderContext *)contextForURL:(NSURL *)URL { - ASDN::MutexLocker l(*currentRequestsLock); + ASDN::MutexLocker l(*self.currentRequestLock); if (!currentRequests) { currentRequests = [[NSMutableDictionary alloc] init]; } @@ -57,7 +65,7 @@ static auto *currentRequestsLock = new ASDN::Mutex; + (void)cancelContextWithURL:(NSURL *)URL { - ASDN::MutexLocker l(*currentRequestsLock); + ASDN::MutexLocker l(*self.currentRequestLock); if (currentRequests) { [currentRequests removeObjectForKey:URL]; } diff --git a/Source/TextKit/ASTextKitContext.mm b/Source/TextKit/ASTextKitContext.mm index d7f6d7b0be..75582f471f 100644 --- a/Source/TextKit/ASTextKitContext.mm +++ b/Source/TextKit/ASTextKitContext.mm @@ -34,9 +34,13 @@ { if (self = [super init]) { + static dispatch_once_t onceToken; + static ASDN::Mutex *mutex; + dispatch_once(&onceToken, ^{ + mutex = new ASDN::Mutex(); + }); + // Concurrently initialising TextKit components crashes (rdar://18448377) so we use a global lock. - // Allocate mutex on the heap to prevent destruction at app exit (https://github.com/TextureGroup/Texture/issues/136) - static auto *mutex = new ASDN::Mutex; ASDN::MutexLocker l(*mutex); __instanceLock__ = std::make_shared();