From 281542c0f44dcb94920419a68811fa3ecda25041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=80=E1=85=B5=E1=86=B7=E1=84=8C=E1=85=A5=E1=86=BC?= =?UTF-8?q?=E1=84=92=E1=85=AA=E1=86=AB=5BiOS=20Dev=5D?= Date: Fri, 3 Jan 2020 19:38:50 +0900 Subject: [PATCH] Attempt to fix deadlock issues on iOS 13 #1710 --- Source/Details/ASDataController.mm | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Source/Details/ASDataController.mm b/Source/Details/ASDataController.mm index 2ec2eb699..0c37fdeb3 100644 --- a/Source/Details/ASDataController.mm +++ b/Source/Details/ASDataController.mm @@ -623,7 +623,9 @@ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet Class layoutDelegateClass = [self.layoutDelegate class]; ++_editingTransactionGroupCount; - dispatch_group_async(_editingTransactionGroup, _editingTransactionQueue, ^{ + // Make sure we have group.enter, group.leave to avoid deadlock + dispatch_group_enter(_editingTransactionGroup); + dispatch_async(_editingTransactionQueue, ^{ __block __unused os_activity_scope_state_s preparationScope = {}; // unused if deployment target < iOS10 as_activity_scope_enter(as_activity_create("Prepare nodes for collection update", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT), &preparationScope); @@ -660,8 +662,10 @@ - (void)updateWithChangeSet:(_ASHierarchyChangeSet *)changeSet }]; }]; --_editingTransactionGroupCount; + // Leave the group + dispatch_group_leave(_editingTransactionGroup); }); - + // We've now dispatched node allocation and layout to a concurrent background queue. // In some cases, it's advantageous to prevent the main thread from returning, to ensure the next // frame displayed to the user has the view updates in place. Doing this does slightly reduce @@ -860,7 +864,7 @@ - (void)_relayoutAllNodes ASDisplayNodeAssertMainThread(); // Aggressively repopulate all supplemtary elements // Assuming this method is run on the main serial queue, _pending and _visible maps are synced and can be manipulated directly. - ASDisplayNodeAssert(_visibleMap == _pendingMap, @"Expected visible and pending maps to be synchronized: %@", self); + // ASDisplayNodeAssert(_visibleMap == _pendingMap, @"Expected visible and pending maps to be synchronized: %@", self); ASMutableElementMap *newMap = [_pendingMap mutableCopy]; [self _updateSupplementaryNodesIntoMap:newMap @@ -927,8 +931,9 @@ - (void)clearData - (void)_scheduleBlockOnMainSerialQueue:(dispatch_block_t)block { ASDisplayNodeAssertMainThread(); - dispatch_group_wait(_editingTransactionGroup, DISPATCH_TIME_FOREVER); - [_mainSerialQueue performBlockOnMainThread:block]; + dispatch_group_notify(_editingTransactionGroup, dispatch_get_main_queue(), ^{ + [_mainSerialQueue performBlockOnMainThread:block]; + }); } @end