diff --git a/packages/react-native/React/CxxBridge/RCTCxxBridge.mm b/packages/react-native/React/CxxBridge/RCTCxxBridge.mm index dc19bd2eb142b5..aeece2d3be09d7 100644 --- a/packages/react-native/React/CxxBridge/RCTCxxBridge.mm +++ b/packages/react-native/React/CxxBridge/RCTCxxBridge.mm @@ -162,11 +162,13 @@ static void mapReactMarkerToPerformanceLogger( static void registerPerformanceLoggerHooks(RCTPerformanceLogger *performanceLogger) { + std::unique_lock lock(ReactMarker::logTaggedMarkerImplMutex); __weak RCTPerformanceLogger *weakPerformanceLogger = performanceLogger; - ReactMarker::logTaggedMarkerImpl = [weakPerformanceLogger]( - const ReactMarker::ReactMarkerId markerId, const char *tag) { + ReactMarker::LogTaggedMarker newMarker = [weakPerformanceLogger]( + const ReactMarker::ReactMarkerId markerId, const char *tag) { mapReactMarkerToPerformanceLogger(markerId, weakPerformanceLogger, tag); }; + ReactMarker::logTaggedMarkerImpl = newMarker; } @interface RCTCxxBridge () diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp index 131237c6d49bff..16d523719d051f 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactMarker.cpp @@ -16,6 +16,7 @@ namespace facebook::react { void JReactMarker::setLogPerfMarkerIfNeeded() { static std::once_flag flag{}; std::call_once(flag, []() { + std::unique_lock lock(ReactMarker::logTaggedMarkerImplMutex); ReactMarker::logTaggedMarkerImpl = JReactMarker::logPerfMarker; ReactMarker::logTaggedMarkerBridgelessImpl = JReactMarker::logPerfMarkerBridgeless; diff --git a/packages/react-native/ReactCommon/cxxreact/ReactMarker.cpp b/packages/react-native/ReactCommon/cxxreact/ReactMarker.cpp index 86c3a03c9df5bf..9180effba85a3b 100644 --- a/packages/react-native/ReactCommon/cxxreact/ReactMarker.cpp +++ b/packages/react-native/ReactCommon/cxxreact/ReactMarker.cpp @@ -16,8 +16,9 @@ namespace ReactMarker { #pragma clang diagnostic ignored "-Wglobal-constructors" #endif -LogTaggedMarker logTaggedMarkerImpl = nullptr; LogTaggedMarker logTaggedMarkerBridgelessImpl = nullptr; +LogTaggedMarker logTaggedMarkerImpl = nullptr; +std::shared_mutex logTaggedMarkerImplMutex; #if __clang__ #pragma clang diagnostic pop @@ -28,7 +29,14 @@ void logMarker(const ReactMarkerId markerId) { } void logTaggedMarker(const ReactMarkerId markerId, const char* tag) { - logTaggedMarkerImpl(markerId, tag); + LogTaggedMarker marker = nullptr; + { + std::shared_lock lock(logTaggedMarkerImplMutex); + marker = logTaggedMarkerImpl; + } + if (marker != nullptr) { + marker(markerId, tag); + } } void logMarkerBridgeless(const ReactMarkerId markerId) { diff --git a/packages/react-native/ReactCommon/cxxreact/ReactMarker.h b/packages/react-native/ReactCommon/cxxreact/ReactMarker.h index e50746780d4867..b74748a655bf2c 100644 --- a/packages/react-native/ReactCommon/cxxreact/ReactMarker.h +++ b/packages/react-native/ReactCommon/cxxreact/ReactMarker.h @@ -8,6 +8,7 @@ #pragma once #include +#include #ifdef __APPLE__ #include @@ -51,7 +52,10 @@ typedef void (*LogTaggedMarkerBridgeless)(const ReactMarkerId, const char* tag); #define RN_EXPORT __attribute__((visibility("default"))) #endif -extern RN_EXPORT LogTaggedMarker logTaggedMarkerImpl; // Bridge only +extern RN_EXPORT std::shared_mutex logTaggedMarkerImplMutex; +/// - important: To ensure this gets read and written to in a thread safe +/// manner, make use of `logTaggedMarkerImplMutex`. +extern RN_EXPORT LogTaggedMarker logTaggedMarkerImpl; extern RN_EXPORT LogTaggedMarker logTaggedMarkerBridgelessImpl; extern RN_EXPORT void logMarker(const ReactMarkerId markerId); // Bridge only diff --git a/packages/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp b/packages/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp index 51fabddc8f0f03..368f36485550b7 100644 --- a/packages/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp +++ b/packages/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp @@ -139,8 +139,11 @@ void JSIExecutor::initializeRuntime() { if (runtimeInstaller_) { runtimeInstaller_(*runtime_); } - - bool hasLogger(ReactMarker::logTaggedMarkerImpl); + bool hasLogger = false; + { + std::shared_lock lock(ReactMarker::logTaggedMarkerImplMutex); + hasLogger = ReactMarker::logTaggedMarkerImpl != nullptr; + } if (hasLogger) { ReactMarker::logMarker(ReactMarker::CREATE_REACT_CONTEXT_STOP); } @@ -150,8 +153,11 @@ void JSIExecutor::loadBundle( std::unique_ptr script, std::string sourceURL) { SystraceSection s("JSIExecutor::loadBundle"); - - bool hasLogger(ReactMarker::logTaggedMarkerImpl); + bool hasLogger = false; + { + std::shared_lock lock(ReactMarker::logTaggedMarkerImplMutex); + hasLogger = ReactMarker::logTaggedMarkerImpl != nullptr; + } std::string scriptName = simpleBasename(sourceURL); if (hasLogger) { ReactMarker::logTaggedMarker( diff --git a/packages/react-native/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp b/packages/react-native/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp index 56503c683e4a39..f61f46f2cfe121 100644 --- a/packages/react-native/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp +++ b/packages/react-native/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp @@ -67,7 +67,11 @@ void JSINativeModules::reset() { std::optional JSINativeModules::createModule( Runtime& rt, const std::string& name) { - bool hasLogger(ReactMarker::logTaggedMarkerImpl); + bool hasLogger = false; + { + std::shared_lock lock(ReactMarker::logTaggedMarkerImplMutex); + hasLogger = ReactMarker::logTaggedMarkerImpl != nullptr; + } if (hasLogger) { ReactMarker::logTaggedMarker( ReactMarker::NATIVE_MODULE_SETUP_START, name.c_str());