diff --git a/AsyncDisplayKit/ASImageNode.mm b/AsyncDisplayKit/ASImageNode.mm index d32955d688..9704cfe8ef 100644 --- a/AsyncDisplayKit/ASImageNode.mm +++ b/AsyncDisplayKit/ASImageNode.mm @@ -44,7 +44,6 @@ struct ASImageNodeDrawParameters { UIImage *_image; void (^_displayCompletionBlock)(BOOL canceled); - ASDN::RecursiveMutex _imageLock; // Drawing ASImageNodeDrawParameters _drawParameter; @@ -119,7 +118,7 @@ struct ASImageNodeDrawParameters { - (CGSize)calculateSizeThatFits:(CGSize)constrainedSize { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); // if a preferredFrameSize is set, call the superclass to return that instead of using the image size. if (CGSizeEqualToSize(self.preferredFrameSize, CGSizeZero) == NO) return [super calculateSizeThatFits:constrainedSize]; @@ -133,11 +132,9 @@ struct ASImageNodeDrawParameters { - (void)setImage:(UIImage *)image { - _imageLock.lock(); + ASDN::MutexLocker l(_propertyLock); if (!ASObjectIsEqual(_image, image)) { _image = image; - - _imageLock.unlock(); [self invalidateCalculatedLayout]; if (image) { @@ -153,14 +150,12 @@ struct ASImageNodeDrawParameters { } else { self.contents = nil; } - } else { - _imageLock.unlock(); // We avoid using MutexUnlocker as it needlessly re-locks at the end of the scope. } } - (UIImage *)image { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); return _image; } @@ -176,7 +171,7 @@ struct ASImageNodeDrawParameters { - (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); _drawParameter = { .bounds = self.bounds, @@ -221,7 +216,7 @@ struct ASImageNodeDrawParameters { asimagenode_modification_block_t imageModificationBlock; { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); ASImageNodeDrawParameters drawParameter = _drawParameter; drawParameterBounds = drawParameter.bounds; @@ -356,19 +351,19 @@ struct ASImageNodeDrawParameters { { [super displayDidFinish]; - _imageLock.lock(); + _propertyLock.lock(); void (^displayCompletionBlock)(BOOL canceled) = _displayCompletionBlock; UIImage *image = _image; - _imageLock.unlock(); + _propertyLock.unlock(); // If we've got a block to perform after displaying, do it. if (image && displayCompletionBlock) { displayCompletionBlock(NO); - _imageLock.lock(); + _propertyLock.lock(); _displayCompletionBlock = nil; - _imageLock.unlock(); + _propertyLock.unlock(); } } @@ -381,7 +376,7 @@ struct ASImageNodeDrawParameters { } // Stash the block and call-site queue. We'll invoke it in -displayDidFinish. - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); if (_displayCompletionBlock != displayCompletionBlock) { _displayCompletionBlock = [displayCompletionBlock copy]; } @@ -393,7 +388,7 @@ struct ASImageNodeDrawParameters { - (BOOL)isCropEnabled { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); return _cropEnabled; } @@ -404,7 +399,7 @@ struct ASImageNodeDrawParameters { - (void)setCropEnabled:(BOOL)cropEnabled recropImmediately:(BOOL)recropImmediately inBounds:(CGRect)cropBounds { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); if (_cropEnabled == cropEnabled) return; @@ -425,13 +420,13 @@ struct ASImageNodeDrawParameters { - (CGRect)cropRect { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); return _cropRect; } - (void)setCropRect:(CGRect)cropRect { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); if (CGRectEqualToRect(_cropRect, cropRect)) return; @@ -452,25 +447,25 @@ struct ASImageNodeDrawParameters { - (BOOL)forceUpscaling { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); return _forceUpscaling; } - (void)setForceUpscaling:(BOOL)forceUpscaling { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); _forceUpscaling = forceUpscaling; } - (asimagenode_modification_block_t)imageModificationBlock { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); return _imageModificationBlock; } - (void)setImageModificationBlock:(asimagenode_modification_block_t)imageModificationBlock { - ASDN::MutexLocker l(_imageLock); + ASDN::MutexLocker l(_propertyLock); _imageModificationBlock = imageModificationBlock; } diff --git a/AsyncDisplayKit/ASNetworkImageNode.mm b/AsyncDisplayKit/ASNetworkImageNode.mm index aa33179d2a..67696883a1 100755 --- a/AsyncDisplayKit/ASNetworkImageNode.mm +++ b/AsyncDisplayKit/ASNetworkImageNode.mm @@ -11,6 +11,7 @@ #import "ASNetworkImageNode.h" #import "ASBasicImageDownloader.h" +#import "ASDisplayNodeInternal.h" #import "ASDisplayNode+Subclasses.h" #import "ASDisplayNode+FrameworkPrivate.h" #import "ASEqualityHelpers.h" @@ -26,11 +27,10 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; @interface ASNetworkImageNode () { - ASDN::RecursiveMutex _lock; __weak id _cache; __weak id _downloader; - // Only access any of these with _lock. + // Only access any of these with _propertyLock. __weak id _delegate; NSURL *_URL; @@ -121,7 +121,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; - (void)setURL:(NSURL *)URL resetToDefault:(BOOL)reset { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); if (ASObjectIsEqual(URL, _URL)) { return; @@ -150,16 +150,15 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; - (NSURL *)URL { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); return _URL; } - (void)setDefaultImage:(UIImage *)defaultImage { - _lock.lock(); + ASDN::MutexLocker l(_propertyLock); if (ASObjectIsEqual(defaultImage, _defaultImage)) { - _lock.unlock(); return; } _defaultImage = defaultImage; @@ -172,49 +171,43 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; dispatch_async(dispatch_get_main_queue(), ^{ self.currentImageQuality = hasURL ? 0.0 : 1.0; }); - _lock.unlock(); - // Locking: it is important to release _lock before entering setImage:, as it needs to release the lock before -invalidateCalculatedLayout. - // If we continue to hold the lock here, it will still be locked until the next unlock() call, causing a possible deadlock with - // -[ASNetworkImageNode displayWillStart] (which is called on a different thread / main, at an unpredictable time due to ASMainRunloopQueue). self.image = defaultImage; - } else { - _lock.unlock(); } } - (UIImage *)defaultImage { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); return _defaultImage; } - (void)setCurrentImageQuality:(CGFloat)currentImageQuality { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); _currentImageQuality = currentImageQuality; } - (CGFloat)currentImageQuality { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); return _currentImageQuality; } - (void)setRenderedImageQuality:(CGFloat)renderedImageQuality { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); _renderedImageQuality = renderedImageQuality; } - (CGFloat)renderedImageQuality { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); return _renderedImageQuality; } - (void)setDelegate:(id)delegate { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); _delegate = delegate; _delegateFlags.delegateDidStartFetchingData = [delegate respondsToSelector:@selector(imageNodeDidStartFetchingData:)]; @@ -225,13 +218,13 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; - (id)delegate { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); return _delegate; } - (void)setShouldRenderProgressImages:(BOOL)shouldRenderProgressImages { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); if (shouldRenderProgressImages == _shouldRenderProgressImages) { return; } @@ -239,19 +232,19 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; _shouldRenderProgressImages = shouldRenderProgressImages; - ASDN::MutexUnlocker u(_lock); + ASDN::MutexUnlocker u(_propertyLock); [self _updateProgressImageBlockOnDownloaderIfNeeded]; } - (BOOL)shouldRenderProgressImages { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); return _shouldRenderProgressImages; } - (BOOL)placeholderShouldPersist { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); return (self.image == nil && _URL != nil); } @@ -262,7 +255,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; [super displayWillStart]; if (_cacheFlags.cacheSupportsSynchronousFetch) { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); if (_imageLoaded == NO && _URL && _downloadIdentifier == nil) { UIImage *result = [[_cache synchronouslyFetchedCachedImageWithURL:_URL] asdk_image]; if (result) { @@ -279,7 +272,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; [self fetchData]; if (self.image == nil && _downloaderFlags.downloaderImplementsSetPriority) { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); if (_downloadIdentifier != nil) { [_downloader setPriority:ASImageDownloaderPriorityImminent withDownloadIdentifier:_downloadIdentifier]; } @@ -293,7 +286,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; [super visibleStateDidChange:isVisible]; if (_downloaderFlags.downloaderImplementsSetPriority) { - _lock.lock(); + ASDN::MutexLocker l(_propertyLock); if (_downloadIdentifier != nil) { if (isVisible) { [_downloader setPriority:ASImageDownloaderPriorityVisible withDownloadIdentifier:_downloadIdentifier]; @@ -301,10 +294,8 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; [_downloader setPriority:ASImageDownloaderPriorityPreload withDownloadIdentifier:_downloadIdentifier]; } } - _lock.unlock(); } - // This method has to be called without _lock held [self _updateProgressImageBlockOnDownloaderIfNeeded]; } @@ -313,7 +304,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; [super clearFetchedData]; { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); [self _cancelImageDownload]; [self _clearImage]; @@ -328,24 +319,19 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; [super fetchData]; { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); [self _lazilyLoadImageIfNecessary]; } } #pragma mark - Private methods -- only call with lock. -/** - @note: This should be called without _lock held. We will lock - super to read our interface state and it's best to avoid acquiring both locks. - */ - (void)_updateProgressImageBlockOnDownloaderIfNeeded { - BOOL shouldRenderProgressImages = self.shouldRenderProgressImages; + ASDN::MutexLocker l(_propertyLock); - // Read our interface state before locking so that we don't lock super while holding our lock. + BOOL shouldRenderProgressImages = _shouldRenderProgressImages; ASInterfaceState interfaceState = self.interfaceState; - ASDN::MutexLocker l(_lock); if (!_downloaderFlags.downloaderImplementsSetProgress || _downloadIdentifier == nil) { return; @@ -360,14 +346,15 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; return; } - ASDN::MutexLocker l(strongSelf->_lock); + ASDN::MutexLocker l(strongSelf->_propertyLock); //Getting a result back for a different download identifier, download must not have been successfully canceled if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) { return; } strongSelf.image = progressImage; dispatch_async(dispatch_get_main_queue(), ^{ - strongSelf->_currentImageQuality = progress; + // See comment in -displayDidFinish for why this must be dispatched to main + strongSelf.currentImageQuality = progress; }); }; } @@ -391,6 +378,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; self.animatedImage = nil; self.image = _defaultImage; _imageLoaded = NO; + // See comment in -displayDidFinish for why this must be dispatched to main dispatch_async(dispatch_get_main_queue(), ^{ self.currentImageQuality = 0.0; }); @@ -413,7 +401,8 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; - (void)_downloadImageWithCompletion:(void (^)(id imageContainer, NSError*, id downloadIdentifier))finished { ASPerformBlockOnBackgroundThread(^{ - _lock.lock(); + + ASDN::MutexLocker l(_propertyLock); if (_downloaderFlags.downloaderSupportsNewProtocol) { _downloadIdentifier = [_downloader downloadImageWithURL:_URL callbackQueue:dispatch_get_main_queue() @@ -436,9 +425,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; }]; #pragma clang diagnostic pop } - _lock.unlock(); - - // This method has to be called without _lock held + [self _updateProgressImageBlockOnDownloaderIfNeeded]; }); @@ -449,7 +436,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; // FIXME: We should revisit locking in this method (e.g. to access the instance variables at the top, and holding lock while calling delegate) if (!_imageLoaded && _URL != nil && _downloadIdentifier == nil) { { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); if (_delegateFlags.delegateDidStartFetchingData) { [_delegate imageNodeDidStartFetchingData:self]; } @@ -457,7 +444,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; if (_URL.isFileURL) { { - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); dispatch_async(dispatch_get_main_queue(), ^{ if (self.shouldCacheImage) { @@ -515,7 +502,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; return; } - ASDN::MutexLocker l(strongSelf->_lock); + ASDN::MutexLocker l(strongSelf->_propertyLock); //Getting a result back for a different download identifier, download must not have been successfully canceled if (ASObjectIsEqual(strongSelf->_downloadIdentifier, downloadIdentifier) == NO && downloadIdentifier != nil) { @@ -592,7 +579,7 @@ static const CGSize kMinReleaseImageOnBackgroundSize = {20.0, 20.0}; { [super displayDidFinish]; - ASDN::MutexLocker l(_lock); + ASDN::MutexLocker l(_propertyLock); if (_delegateFlags.delegateDidFinishDecoding && self.layer.contents != nil) { /* We store the image quality in _currentImageQuality whenever _image is set. On the following displayDidFinish, we'll know that _currentImageQuality is the quality of the image that has just finished rendering. In order for this to be accurate, we diff --git a/AsyncDisplayKit/ASTextNode.mm b/AsyncDisplayKit/ASTextNode.mm index e77b1b2bf2..28fb35764a 100644 --- a/AsyncDisplayKit/ASTextNode.mm +++ b/AsyncDisplayKit/ASTextNode.mm @@ -57,8 +57,6 @@ struct ASTextNodeDrawParameter { NSRange _highlightRange; ASHighlightOverlayLayer *_activeHighlightLayer; - std::recursive_mutex _textLock; - CGSize _constrainedSize; ASTextKitRenderer *_renderer; @@ -153,7 +151,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (NSString *)description { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); NSString *plainString = [[_attributedText string] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]]; NSString *truncationString = [_composedTruncationText string]; @@ -222,7 +220,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (ASTextKitRenderer *)_rendererWithBounds:(CGRect)bounds { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (_renderer == nil) { CGSize constrainedSize = _constrainedSize.width != -INFINITY ? _constrainedSize : bounds.size; @@ -234,7 +232,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (ASTextKitAttributes)_rendererAttributes { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return { .attributedString = _attributedText, @@ -260,7 +258,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; // so our previous layout information is invalid, and TextKit may draw at the // incorrect origin. { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); _constrainedSize = CGSizeMake(-INFINITY, -INFINITY); } [self _invalidateRenderer]; @@ -269,7 +267,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (void)_invalidateRenderer { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (_renderer) { // Destruction of the layout managers/containers/text storage is quite @@ -288,7 +286,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (BOOL)_needInvalidateRendererForBoundsSize:(CGSize)boundsSize { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (_renderer == nil) { return YES; @@ -327,7 +325,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; ASLayout *layout = self.calculatedLayout; if (layout != nil) { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); _constrainedSize = layout.size; _renderer.constrainedSize = layout.size; } @@ -338,7 +336,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; ASDisplayNodeAssert(constrainedSize.width >= 0, @"Constrained width for text (%f) is too narrow", constrainedSize.width); ASDisplayNodeAssert(constrainedSize.height >= 0, @"Constrained height for text (%f) is too short", constrainedSize.height); - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); _constrainedSize = constrainedSize; @@ -373,7 +371,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; // Don't hold textLock for too long. { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (ASObjectIsEqual(attributedText, _attributedText)) { return; } @@ -411,7 +409,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (void)setExclusionPaths:(NSArray *)exclusionPaths { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (ASObjectIsEqual(exclusionPaths, _exclusionPaths)) { return; @@ -425,7 +423,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (NSArray *)exclusionPaths { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return _exclusionPaths; } @@ -434,7 +432,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (NSObject *)drawParametersForAsyncLayer:(_ASDisplayLayer *)layer { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); _drawParameter = { .backgroundColor = self.backgroundColor, @@ -446,7 +444,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (void)drawRect:(CGRect)bounds withParameters:(id )p isCancelled:(asdisplaynode_iscancelled_block_t)isCancelledBlock isRasterizing:(BOOL)isRasterizing; { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); ASTextNodeDrawParameter drawParameter = _drawParameter; CGRect drawParameterBounds = drawParameter.bounds; @@ -499,7 +497,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; { ASDisplayNodeAssertMainThread(); - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); ASTextKitRenderer *renderer = [self _renderer]; NSRange visibleRange = renderer.firstVisibleRange; @@ -626,14 +624,14 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; - (ASTextNodeHighlightStyle)highlightStyle { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return _highlightStyle; } - (void)setHighlightStyle:(ASTextNodeHighlightStyle)highlightStyle { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); _highlightStyle = highlightStyle; } @@ -717,7 +715,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; } if (highlightTargetLayer != nil) { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); NSArray *highlightRects = [[self _renderer] rectsForTextRange:highlightRange measureOption:ASTextKitRendererMeasureOptionBlock]; NSMutableArray *converted = [NSMutableArray arrayWithCapacity:highlightRects.count]; @@ -797,7 +795,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI - (NSArray *)_rectsForTextRange:(NSRange)textRange measureOption:(ASTextKitRendererMeasureOption)measureOption { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); NSArray *rects = [[self _renderer] rectsForTextRange:textRange measureOption:measureOption]; NSMutableArray *adjustedRects = [NSMutableArray array]; @@ -815,7 +813,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI - (CGRect)trailingRect { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); CGRect rect = [[self _renderer] trailingRect]; return ASTextNodeAdjustRenderRectForShadowPadding(rect, self.shadowPadding); @@ -823,7 +821,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI - (CGRect)frameForTextRange:(NSRange)textRange { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); CGRect frame = [[self _renderer] frameForTextRange:textRange]; return ASTextNodeAdjustRenderRectForShadowPadding(frame, self.shadowPadding); @@ -833,7 +831,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI - (void)setPlaceholderColor:(UIColor *)placeholderColor { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); _placeholderColor = placeholderColor; @@ -850,7 +848,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI return nil; } - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); UIGraphicsBeginImageContext(size); [self.placeholderColor setFill]; @@ -932,7 +930,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI if (inAdditionalTruncationMessage) { NSRange visibleRange = NSMakeRange(0, 0); { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); visibleRange = [self _renderer].firstVisibleRange; } NSRange truncationMessageRange = [self _additionalTruncationMessageRangeWithVisibleRange:visibleRange]; @@ -1011,14 +1009,14 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI - (BOOL)_pendingLinkTap { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return (_highlightedLinkAttributeValue != nil && ![self _pendingTruncationTap]) && _delegate != nil; } - (BOOL)_pendingTruncationTap { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return [_highlightedLinkAttributeName isEqualToString:ASTextNodeTruncationTokenAttributeName]; } @@ -1027,14 +1025,14 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI - (CGColorRef)shadowColor { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return _shadowColor; } - (void)setShadowColor:(CGColorRef)shadowColor { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (_shadowColor != shadowColor) { if (shadowColor != NULL) { @@ -1048,14 +1046,14 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI - (CGSize)shadowOffset { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return _shadowOffset; } - (void)setShadowOffset:(CGSize)shadowOffset { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (!CGSizeEqualToSize(_shadowOffset, shadowOffset)) { _shadowOffset = shadowOffset; @@ -1066,14 +1064,14 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI - (CGFloat)shadowOpacity { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return _shadowOpacity; } - (void)setShadowOpacity:(CGFloat)shadowOpacity { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (_shadowOpacity != shadowOpacity) { _shadowOpacity = shadowOpacity; @@ -1084,14 +1082,14 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI - (CGFloat)shadowRadius { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return _shadowRadius; } - (void)setShadowRadius:(CGFloat)shadowRadius { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (_shadowRadius != shadowRadius) { _shadowRadius = shadowRadius; @@ -1107,7 +1105,7 @@ static CGRect ASTextNodeAdjustRenderRectForShadowPadding(CGRect rendererRect, UI - (UIEdgeInsets)shadowPaddingWithRenderer:(ASTextKitRenderer *)renderer { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return renderer.shadower.shadowPadding; } @@ -1126,7 +1124,7 @@ static NSAttributedString *DefaultTruncationAttributedString() - (void)setTruncationAttributedText:(NSAttributedString *)truncationAttributedText { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (ASObjectIsEqual(_truncationAttributedText, truncationAttributedText)) { return; @@ -1138,7 +1136,7 @@ static NSAttributedString *DefaultTruncationAttributedString() - (void)setAdditionalTruncationMessage:(NSAttributedString *)additionalTruncationMessage { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (ASObjectIsEqual(_additionalTruncationMessage, additionalTruncationMessage)) { return; @@ -1150,7 +1148,7 @@ static NSAttributedString *DefaultTruncationAttributedString() - (void)setTruncationMode:(NSLineBreakMode)truncationMode { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (_truncationMode != truncationMode) { _truncationMode = truncationMode; @@ -1161,7 +1159,7 @@ static NSAttributedString *DefaultTruncationAttributedString() - (BOOL)isTruncated { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); ASTextKitRenderer *renderer = [self _renderer]; return renderer.firstVisibleRange.length < _attributedText.length; @@ -1169,7 +1167,7 @@ static NSAttributedString *DefaultTruncationAttributedString() - (void)setPointSizeScaleFactors:(NSArray *)pointSizeScaleFactors { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if ([_pointSizeScaleFactors isEqualToArray:pointSizeScaleFactors] == NO) { _pointSizeScaleFactors = pointSizeScaleFactors; @@ -1179,7 +1177,7 @@ static NSAttributedString *DefaultTruncationAttributedString() - (void)setMaximumNumberOfLines:(NSUInteger)maximumNumberOfLines { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); if (_maximumNumberOfLines != maximumNumberOfLines) { _maximumNumberOfLines = maximumNumberOfLines; @@ -1190,7 +1188,7 @@ static NSAttributedString *DefaultTruncationAttributedString() - (NSUInteger)lineCount { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); return [[self _renderer] lineCount]; } @@ -1199,7 +1197,7 @@ static NSAttributedString *DefaultTruncationAttributedString() - (void)_updateComposedTruncationText { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); _composedTruncationText = [self _prepareTruncationStringForDrawing:[self _composedTruncationText]]; } @@ -1217,7 +1215,7 @@ static NSAttributedString *DefaultTruncationAttributedString() */ - (NSRange)_additionalTruncationMessageRangeWithVisibleRange:(NSRange)visibleRange { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); // Check if we even have an additional truncation message. if (!_additionalTruncationMessage) { @@ -1240,7 +1238,7 @@ static NSAttributedString *DefaultTruncationAttributedString() */ - (NSAttributedString *)_composedTruncationText { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); //If we have neither return the default if (!_additionalTruncationMessage && !_truncationAttributedText) { @@ -1270,7 +1268,7 @@ static NSAttributedString *DefaultTruncationAttributedString() */ - (NSAttributedString *)_prepareTruncationStringForDrawing:(NSAttributedString *)truncationString { - std::lock_guard l(_textLock); + ASDN::MutexLocker l(_propertyLock); truncationString = ASCleanseAttributedStringOfCoreTextAttributes(truncationString); NSMutableAttributedString *truncationMutableString = [truncationString mutableCopy]; diff --git a/AsyncDisplayKit/ASVideoNode.mm b/AsyncDisplayKit/ASVideoNode.mm index 1a29eb865d..7e0c9050da 100644 --- a/AsyncDisplayKit/ASVideoNode.mm +++ b/AsyncDisplayKit/ASVideoNode.mm @@ -9,6 +9,7 @@ // #if TARGET_OS_IOS #import +#import "ASDisplayNodeInternal.h" #import "ASDisplayNode+Subclasses.h" #import "ASVideoNode.h" #import "ASEqualityHelpers.h" @@ -39,8 +40,6 @@ static NSString * const kStatus = @"status"; @interface ASVideoNode () { - ASDN::RecursiveMutex _videoLock; - __weak id _delegate; struct { unsigned int delegateVideNodeShouldChangePlayerStateTo:1; @@ -122,7 +121,7 @@ static NSString * const kStatus = @"status"; - (AVPlayerItem *)constructPlayerItem { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); if (_asset != nil) { return [[AVPlayerItem alloc] initWithAsset:_asset]; @@ -210,7 +209,7 @@ static NSString * const kStatus = @"status"; - (CGSize)calculateSizeThatFits:(CGSize)constrainedSize { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); CGSize calculatedSize = constrainedSize; // if a preferredFrameSize is set, call the superclass to return that instead of using the image size. @@ -273,7 +272,7 @@ static NSString * const kStatus = @"status"; - (void)setVideoPlaceholderImage:(UIImage *)image { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); if (image != nil) { self.contentMode = ASContentModeFromVideoGravity(_gravity); } @@ -282,7 +281,7 @@ static NSString * const kStatus = @"status"; - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); if (object != _currentPlayerItem) { return; @@ -335,7 +334,7 @@ static NSString * const kStatus = @"status"; { [super fetchData]; - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); AVAsset *asset = self.asset; // Return immediately if the asset is nil; if (asset == nil || self.playerState == ASVideoNodePlayerStateInitialLoading) { @@ -385,7 +384,7 @@ static NSString * const kStatus = @"status"; [super clearFetchedData]; { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); self.player = nil; self.currentItem = nil; @@ -396,7 +395,7 @@ static NSString * const kStatus = @"status"; { [super visibleStateDidChange:isVisible]; - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); if (isVisible) { if (_shouldBePlaying || _shouldAutoplay) { @@ -413,7 +412,7 @@ static NSString * const kStatus = @"status"; - (void)setPlayerState:(ASVideoNodePlayerState)playerState { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); ASVideoNodePlayerState oldState = _playerState; @@ -430,7 +429,7 @@ static NSString * const kStatus = @"status"; - (void)setAsset:(AVAsset *)asset { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); if (ASAssetIsEqual(asset, _asset)) { return; @@ -445,13 +444,13 @@ static NSString * const kStatus = @"status"; - (AVAsset *)asset { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); return _asset; } - (AVPlayer *)player { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); return _player; } @@ -489,7 +488,7 @@ static NSString * const kStatus = @"status"; - (void)setGravity:(NSString *)gravity { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); if (_playerNode.isNodeLoaded) { ((AVPlayerLayer *)_playerNode.layer).videoGravity = gravity; } @@ -499,19 +498,19 @@ static NSString * const kStatus = @"status"; - (NSString *)gravity { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); return _gravity; } - (BOOL)muted { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); return _muted; } - (void)setMuted:(BOOL)muted { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); _player.muted = muted; _muted = muted; @@ -521,7 +520,7 @@ static NSString * const kStatus = @"status"; - (void)play { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); if (![self isStateChangeValid:ASVideoNodePlayerStatePlaying]) { return; @@ -558,7 +557,7 @@ static NSString * const kStatus = @"status"; - (void)pause { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); if (![self isStateChangeValid:ASVideoNodePlayerStatePaused]) { return; } @@ -569,7 +568,7 @@ static NSString * const kStatus = @"status"; - (BOOL)isPlaying { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); return (_player.rate > 0 && !_player.error); } @@ -637,13 +636,13 @@ static NSString * const kStatus = @"status"; - (AVPlayerItem *)currentItem { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); return _currentPlayerItem; } - (void)setCurrentItem:(AVPlayerItem *)currentItem { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); [self removePlayerItemObservers:_currentPlayerItem]; @@ -656,13 +655,13 @@ static NSString * const kStatus = @"status"; - (ASDisplayNode *)playerNode { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); return _playerNode; } - (void)setPlayerNode:(ASDisplayNode *)playerNode { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); _playerNode = playerNode; [self setNeedsLayout]; @@ -670,7 +669,7 @@ static NSString * const kStatus = @"status"; - (void)setPlayer:(AVPlayer *)player { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); _player = player; player.muted = _muted; ((AVPlayerLayer *)_playerNode.layer).player = player; @@ -678,13 +677,13 @@ static NSString * const kStatus = @"status"; - (BOOL)shouldBePlaying { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); return _shouldBePlaying; } - (void)setShouldBePlaying:(BOOL)shouldBePlaying { - ASDN::MutexLocker l(_videoLock); + ASDN::MutexLocker l(_propertyLock); _shouldBePlaying = shouldBePlaying; }