From 33f20242f6df6e05b018d5b9b18c9519b0c930fb Mon Sep 17 00:00:00 2001 From: Spencer Ahrens Date: Tue, 24 Mar 2020 11:21:24 -0700 Subject: [PATCH] Hopefully fix so loading crashes Summary: Changelog: [Android][Internal] Fix potential initializer interruption threading crashes. Reviewed By: mdvacca Differential Revision: D20615755 fbshipit-source-id: 58b706deeb6df1998caff5bf2ae9ec60114313fe --- .../core/CallInvokerHolderImpl.java | 13 ++++++++++--- .../turbomodule/core/TurboModuleManager.java | 13 ++++++++++--- .../core/TurboModuleManagerDelegate.java | 18 ++++++++++++++---- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/CallInvokerHolderImpl.java b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/CallInvokerHolderImpl.java index e737a3ef14..c76bb1bc10 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/CallInvokerHolderImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/CallInvokerHolderImpl.java @@ -17,13 +17,20 @@ import com.facebook.soloader.SoLoader; * pass it from CatalystInstance, through Java, to TurboModuleManager::initHybrid. */ public class CallInvokerHolderImpl implements CallInvokerHolder { - static { - SoLoader.loadLibrary("turbomodulejsijni"); - } + private static volatile boolean sIsSoLibraryLoaded; private final HybridData mHybridData; private CallInvokerHolderImpl(HybridData hd) { + maybeLoadSoLibrary(); mHybridData = hd; } + + // Prevents issues with initializer interruptions. See T38996825 and D13793825 for more context. + private static synchronized void maybeLoadSoLibrary() { + if (!sIsSoLibraryLoaded) { + SoLoader.loadLibrary("turbomodulejsijni"); + sIsSoLibraryLoaded = true; + } + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java index 3496ba3b4d..67a9dd4831 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java @@ -26,11 +26,9 @@ import java.util.*; * a Java module, that the C++ counterpart calls. */ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { - static { - SoLoader.loadLibrary("turbomodulejsijni"); - } private final TurboModuleManagerDelegate mTurbomoduleManagerDelegate; + private static volatile boolean sIsSoLibraryLoaded; private final Map mTurboModules = new HashMap<>(); @@ -43,6 +41,7 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { TurboModuleManagerDelegate tmmDelegate, CallInvokerHolder jsCallInvokerHolder, CallInvokerHolder nativeCallInvokerHolder) { + maybeLoadSoLibrary(); mHybridData = initHybrid( jsContext.get(), @@ -137,4 +136,12 @@ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { // Delete the native part of this hybrid class. mHybridData.resetNative(); } + + // Prevents issues with initializer interruptions. See T38996825 and D13793825 for more context. + private static synchronized void maybeLoadSoLibrary() { + if (!sIsSoLibraryLoaded) { + SoLoader.loadLibrary("turbomodulejsijni"); + sIsSoLibraryLoaded = true; + } + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManagerDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManagerDelegate.java index b92fa24ff5..b744d110dd 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManagerDelegate.java +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManagerDelegate.java @@ -16,15 +16,15 @@ import java.util.ArrayList; import java.util.List; public abstract class TurboModuleManagerDelegate { - static { - SoLoader.loadLibrary("turbomodulejsijni"); - } - private final HybridData mHybridData; + private static volatile boolean sIsSoLibraryLoaded; + protected abstract HybridData initHybrid(); protected TurboModuleManagerDelegate() { + maybeLoadOtherSoLibraries(); + maybeLoadSoLibrary(); mHybridData = initHybrid(); } @@ -45,4 +45,14 @@ public abstract class TurboModuleManagerDelegate { public List getEagerInitModuleNames() { return new ArrayList<>(); } + + // Prevents issues with initializer interruptions. See T38996825 and D13793825 for more context. + private static synchronized void maybeLoadSoLibrary() { + if (!sIsSoLibraryLoaded) { + SoLoader.loadLibrary("turbomodulejsijni"); + sIsSoLibraryLoaded = true; + } + } + + protected synchronized void maybeLoadOtherSoLibraries() {} }