@@ -155,6 +155,7 @@ @implementation RCTCxxBridge
155155{
156156 BOOL _wasBatchActive;
157157 BOOL _didInvalidate;
158+ BOOL _moduleRegistryCreated;
158159
159160 NSMutableArray <RCTPendingCall> *_pendingCalls;
160161 std::atomic<NSInteger > _pendingCount;
@@ -169,6 +170,7 @@ @implementation RCTCxxBridge
169170 // JS thread management
170171 NSThread *_jsThread;
171172 std::shared_ptr<RCTMessageThread> _jsMessageThread;
173+ std::mutex _moduleRegistryLock;
172174
173175 // This is uniquely owned, but weak_ptr is used.
174176 std::shared_ptr<Instance> _reactInstance;
@@ -209,9 +211,9 @@ - (instancetype)initWithParentBridge:(RCTBridge *)bridge
209211 */
210212 _valid = YES ;
211213 _loading = YES ;
214+ _moduleRegistryCreated = NO ;
212215 _pendingCalls = [NSMutableArray new ];
213216 _displayLink = [RCTDisplayLink new ];
214-
215217 _moduleDataByName = [NSMutableDictionary new ];
216218 _moduleClassesByID = [NSMutableArray new ];
217219 _moduleDataByID = [NSMutableArray new ];
@@ -442,7 +444,7 @@ - (BOOL)moduleIsInitialized:(Class)moduleClass
442444 return _moduleDataByName[RCTBridgeModuleNameForClass (moduleClass)].hasInstance ;
443445}
444446
445- - (std::shared_ptr<ModuleRegistry>)_buildModuleRegistry
447+ - (std::shared_ptr<ModuleRegistry>)_buildModuleRegistryUnlocked
446448{
447449 if (!self.valid ) {
448450 return {};
@@ -489,12 +491,7 @@ - (void)_initializeBridge:(std::shared_ptr<JSExecutorFactory>)executorFactory
489491 executorFactory = std::make_shared<GetDescAdapter>(self, executorFactory);
490492#endif
491493
492- // This is async, but any calls into JS are blocked by the m_syncReady CV in Instance
493- _reactInstance->initializeBridge (
494- std::make_unique<RCTInstanceCallback>(self),
495- executorFactory,
496- _jsMessageThread,
497- [self _buildModuleRegistry ]);
494+ [self _initializeBridgeLocked: executorFactory];
498495
499496#if RCT_PROFILE
500497 if (RCTProfileIsProfiling ()) {
@@ -508,6 +505,19 @@ - (void)_initializeBridge:(std::shared_ptr<JSExecutorFactory>)executorFactory
508505 RCT_PROFILE_END_EVENT (RCTProfileTagAlways, @" " );
509506}
510507
508+ - (void )_initializeBridgeLocked : (std::shared_ptr<JSExecutorFactory>)executorFactory
509+ {
510+ std::lock_guard<std::mutex> guard (_moduleRegistryLock);
511+
512+ // This is async, but any calls into JS are blocked by the m_syncReady CV in Instance
513+ _reactInstance->initializeBridge (
514+ std::make_unique<RCTInstanceCallback>(self),
515+ executorFactory,
516+ _jsMessageThread,
517+ [self _buildModuleRegistryUnlocked ]);
518+ _moduleRegistryCreated = YES ;
519+ }
520+
511521- (NSArray <RCTModuleData *> *)registerModulesForClasses : (NSArray <Class> *)moduleClasses
512522{
513523 RCT_PROFILE_BEGIN_EVENT (RCTProfileTagAlways,
@@ -706,11 +716,13 @@ - (void)registerExtraLazyModules
706716
707717- (void )registerAdditionalModuleClasses : (NSArray <Class> *)modules
708718{
709- @synchronized (self) {
719+ std::lock_guard<std::mutex> guard (_moduleRegistryLock);
720+ if (_moduleRegistryCreated) {
710721 NSArray <RCTModuleData *> *newModules = [self _initializeModules: modules withDispatchGroup: NULL lazilyDiscovered: YES ];
711- if (_reactInstance) {
712- _reactInstance->getModuleRegistry ().registerModules (createNativeModules (newModules, self, _reactInstance));
713- }
722+ assert (_reactInstance); // at this point you must have reactInstance as you already called reactInstance->initialzeBridge
723+ _reactInstance->getModuleRegistry ().registerModules (createNativeModules (newModules, self, _reactInstance));
724+ } else {
725+ [self registerModulesForClasses: modules];
714726 }
715727}
716728
0 commit comments