Protect against JS module call race condition while initializing react instance

Summary: Fixes a race condition where JS module functions could be called in between ##initializeWithInstance(catalystInstance);## and ##CatalystInstance#runJSBundle##, before the BatchedBridge in JS was set up. We now guarantee that all JS module methods that are called after `ReactContext#hasActiveCatalystInstance()` returns true will have the batched bridge created and ready to use.

Reviewed By: lexs

Differential Revision: D3258651

fb-gh-sync-id: 66e66533cc86d185e7c865376d6a5cdc6520d2d4
fbshipit-source-id: 66e66533cc86d185e7c865376d6a5cdc6520d2d4
This commit is contained in:
Andy Street
2016-05-05 05:51:45 -07:00
committed by Facebook Github Bot 0
parent a69b883537
commit a1ba0918ab
4 changed files with 72 additions and 40 deletions

View File

@@ -140,33 +140,24 @@ public class CatalystInstanceImpl implements CatalystInstance {
@Override
public void runJSBundle() {
mReactQueueConfiguration.getJSQueueThread().assertIsOnThread();
Assertions.assertCondition(!mJSBundleHasLoaded, "JS bundle was already loaded!");
incrementPendingJSCalls();
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "loadJSScript");
try {
mJSBundleHasLoaded = mReactQueueConfiguration.getJSQueueThread().callOnQueue(
new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Assertions.assertCondition(!mJSBundleHasLoaded, "JS bundle was already loaded!");
mJSBundleLoader.loadScript(mBridge);
incrementPendingJSCalls();
Systrace.beginSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "loadJSScript");
try {
mJSBundleLoader.loadScript(mBridge);
// This is registered after JS starts since it makes a JS call
Systrace.registerListener(mTraceListener);
} catch (JSExecutionException e) {
mNativeModuleCallExceptionHandler.handleException(e);
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
return true;
}
}).get();
} catch (Exception t) {
throw new RuntimeException(t);
// This is registered after JS starts since it makes a JS call
Systrace.registerListener(mTraceListener);
} catch (JSExecutionException e) {
mNativeModuleCallExceptionHandler.handleException(e);
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE);
}
mJSBundleHasLoaded = true;
}
@Override