diff --git a/ReactAndroid/src/main/jni/react/Bridge.cpp b/ReactAndroid/src/main/jni/react/Bridge.cpp index a06871c1e..0e6982af5 100644 --- a/ReactAndroid/src/main/jni/react/Bridge.cpp +++ b/ReactAndroid/src/main/jni/react/Bridge.cpp @@ -13,107 +13,42 @@ using fbsystrace::FbSystraceSection; namespace facebook { namespace react { -class JSThreadState { -public: - JSThreadState(const RefPtr& jsExecutorFactory, Bridge::Callback&& callback) : - m_callback(callback) - { - m_jsExecutor = jsExecutorFactory->createJSExecutor([this, callback] (std::string queueJSON, bool isEndOfBatch) { - m_callback(parseMethodCalls(queueJSON), false /* = isEndOfBatch */); - }); - } - - void executeApplicationScript(const std::string& script, const std::string& sourceURL) { - m_jsExecutor->executeApplicationScript(script, sourceURL); - } - - void loadApplicationUnbundle( - JSModulesUnbundle&& unbundle, - const std::string& startupCode, - const std::string& sourceURL) { - m_jsExecutor->loadApplicationUnbundle(std::move(unbundle), startupCode, sourceURL); - } - - void flush() { - auto returnedJSON = m_jsExecutor->flush(); - m_callback(parseMethodCalls(returnedJSON), true /* = isEndOfBatch */); - } - - void callFunction(const double moduleId, const double methodId, const folly::dynamic& arguments) { - auto returnedJSON = m_jsExecutor->callFunction(moduleId, methodId, arguments); - m_callback(parseMethodCalls(returnedJSON), true /* = isEndOfBatch */); - } - - void invokeCallback(const double callbackId, const folly::dynamic& arguments) { - auto returnedJSON = m_jsExecutor->invokeCallback(callbackId, arguments); - m_callback(parseMethodCalls(returnedJSON), true /* = isEndOfBatch */); - } - - void setGlobalVariable(const std::string& propName, const std::string& jsonValue) { - m_jsExecutor->setGlobalVariable(propName, jsonValue); - } - - bool supportsProfiling() { - return m_jsExecutor->supportsProfiling(); - } - - void startProfiler(const std::string& title) { - m_jsExecutor->startProfiler(title); - } - - void stopProfiler(const std::string& title, const std::string& filename) { - m_jsExecutor->stopProfiler(title, filename); - } - - void handleMemoryPressureModerate() { - m_jsExecutor->handleMemoryPressureModerate(); - } - - void handleMemoryPressureCritical() { - m_jsExecutor->handleMemoryPressureCritical(); - } - -private: - std::unique_ptr m_jsExecutor; - Bridge::Callback m_callback; -}; - Bridge::Bridge(const RefPtr& jsExecutorFactory, Callback callback) : - m_callback(callback), + m_callback(std::move(callback)), m_destroyed(std::shared_ptr(new bool(false))) { auto destroyed = m_destroyed; - auto proxyCallback = [this, destroyed] (std::vector calls, bool isEndOfBatch) { + m_jsExecutor = jsExecutorFactory->createJSExecutor([this, destroyed] (std::string queueJSON, bool isEndOfBatch) { if (*destroyed) { return; } - m_callback(std::move(calls), isEndOfBatch); - }; - m_threadState.reset(new JSThreadState(jsExecutorFactory, std::move(proxyCallback))); + m_callback(parseMethodCalls(queueJSON), isEndOfBatch); + }); } // This must be called on the same thread on which the constructor was called. Bridge::~Bridge() { *m_destroyed = true; - m_threadState.reset(); + m_jsExecutor.reset(); } void Bridge::executeApplicationScript(const std::string& script, const std::string& sourceURL) { - m_threadState->executeApplicationScript(script, sourceURL); + m_jsExecutor->executeApplicationScript(script, sourceURL); } void Bridge::loadApplicationUnbundle( JSModulesUnbundle&& unbundle, const std::string& startupCode, const std::string& sourceURL) { - m_threadState->loadApplicationUnbundle(std::move(unbundle), startupCode, sourceURL); + m_jsExecutor->loadApplicationUnbundle(std::move(unbundle), startupCode, sourceURL); } void Bridge::flush() { if (*m_destroyed) { return; } - m_threadState->flush(); + auto returnedJSON = m_jsExecutor->flush(); + m_callback(parseMethodCalls(returnedJSON), true /* = isEndOfBatch */); } void Bridge::callFunction(const double moduleId, const double methodId, const folly::dynamic& arguments) { @@ -123,7 +58,8 @@ void Bridge::callFunction(const double moduleId, const double methodId, const fo #ifdef WITH_FBSYSTRACE FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "Bridge.callFunction"); #endif - m_threadState->callFunction(moduleId, methodId, arguments); + auto returnedJSON = m_jsExecutor->callFunction(moduleId, methodId, arguments); + m_callback(parseMethodCalls(returnedJSON), true /* = isEndOfBatch */); } void Bridge::invokeCallback(const double callbackId, const folly::dynamic& arguments) { @@ -133,31 +69,32 @@ void Bridge::invokeCallback(const double callbackId, const folly::dynamic& argum #ifdef WITH_FBSYSTRACE FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "Bridge.invokeCallback"); #endif - m_threadState->invokeCallback(callbackId, arguments); + auto returnedJSON = m_jsExecutor->invokeCallback(callbackId, arguments); + m_callback(parseMethodCalls(returnedJSON), true /* = isEndOfBatch */); } void Bridge::setGlobalVariable(const std::string& propName, const std::string& jsonValue) { - m_threadState->setGlobalVariable(propName, jsonValue); + m_jsExecutor->setGlobalVariable(propName, jsonValue); } bool Bridge::supportsProfiling() { - return m_threadState->supportsProfiling(); + return m_jsExecutor->supportsProfiling(); } void Bridge::startProfiler(const std::string& title) { - m_threadState->startProfiler(title); + m_jsExecutor->startProfiler(title); } void Bridge::stopProfiler(const std::string& title, const std::string& filename) { - m_threadState->stopProfiler(title, filename); + m_jsExecutor->stopProfiler(title, filename); } void Bridge::handleMemoryPressureModerate() { - m_threadState->handleMemoryPressureModerate(); + m_jsExecutor->handleMemoryPressureModerate(); } void Bridge::handleMemoryPressureCritical() { - m_threadState->handleMemoryPressureCritical(); + m_jsExecutor->handleMemoryPressureCritical(); } } } diff --git a/ReactAndroid/src/main/jni/react/Bridge.h b/ReactAndroid/src/main/jni/react/Bridge.h index c8f0be4c4..33f7a4a99 100644 --- a/ReactAndroid/src/main/jni/react/Bridge.h +++ b/ReactAndroid/src/main/jni/react/Bridge.h @@ -22,7 +22,6 @@ struct dynamic; namespace facebook { namespace react { -class JSThreadState; class Bridge : public Countable { public: typedef std::function, bool isEndOfBatch)> Callback; @@ -68,11 +67,11 @@ public: void handleMemoryPressureCritical(); private: Callback m_callback; - std::unique_ptr m_threadState; // This is used to avoid a race condition where a proxyCallback gets queued after ~Bridge(), // on the same thread. In that case, the callback will try to run the task on m_callback which // will have been destroyed within ~Bridge(), thus causing a SIGSEGV. std::shared_ptr m_destroyed; + std::unique_ptr m_jsExecutor; }; } }