Skip to content

Commit

Permalink
Improve locking around clearContents (#1107)
Browse files Browse the repository at this point in the history
* Improve locking around clearContents

* Add changelog
  • Loading branch information
maicki authored Sep 14, 2018
1 parent eb5bd09 commit f759d5c
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
- Remove double scaling of lineHeightMultiple & paragraphSpacing attributes in ASTextKitFontSizeAdjuster. [Eric Jensen](https://github.com/ejensen)
- Add a delegate callback for when the framework has initialized. [Adlai Holler](https://github.com/Adlai-Holler)
- Improve TextNode2 by skipping an unneeded copy during measurement. [Adlai Holler](https://github.com/Adlai-Holler)
- Improve locking around clearContents [Michael Schneider](https://github.com/maicki)

## 2.7
- Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877)
Expand Down
15 changes: 11 additions & 4 deletions Source/ASDisplayNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3144,8 +3144,10 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState
[self setDisplaySuspended:YES];
//schedule clear contents on next runloop
dispatch_async(dispatch_get_main_queue(), ^{
ASDN::MutexLocker l(__instanceLock__);
if (ASInterfaceStateIncludesDisplay(_interfaceState) == NO) {
__instanceLock__.lock();
ASInterfaceState interfaceState = _interfaceState;
__instanceLock__.unlock();
if (ASInterfaceStateIncludesDisplay(interfaceState) == NO) {
[self clearContents];
}
});
Expand All @@ -3162,8 +3164,10 @@ - (void)applyPendingInterfaceState:(ASInterfaceState)newPendingState
[[self asyncLayer] cancelAsyncDisplay];
//schedule clear contents on next runloop
dispatch_async(dispatch_get_main_queue(), ^{
ASDN::MutexLocker l(__instanceLock__);
if (ASInterfaceStateIncludesDisplay(_interfaceState) == NO) {
__instanceLock__.lock();
ASInterfaceState interfaceState = _interfaceState;
__instanceLock__.unlock();
if (ASInterfaceStateIncludesDisplay(interfaceState) == NO) {
[self clearContents];
}
});
Expand Down Expand Up @@ -3355,6 +3359,9 @@ - (void)didExitPreloadState
- (void)clearContents
{
ASDisplayNodeAssertMainThread();
ASAssertUnlocked(__instanceLock__);

ASDN::MutexLocker l(__instanceLock__);
if (_flags.canClearContentsOfLayer) {
// No-op if these haven't been created yet, as that guarantees they don't have contents that needs to be released.
_layer.contents = nil;
Expand Down
7 changes: 3 additions & 4 deletions Source/ASImageNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -590,10 +590,9 @@ - (void)setNeedsDisplayWithCompletion:(void (^ _Nullable)(BOOL canceled))display
- (void)clearContents
{
[super clearContents];

__instanceLock__.lock();
_weakCacheEntry = nil; // release contents from the cache.
__instanceLock__.unlock();

ASDN::MutexLocker l(__instanceLock__);
_weakCacheEntry = nil; // release contents from the cache.
}

#pragma mark - Cropping
Expand Down
5 changes: 4 additions & 1 deletion Source/ASMultiplexImageNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,11 @@ - (void)reloadImageIdentifierSources
#pragma mark - Core Internal
- (void)_setDisplayedImageIdentifier:(id)displayedImageIdentifier withImage:(UIImage *)image
{
if (ASObjectIsEqual(displayedImageIdentifier, _displayedImageIdentifier))
ASDisplayNodeAssertMainThread();

if (ASObjectIsEqual(_displayedImageIdentifier, displayedImageIdentifier)) {
return;
}

_displayedImageIdentifier = displayedImageIdentifier;

Expand Down
2 changes: 2 additions & 0 deletions Source/Details/ASRangeController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ - (void)dataController:(ASDataController *)dataController updateWithChangeSet:(_
// Skip the many method calls of the recursive operation if the top level cell node already has the right interfaceState.
- (void)clearContents
{
ASDisplayNodeAssertMainThread();
for (ASCollectionElement *element in [_dataSource elementMapForRangeController:self]) {
ASCellNode *node = element.nodeIfAllocated;
if (ASInterfaceStateIncludesDisplay(node.interfaceState)) {
Expand All @@ -528,6 +529,7 @@ - (void)clearContents

- (void)clearPreloadedData
{
ASDisplayNodeAssertMainThread();
for (ASCollectionElement *element in [_dataSource elementMapForRangeController:self]) {
ASCellNode *node = element.nodeIfAllocated;
if (ASInterfaceStateIncludesPreload(node.interfaceState)) {
Expand Down

0 comments on commit f759d5c

Please sign in to comment.