From 80327581765635e68c2a705bc6f359a2c29dfcd2 Mon Sep 17 00:00:00 2001 From: Garrett Moon Date: Fri, 26 Aug 2016 14:09:38 -0700 Subject: [PATCH] Fixes a deadlock caused by walking up the heirarchy. (#2147) * Fixes a deadlock caused by walking up the heirarchy. * Use scope locker / unlocker and add a comment. * Add comment about calling __setNeedsLayout without the lock. --- AsyncDisplayKit/ASDisplayNode.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AsyncDisplayKit/ASDisplayNode.mm b/AsyncDisplayKit/ASDisplayNode.mm index 566b4ed9c6..4a296777ab 100644 --- a/AsyncDisplayKit/ASDisplayNode.mm +++ b/AsyncDisplayKit/ASDisplayNode.mm @@ -1182,6 +1182,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c) // but automatic subnode management would require us to modify the node tree // in the background on a loaded node, which isn't currently supported. if (_pendingViewState.hasSetNeedsLayout) { + //Need to unlock before calling setNeedsLayout to avoid deadlocks. + //MutexUnlocker will re-lock at the end of scope. + ASDN::MutexUnlocker u(__instanceLock__); [self __setNeedsLayout]; } @@ -1213,6 +1216,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c) [self displayImmediately]; } +//Calling this with the lock held can lead to deadlocks. Always call *unlocked* - (void)__setNeedsLayout { ASDisplayNodeAssertThreadAffinity(self);