From 324b633b0f3dd85519edc6883463a626b11a5531 Mon Sep 17 00:00:00 2001 From: Adlai Holler Date: Fri, 26 Feb 2016 23:14:58 -0800 Subject: [PATCH] [ASPendingStateController] Don't hold lock while flushing --- .../Private/ASPendingStateController.mm | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/AsyncDisplayKit/Private/ASPendingStateController.mm b/AsyncDisplayKit/Private/ASPendingStateController.mm index 113af7dc..4f2574a7 100644 --- a/AsyncDisplayKit/Private/ASPendingStateController.mm +++ b/AsyncDisplayKit/Private/ASPendingStateController.mm @@ -58,22 +58,18 @@ [self scheduleFlushIfNeeded]; } -/** - * NOTE: There is a small re-entrancy hazard here. - * If the user gives us a subclass of UIView/CALayer that - * adds side-effects to property sets, and one side effect - * waits on a background thread that sets a view/layer property - * on a loaded node, then we've got a deadlock. - */ - (void)flush { ASDisplayNodeAssertMainThread(); - ASDN::MutexLocker l(_lock); - for (ASDisplayNode *node in _dirtyNodes) { + _lock.lock(); + ASWeakSet *dirtyNodes = _dirtyNodes; + _dirtyNodes = [[ASWeakSet alloc] init]; + _flags.pendingFlush = NO; + _lock.unlock(); + + for (ASDisplayNode *node in dirtyNodes) { [node applyPendingViewState]; } - [_dirtyNodes removeAllObjects]; - _flags.pendingFlush = NO; }