Remove JSThreadState from Bridge

Reviewed By: lexs

Differential Revision: D2857580

fb-gh-sync-id: f3172cecb8f4563c70564a50c2e9f42178af347a
This commit is contained in:
Andy Street 2016-01-25 18:35:12 -08:00 committed by facebook-github-bot-7
parent aa0f9c8a8d
commit 91fe9158c9
2 changed files with 20 additions and 84 deletions

View File

@ -13,107 +13,42 @@ using fbsystrace::FbSystraceSection;
namespace facebook {
namespace react {
class JSThreadState {
public:
JSThreadState(const RefPtr<JSExecutorFactory>& 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<JSExecutor> m_jsExecutor;
Bridge::Callback m_callback;
};
Bridge::Bridge(const RefPtr<JSExecutorFactory>& jsExecutorFactory, Callback callback) :
m_callback(callback),
m_callback(std::move(callback)),
m_destroyed(std::shared_ptr<bool>(new bool(false)))
{
auto destroyed = m_destroyed;
auto proxyCallback = [this, destroyed] (std::vector<MethodCall> 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();
}
} }

View File

@ -22,7 +22,6 @@ struct dynamic;
namespace facebook {
namespace react {
class JSThreadState;
class Bridge : public Countable {
public:
typedef std::function<void(std::vector<MethodCall>, bool isEndOfBatch)> Callback;
@ -68,11 +67,11 @@ public:
void handleMemoryPressureCritical();
private:
Callback m_callback;
std::unique_ptr<JSThreadState> 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<bool> m_destroyed;
std::unique_ptr<JSExecutor> m_jsExecutor;
};
} }