Add locks around read/writes of _scriptEnginesHash

This commit is contained in:
Ryan Huffman 2015-12-09 14:48:33 -08:00
parent 4dbfd3bfd9
commit 4bfce768ca
2 changed files with 77 additions and 37 deletions

View file

@ -4259,11 +4259,14 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser
QUrl scriptUrl(scriptFilename);
const QString& scriptURLString = scriptUrl.toString();
{
QReadLocker lock(&_scriptEnginesHashLock);
if (_scriptEnginesHash.contains(scriptURLString) && loadScriptFromEditor
&& !_scriptEnginesHash[scriptURLString]->isFinished()) {
return _scriptEnginesHash[scriptURLString];
}
}
ScriptEngine* scriptEngine = new ScriptEngine(NO_SCRIPT, "", &_controllerScriptingInterface);
scriptEngine->setUserLoaded(isUserLoaded);
@ -4302,7 +4305,11 @@ void Application::reloadScript(const QString& scriptName, bool isUserLoaded) {
void Application::handleScriptEngineLoaded(const QString& scriptFilename) {
ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(sender());
{
QWriteLocker lock(&_scriptEnginesHashLock);
_scriptEnginesHash.insertMulti(scriptFilename, scriptEngine);
}
_runningScriptsWidget->setRunningScripts(getRunningScripts());
UserActivityLogger::getInstance().loadedScript(scriptFilename);
@ -4317,17 +4324,39 @@ void Application::handleScriptLoadError(const QString& scriptFilename) {
QMessageBox::warning(getWindow(), "Error Loading Script", scriptFilename + " failed to load.");
}
void Application::scriptFinished(const QString& scriptName) {
QStringList Application::getRunningScripts() {
QReadLocker lock(&_scriptEnginesHashLock);
return _scriptEnginesHash.keys();
}
ScriptEngine* Application::getScriptEngine(const QString& scriptHash) {
QReadLocker lock(&_scriptEnginesHashLock);
return _scriptEnginesHash.value(scriptHash, nullptr);
}
void Application::scriptFinished(const QString& scriptName, ScriptEngine* engine) {
bool removed = false;
{
QWriteLocker lock(&_scriptEnginesHashLock);
const QString& scriptURLString = QUrl(scriptName).toString();
QHash<QString, ScriptEngine*>::iterator it = _scriptEnginesHash.find(scriptURLString);
if (it != _scriptEnginesHash.end()) {
for (auto it = _scriptEnginesHash.find(scriptURLString); it != _scriptEnginesHash.end(); ++it) {
if (it.value() == engine) {
_scriptEnginesHash.erase(it);
removed = true;
break;
}
}
}
postLambdaEvent([this, scriptName]() {
_runningScriptsWidget->scriptStopped(scriptName);
_runningScriptsWidget->setRunningScripts(getRunningScripts());
}
});
}
void Application::stopAllScripts(bool restart) {
{
QReadLocker lock(&_scriptEnginesHashLock);
if (restart) {
// Delete all running scripts from cache so that they are re-downloaded when they are restarted
auto scriptCache = DependencyManager::get<ScriptCache>();
@ -4346,27 +4375,36 @@ void Application::stopAllScripts(bool restart) {
continue;
}
if (restart && it.value()->isUserLoaded()) {
connect(it.value(), SIGNAL(finished(const QString&)), SLOT(reloadScript(const QString&)));
connect(it.value(), &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) {
reloadScript(scriptName);
});
}
it.value()->stop();
QMetaObject::invokeMethod(it.value(), "stop");
//it.value()->stop();
qCDebug(interfaceapp) << "stopping script..." << it.key();
}
}
getMyAvatar()->clearScriptableSettings();
}
bool Application::stopScript(const QString& scriptHash, bool restart) {
bool stoppedScript = false;
{
QReadLocker lock(&_scriptEnginesHashLock);
if (_scriptEnginesHash.contains(scriptHash)) {
ScriptEngine* scriptEngine = _scriptEnginesHash[scriptHash];
if (restart) {
auto scriptCache = DependencyManager::get<ScriptCache>();
scriptCache->deleteScript(QUrl(scriptHash));
connect(scriptEngine, SIGNAL(finished(const QString&)), SLOT(reloadScript(const QString&)));
connect(scriptEngine, &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) {
reloadScript(scriptName);
});
}
scriptEngine->stop();
stoppedScript = true;
qCDebug(interfaceapp) << "stopping script..." << scriptHash;
}
}
if (_scriptEnginesHash.empty()) {
getMyAvatar()->clearScriptableSettings();
}
@ -4384,6 +4422,7 @@ void Application::reloadOneScript(const QString& scriptName) {
}
void Application::loadDefaultScripts() {
QReadLocker lock(&_scriptEnginesHashLock);
if (!_scriptEnginesHash.contains(DEFAULT_SCRIPTS_JS_URL)) {
loadScript(DEFAULT_SCRIPTS_JS_URL);
}

View file

@ -505,6 +505,7 @@ private:
TouchEvent _lastTouchEvent;
QReadWriteLock _scriptEnginesHashLock;
RunningScriptsWidget* _runningScriptsWidget;
QHash<QString, ScriptEngine*> _scriptEnginesHash;
bool _runningScriptsWidgetWasVisible;