Permalink
Browse files

Allow RCTModuleData to explicitly opt out from performing its set up …

…on the main queue

Reviewed By: javache

Differential Revision: D5328995

fbshipit-source-id: 6ef6c260a01ee3b088665b13587ff25b84b51771
  • Loading branch information...
fromcelticpark authored and facebook-github-bot committed Jun 28, 2017
1 parent 937568b commit 2f193b9bc19906cdb7dfb3f0d6dea434590d4579
Showing with 25 additions and 8 deletions.
  1. +13 −0 React/Base/RCTModuleData.h
  2. +12 −8 React/Base/RCTModuleData.mm
View
@@ -58,14 +58,27 @@ typedef id<RCTBridgeModule>(^RCTBridgeModuleProvider)(void);
/**
* Returns YES if module instance must be created on the main thread.
* May be overriden by "allowOffMainQueueRegistration".
*/
@property (nonatomic, assign, readonly) BOOL requiresMainQueueSetup;
/**
* Returns YES if module has constants to export.
* May be overriden by "allowOffMainQueueRegistration".
*/
@property (nonatomic, assign, readonly) BOOL hasConstantsToExport;
/**
* If set to YES, it will force both setup and constants export process
* to explicitly happen off the main queue.
* Overrides "requiresMainQueueSetup" & "hasConstantsToExport"
* Defaults to NO.
*
* @experimental
*/
@property (nonatomic, assign) BOOL allowOffMainQueueRegistration;
/**
* Returns the current module instance. Note that this will init the instance
* if it has not already been created. To check if the module instance exists
@@ -101,7 +101,7 @@ - (void)setUpInstanceAndBridge
if (!_setupComplete && _bridge.valid) {
if (!_instance) {
if (RCT_DEBUG && _requiresMainQueueSetup) {
if (RCT_DEBUG && _requiresMainQueueSetup && !_allowOffMainQueueRegistration) {
RCTAssertMainQueue();
}
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setUpInstanceAndBridge] Create module", nil);
@@ -222,7 +222,7 @@ - (BOOL)hasInstance
{
if (!_setupComplete) {
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, ([NSString stringWithFormat:@"[RCTModuleData instanceForClass:%@]", _moduleClass]), nil);
if (_requiresMainQueueSetup) {
if (_requiresMainQueueSetup && !_allowOffMainQueueRegistration) {
// The chances of deadlock here are low, because module init very rarely
// calls out to other threads, however we can't control when a module might
// get accessed by client code during bridge setup, and a very low risk of
@@ -295,13 +295,17 @@ - (void)gatherConstants
if (_hasConstantsToExport && !_constantsToExport) {
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, ([NSString stringWithFormat:@"[RCTModuleData gatherConstants] %@", _moduleClass]), nil);
(void)[self instance];
if (!RCTIsMainQueue()) {
RCTLogWarn(@"Required dispatch_sync to load constants for %@. This may lead to deadlocks", _moduleClass);
}
if (_allowOffMainQueueRegistration) {
_constantsToExport = [_instance constantsToExport] ?: @{};
} else {
if (!RCTIsMainQueue()) {
RCTLogWarn(@"Required dispatch_sync to load constants for %@. This may lead to deadlocks", _moduleClass);
}
RCTUnsafeExecuteOnMainQueueSync(^{
self->_constantsToExport = [self->_instance constantsToExport] ?: @{};
});
RCTUnsafeExecuteOnMainQueueSync(^{
self->_constantsToExport = [self->_instance constantsToExport] ?: @{};
});
}
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
}
}

0 comments on commit 2f193b9

Please sign in to comment.