mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-16 08:19:47 +08:00
Fix ReactInstanceManager deadlock
Summary: D12829677 introduced a deadlock where onHostResume holds the lock on `moveToResumedLifecycleState()` then waits for the `mReactContext` lock, but at the same time setupReactContext holds the `mReactContext` lock and waits for `moveToResumedLifecycleState()` https://our.intern.facebook.com/intern/everpaste/?handle=GAgXFgLQH1ZlQikBAMQzo2LZ6h9TbiAxAAAz. The purpose of the previous diff was to make sure that detachRootoView and setupReactContext did not interfere with each other, and implemented that by blocking on mReactContext. Since this overloads the usage of mReactContext, let's use a different lock `mAttachedRootViews` to implement this behavior instead Reviewed By: mdvacca Differential Revision: D12989555 fbshipit-source-id: c12e5fd9c5fa4c2037167e9400dc0c1578e38959
This commit is contained in:
committed by
Facebook Github Bot
parent
80f92adf1f
commit
df7e8c64ff
@@ -741,11 +741,13 @@ public class ReactInstanceManager {
|
||||
@ThreadConfined(UI)
|
||||
public void detachRootView(ReactRootView rootView) {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
if (mAttachedRootViews.contains(rootView)) {
|
||||
ReactContext currentContext = getCurrentReactContext();
|
||||
mAttachedRootViews.remove(rootView);
|
||||
if (currentContext != null && currentContext.hasActiveCatalystInstance()) {
|
||||
detachViewFromInstance(rootView, currentContext.getCatalystInstance());
|
||||
synchronized (mAttachedRootViews) {
|
||||
if (mAttachedRootViews.contains(rootView)) {
|
||||
ReactContext currentContext = getCurrentReactContext();
|
||||
mAttachedRootViews.remove(rootView);
|
||||
if (currentContext != null && currentContext.hasActiveCatalystInstance()) {
|
||||
detachViewFromInstance(rootView, currentContext.getCatalystInstance());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -904,10 +906,12 @@ public class ReactInstanceManager {
|
||||
private void runCreateReactContextOnNewThread(final ReactContextInitParams initParams) {
|
||||
Log.d(ReactConstants.TAG, "ReactInstanceManager.runCreateReactContextOnNewThread()");
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
synchronized (mReactContextLock) {
|
||||
if (mCurrentReactContext != null) {
|
||||
tearDownReactContext(mCurrentReactContext);
|
||||
mCurrentReactContext = null;
|
||||
synchronized (mAttachedRootViews) {
|
||||
synchronized (mReactContextLock) {
|
||||
if (mCurrentReactContext != null) {
|
||||
tearDownReactContext(mCurrentReactContext);
|
||||
mCurrentReactContext = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -979,8 +983,11 @@ public class ReactInstanceManager {
|
||||
ReactMarker.logMarker(PRE_SETUP_REACT_CONTEXT_END);
|
||||
ReactMarker.logMarker(SETUP_REACT_CONTEXT_START);
|
||||
Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "setupReactContext");
|
||||
synchronized (mReactContextLock) {
|
||||
mCurrentReactContext = Assertions.assertNotNull(reactContext);
|
||||
synchronized (mAttachedRootViews) {
|
||||
synchronized (mReactContextLock) {
|
||||
mCurrentReactContext = Assertions.assertNotNull(reactContext);
|
||||
}
|
||||
|
||||
CatalystInstance catalystInstance =
|
||||
Assertions.assertNotNull(reactContext.getCatalystInstance());
|
||||
|
||||
@@ -990,10 +997,8 @@ public class ReactInstanceManager {
|
||||
moveReactContextToCurrentLifecycleState();
|
||||
|
||||
ReactMarker.logMarker(ATTACH_MEASURED_ROOT_VIEWS_START);
|
||||
synchronized (mAttachedRootViews) {
|
||||
for (ReactRootView rootView : mAttachedRootViews) {
|
||||
attachRootViewToInstance(rootView);
|
||||
}
|
||||
for (ReactRootView rootView : mAttachedRootViews) {
|
||||
attachRootViewToInstance(rootView);
|
||||
}
|
||||
ReactMarker.logMarker(ATTACH_MEASURED_ROOT_VIEWS_END);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user