@@ -155,6 +155,7 @@ @implementation RCTCxxBridge
155
155
{
156
156
BOOL _wasBatchActive;
157
157
BOOL _didInvalidate;
158
+ BOOL _moduleRegistryCreated;
158
159
159
160
NSMutableArray <RCTPendingCall> *_pendingCalls;
160
161
std::atomic<NSInteger > _pendingCount;
@@ -169,6 +170,7 @@ @implementation RCTCxxBridge
169
170
// JS thread management
170
171
NSThread *_jsThread;
171
172
std::shared_ptr<RCTMessageThread> _jsMessageThread;
173
+ std::mutex _moduleRegistryLock;
172
174
173
175
// This is uniquely owned, but weak_ptr is used.
174
176
std::shared_ptr<Instance> _reactInstance;
@@ -209,9 +211,9 @@ - (instancetype)initWithParentBridge:(RCTBridge *)bridge
209
211
*/
210
212
_valid = YES ;
211
213
_loading = YES ;
214
+ _moduleRegistryCreated = NO ;
212
215
_pendingCalls = [NSMutableArray new ];
213
216
_displayLink = [RCTDisplayLink new ];
214
-
215
217
_moduleDataByName = [NSMutableDictionary new ];
216
218
_moduleClassesByID = [NSMutableArray new ];
217
219
_moduleDataByID = [NSMutableArray new ];
@@ -442,7 +444,7 @@ - (BOOL)moduleIsInitialized:(Class)moduleClass
442
444
return _moduleDataByName[RCTBridgeModuleNameForClass (moduleClass)].hasInstance ;
443
445
}
444
446
445
- - (std::shared_ptr<ModuleRegistry>)_buildModuleRegistry
447
+ - (std::shared_ptr<ModuleRegistry>)_buildModuleRegistryUnlocked
446
448
{
447
449
if (!self.valid ) {
448
450
return {};
@@ -489,12 +491,7 @@ - (void)_initializeBridge:(std::shared_ptr<JSExecutorFactory>)executorFactory
489
491
executorFactory = std::make_shared<GetDescAdapter>(self, executorFactory);
490
492
#endif
491
493
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];
498
495
499
496
#if RCT_PROFILE
500
497
if (RCTProfileIsProfiling ()) {
@@ -508,6 +505,19 @@ - (void)_initializeBridge:(std::shared_ptr<JSExecutorFactory>)executorFactory
508
505
RCT_PROFILE_END_EVENT (RCTProfileTagAlways, @" " );
509
506
}
510
507
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
+
511
521
- (NSArray <RCTModuleData *> *)registerModulesForClasses : (NSArray <Class> *)moduleClasses
512
522
{
513
523
RCT_PROFILE_BEGIN_EVENT (RCTProfileTagAlways,
@@ -706,11 +716,13 @@ - (void)registerExtraLazyModules
706
716
707
717
- (void )registerAdditionalModuleClasses : (NSArray <Class> *)modules
708
718
{
709
- @synchronized (self) {
719
+ std::lock_guard<std::mutex> guard (_moduleRegistryLock);
720
+ if (_moduleRegistryCreated) {
710
721
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];
714
726
}
715
727
}
716
728
0 commit comments