From 366fa2f1ef442bf30da17ec82131a59bb1b7906b Mon Sep 17 00:00:00 2001 From: Spencer Ahrens Date: Fri, 29 Mar 2019 10:27:20 -0700 Subject: [PATCH] use shared mutex in RCTSurfacePresenter Summary: Otherwise reloading from metro deadlocks like this: `[RCTSurfaceRegistry _stopAllSurfaces]` is calling `[RCTSurfaceRegistry enumerateWithBlock]` which locks `_mutex` and then we call `surfaceForRootTag` which then deadlocks on the same mutex: https://pxl.cl/tmm1 Reviewed By: shergin Differential Revision: D14679843 fbshipit-source-id: 9f4ecdfa7a79fcf7f3fc2ce437d4399b00910f26 --- React/Fabric/RCTSurfaceRegistry.mm | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/React/Fabric/RCTSurfaceRegistry.mm b/React/Fabric/RCTSurfaceRegistry.mm index 76bbf8f86..0eae535f4 100644 --- a/React/Fabric/RCTSurfaceRegistry.mm +++ b/React/Fabric/RCTSurfaceRegistry.mm @@ -8,11 +8,15 @@ #import "RCTSurfaceRegistry.h" #import +#import +#import #import +using namespace facebook; + @implementation RCTSurfaceRegistry { - std::mutex _mutex; + better::shared_mutex _mutex; NSMapTable *_registry; } @@ -28,13 +32,13 @@ - (void)enumerateWithBlock:(RCTSurfaceEnumeratorBlock)block { - std::lock_guard lock(_mutex); + std::shared_lock lock(_mutex); block([_registry objectEnumerator]); } - (void)registerSurface:(RCTFabricSurface *)surface { - std::lock_guard lock(_mutex); + std::unique_lock lock(_mutex); ReactTag rootTag = surface.rootViewTag.integerValue; [_registry setObject:surface forKey:(__bridge id)(void *)rootTag]; @@ -42,7 +46,7 @@ - (void)unregisterSurface:(RCTFabricSurface *)surface { - std::lock_guard lock(_mutex); + std::unique_lock lock(_mutex); ReactTag rootTag = surface.rootViewTag.integerValue; [_registry removeObjectForKey:(__bridge id)(void *)rootTag]; @@ -50,7 +54,7 @@ - (RCTFabricSurface *)surfaceForRootTag:(ReactTag)rootTag { - std::lock_guard lock(_mutex); + std::shared_lock lock(_mutex); return [_registry objectForKey:(__bridge id)(void *)rootTag]; }