diff --git a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm index 0da68b3f3db..93f91f00ef7 100644 --- a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm +++ b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm @@ -8,6 +8,7 @@ #import "RCTTurboModuleManager.h" #import +#import #import #import @@ -45,6 +46,18 @@ static Class getFallbackClassFromName(const char *name) */ std::unordered_map> _rctTurboModuleCache; std::unordered_map> _turboModuleCache; + + /** + * _rctTurboModuleCache can be accessed by muitiple threads at once via + * the provideRCTTurboModule method. This can lead to races. Therefore, we + * need to protect access to this unordered_map. + * + * Note: + * There's no need to protect access to _turboModuleCache because that cache + * is only accessed within provideTurboModule, which is only invoked by the + * JS thread. + */ + std::mutex _rctTurboModuleCacheLock; } - (instancetype)initWithBridge:(RCTBridge *)bridge delegate:(id)delegate @@ -198,6 +211,8 @@ static Class getFallbackClassFromName(const char *name) */ - (id)provideRCTTurboModule:(const char *)moduleName { + std::lock_guard guard{_rctTurboModuleCacheLock}; + auto rctTurboModuleCacheLookup = _rctTurboModuleCache.find(moduleName); if (rctTurboModuleCacheLookup != _rctTurboModuleCache.end()) { return rctTurboModuleCacheLookup->second;