@@ -158,6 +158,7 @@ @implementation RCTCxxBridge
158
158
{
159
159
BOOL _wasBatchActive;
160
160
BOOL _didInvalidate;
161
+ BOOL _moduleRegistryCreated;
161
162
162
163
NSMutableArray <RCTPendingCall> *_pendingCalls;
163
164
std::atomic<NSInteger > _pendingCount;
@@ -172,6 +173,7 @@ @implementation RCTCxxBridge
172
173
// JS thread management
173
174
NSThread *_jsThread;
174
175
std::shared_ptr<RCTMessageThread> _jsMessageThread;
176
+ std::mutex _moduleRegistryLock;
175
177
176
178
// This is uniquely owned, but weak_ptr is used.
177
179
std::shared_ptr<Instance> _reactInstance;
@@ -219,9 +221,9 @@ - (instancetype)initWithParentBridge:(RCTBridge *)bridge
219
221
*/
220
222
_valid = YES ;
221
223
_loading = YES ;
224
+ _moduleRegistryCreated = NO ;
222
225
_pendingCalls = [NSMutableArray new ];
223
226
_displayLink = [RCTDisplayLink new ];
224
-
225
227
_moduleDataByName = [NSMutableDictionary new ];
226
228
_moduleClassesByID = [NSMutableArray new ];
227
229
_moduleDataByID = [NSMutableArray new ];
@@ -456,7 +458,7 @@ - (BOOL)moduleIsInitialized:(Class)moduleClass
456
458
return _moduleDataByName[RCTBridgeModuleNameForClass (moduleClass)].hasInstance ;
457
459
}
458
460
459
- - (std::shared_ptr<ModuleRegistry>)_buildModuleRegistry
461
+ - (std::shared_ptr<ModuleRegistry>)_buildModuleRegistryUnlocked
460
462
{
461
463
if (!self.valid ) {
462
464
return {};
@@ -503,12 +505,7 @@ - (void)_initializeBridge:(std::shared_ptr<JSExecutorFactory>)executorFactory
503
505
executorFactory = std::make_shared<GetDescAdapter>(self, executorFactory);
504
506
#endif
505
507
506
- // This is async, but any calls into JS are blocked by the m_syncReady CV in Instance
507
- _reactInstance->initializeBridge (
508
- std::make_unique<RCTInstanceCallback>(self),
509
- executorFactory,
510
- _jsMessageThread,
511
- [self _buildModuleRegistry ]);
508
+ [self _initializeBridgeLocked: executorFactory];
512
509
513
510
#if RCT_PROFILE
514
511
if (RCTProfileIsProfiling ()) {
@@ -522,6 +519,19 @@ - (void)_initializeBridge:(std::shared_ptr<JSExecutorFactory>)executorFactory
522
519
RCT_PROFILE_END_EVENT (RCTProfileTagAlways, @" " );
523
520
}
524
521
522
+ - (void )_initializeBridgeLocked : (std::shared_ptr<JSExecutorFactory>)executorFactory
523
+ {
524
+ std::lock_guard<std::mutex> guard (_moduleRegistryLock);
525
+
526
+ // This is async, but any calls into JS are blocked by the m_syncReady CV in Instance
527
+ _reactInstance->initializeBridge (
528
+ std::make_unique<RCTInstanceCallback>(self),
529
+ executorFactory,
530
+ _jsMessageThread,
531
+ [self _buildModuleRegistryUnlocked ]);
532
+ _moduleRegistryCreated = YES ;
533
+ }
534
+
525
535
- (NSArray *)configForModuleName : (NSString *)moduleName
526
536
{
527
537
return _moduleDataByName[moduleName].config ;
@@ -682,11 +692,13 @@ - (void)registerExtraModules
682
692
683
693
- (void )registerAdditionalModuleClasses : (NSArray <Class> *)modules
684
694
{
685
- @synchronized (self) {
695
+ std::lock_guard<std::mutex> guard (_moduleRegistryLock);
696
+ if (_moduleRegistryCreated) {
686
697
NSArray <RCTModuleData *> *newModules = [self _initializeModules: modules withDispatchGroup: NULL lazilyDiscovered: YES ];
687
- if (_reactInstance) {
688
- _reactInstance->getModuleRegistry ().registerModules (createNativeModules (newModules, self, _reactInstance));
689
- }
698
+ assert (_reactInstance); // at this point you must have reactInstance as you already called reactInstance->initialzeBridge
699
+ _reactInstance->getModuleRegistry ().registerModules (createNativeModules (newModules, self, _reactInstance));
700
+ } else {
701
+ [self registerModulesForClasses: modules];
690
702
}
691
703
}
692
704
0 commit comments