From 4e862941cb9307ebbcfb88c1a14e463c62a854c4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 19 May 2016 14:51:56 -0700 Subject: [PATCH 1/8] fix a race when restarting scripts -- avoid the old not-yet-stopped script from being considered the restart script --- libraries/script-engine/src/ScriptEngine.h | 3 +++ libraries/script-engine/src/ScriptEngines.cpp | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 80978e4527..b576e2a37f 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -146,6 +146,8 @@ public: bool isFinished() const { return _isFinished; } // used by Application and ScriptWidget bool isRunning() const { return _isRunning; } // used by ScriptWidget + bool isStopping() const { return _isStopping; } + void flagAsStopping() { _isStopping = true; } bool isDebuggable() const { return _debuggable; } @@ -189,6 +191,7 @@ protected: QString _parentURL; std::atomic _isFinished { false }; std::atomic _isRunning { false }; + std::atomic _isStopping { false }; int _evaluatesPending { 0 }; bool _isInitialized { false }; QHash _timerFunctionMap; diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 70eb055d22..5a2beb901d 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -351,6 +351,7 @@ void ScriptEngines::stopAllScripts(bool restart) { reloadScript(scriptName); }); } + it.value()->flagAsStopping(); QMetaObject::invokeMethod(it.value(), "stop"); //it.value()->stop(); qCDebug(scriptengine) << "stopping script..." << it.key(); @@ -369,6 +370,7 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { if (_scriptEnginesHash.contains(scriptURL)) { ScriptEngine* scriptEngine = _scriptEnginesHash[scriptURL]; if (restart) { + scriptEngine->flagAsStopping(); auto scriptCache = DependencyManager::get(); scriptCache->deleteScript(scriptURL); connect(scriptEngine, &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) { @@ -454,7 +456,7 @@ ScriptEngine* ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { QReadLocker lock(&_scriptEnginesHashLock); const QUrl scriptURL = normalizeScriptURL(rawScriptURL); auto it = _scriptEnginesHash.find(scriptURL); - if (it != _scriptEnginesHash.end()) { + if (it != _scriptEnginesHash.end() && !it.value()->isStopping()) { result = it.value(); } } From 9ad488ba7b1d1ce3709fbbba79ad8a2ef5e04821 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 19 May 2016 16:08:44 -0700 Subject: [PATCH 2/8] fix method name to match coding standard --- libraries/script-engine/src/ScriptEngine.h | 2 +- libraries/script-engine/src/ScriptEngines.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index b576e2a37f..512e79fb95 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -147,7 +147,7 @@ public: bool isFinished() const { return _isFinished; } // used by Application and ScriptWidget bool isRunning() const { return _isRunning; } // used by ScriptWidget bool isStopping() const { return _isStopping; } - void flagAsStopping() { _isStopping = true; } + void setIsStopping() { _isStopping = true; } bool isDebuggable() const { return _debuggable; } diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 5a2beb901d..65e08938b3 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -351,7 +351,7 @@ void ScriptEngines::stopAllScripts(bool restart) { reloadScript(scriptName); }); } - it.value()->flagAsStopping(); + it.value()->setIsStopping(); QMetaObject::invokeMethod(it.value(), "stop"); //it.value()->stop(); qCDebug(scriptengine) << "stopping script..." << it.key(); @@ -370,7 +370,7 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { if (_scriptEnginesHash.contains(scriptURL)) { ScriptEngine* scriptEngine = _scriptEnginesHash[scriptURL]; if (restart) { - scriptEngine->flagAsStopping(); + scriptEngine->setIsStopping(); auto scriptCache = DependencyManager::get(); scriptCache->deleteScript(scriptURL); connect(scriptEngine, &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) { From 3f5ed4bef8603eae9bb4a08e9912953057244c1d Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 19 May 2016 16:15:33 -0700 Subject: [PATCH 3/8] set isStopping on other calls to stop --- libraries/script-engine/src/ScriptEngines.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 65e08938b3..8b57487db0 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -160,6 +160,7 @@ void ScriptEngines::shutdownScripting() { scriptEngine->disconnect(this); // Gracefully stop the engine's scripting thread + scriptEngine->setIsStopping(); scriptEngine->stop(); // We need to wait for the engine to be done running before we proceed, because we don't @@ -353,7 +354,6 @@ void ScriptEngines::stopAllScripts(bool restart) { } it.value()->setIsStopping(); QMetaObject::invokeMethod(it.value(), "stop"); - //it.value()->stop(); qCDebug(scriptengine) << "stopping script..." << it.key(); } } @@ -370,13 +370,13 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { if (_scriptEnginesHash.contains(scriptURL)) { ScriptEngine* scriptEngine = _scriptEnginesHash[scriptURL]; if (restart) { - scriptEngine->setIsStopping(); auto scriptCache = DependencyManager::get(); scriptCache->deleteScript(scriptURL); connect(scriptEngine, &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) { reloadScript(scriptName); }); } + scriptEngine->setIsStopping(); scriptEngine->stop(); stoppedScript = true; qCDebug(scriptengine) << "stopping script..." << scriptURL; From aa58cad93e51ef078a3d6230c15d99b94cf5f86f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 20 May 2016 09:54:54 -0700 Subject: [PATCH 4/8] code review --- libraries/script-engine/src/ScriptEngine.cpp | 7 +++++++ libraries/script-engine/src/ScriptEngine.h | 4 +++- libraries/script-engine/src/ScriptEngines.cpp | 5 +---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 67b87ae5e0..d8e0397347 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -938,6 +938,13 @@ void ScriptEngine::stopAllTimersForEntityScript(const EntityItemID& entityID) { } void ScriptEngine::stop() { + _isStopping = true; // this can be done on any thread + + // marshal us over to the correct thread + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "stop"); + return; + } if (!_isFinished) { _isFinished = true; emit runningStateChanged(); diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 512e79fb95..6af6aef338 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -84,7 +84,7 @@ public: //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts - Q_INVOKABLE void stop(); + Q_INVOKABLE void stop(); // this can be called from any thread // Stop any evaluating scripts and wait for the scripting thread to finish. void waitTillDoneRunning(); @@ -146,6 +146,8 @@ public: bool isFinished() const { return _isFinished; } // used by Application and ScriptWidget bool isRunning() const { return _isRunning; } // used by ScriptWidget + + // these are used by code in ScriptEngines.cpp during the "reload all" operation bool isStopping() const { return _isStopping; } void setIsStopping() { _isStopping = true; } diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 8b57487db0..0d1f0de3c9 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -160,7 +160,6 @@ void ScriptEngines::shutdownScripting() { scriptEngine->disconnect(this); // Gracefully stop the engine's scripting thread - scriptEngine->setIsStopping(); scriptEngine->stop(); // We need to wait for the engine to be done running before we proceed, because we don't @@ -352,8 +351,7 @@ void ScriptEngines::stopAllScripts(bool restart) { reloadScript(scriptName); }); } - it.value()->setIsStopping(); - QMetaObject::invokeMethod(it.value(), "stop"); + it.value()->stop(); qCDebug(scriptengine) << "stopping script..." << it.key(); } } @@ -376,7 +374,6 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { reloadScript(scriptName); }); } - scriptEngine->setIsStopping(); scriptEngine->stop(); stoppedScript = true; qCDebug(scriptengine) << "stopping script..." << scriptURL; From 35065ab05ecb7384907f47a6360fda08c187cfd1 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 20 May 2016 10:12:38 -0700 Subject: [PATCH 5/8] remove unused setter --- libraries/script-engine/src/ScriptEngine.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 6af6aef338..2222503781 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -149,7 +149,6 @@ public: // these are used by code in ScriptEngines.cpp during the "reload all" operation bool isStopping() const { return _isStopping; } - void setIsStopping() { _isStopping = true; } bool isDebuggable() const { return _debuggable; } From 1ef0f8055bcd0f9b0a981bd24f16f6d6b8cb67fc Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 20 May 2016 10:12:59 -0700 Subject: [PATCH 6/8] fix grammar in comment --- libraries/script-engine/src/ScriptEngine.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 2222503781..ef7e075021 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -147,7 +147,7 @@ public: bool isFinished() const { return _isFinished; } // used by Application and ScriptWidget bool isRunning() const { return _isRunning; } // used by ScriptWidget - // these are used by code in ScriptEngines.cpp during the "reload all" operation + // this is used by code in ScriptEngines.cpp during the "reload all" operation bool isStopping() const { return _isStopping; } bool isDebuggable() const { return _debuggable; } From b0ce65ec0197e2c7154ca7f21573337638235063 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 May 2016 11:42:06 -0700 Subject: [PATCH 7/8] trying to mimic previous behavior more closely --- assignment-client/src/Agent.cpp | 2 +- .../src/EntityTreeRenderer.cpp | 2 +- libraries/script-engine/src/ScriptEngine.cpp | 12 ++++--- libraries/script-engine/src/ScriptEngine.h | 2 +- libraries/script-engine/src/ScriptEngines.cpp | 31 +++++++++++-------- libraries/script-engine/src/ScriptEngines.h | 1 + 6 files changed, 29 insertions(+), 21 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 65e193dec6..327f6de695 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -476,7 +476,7 @@ void Agent::aboutToFinish() { setIsAvatar(false);// will stop timers for sending identity packets if (_scriptEngine) { - _scriptEngine->stop(); + _scriptEngine->stop(false); } // our entity tree is going to go away so tell that to the EntityScriptingInterface diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 56f6438e70..bc3c6b2441 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -114,7 +114,7 @@ void EntityTreeRenderer::clear() { // Unload and stop the engine here (instead of in its deleter) to // avoid marshalling unload signals back to this thread _entitiesScriptEngine->unloadAllEntityScripts(); - _entitiesScriptEngine->stop(); + _entitiesScriptEngine->stop(false); } if (_wantScripts && !_shuttingDown) { diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index e7938ac5a0..61ab8c0c63 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -290,7 +290,7 @@ void ScriptEngine::waitTillDoneRunning() { assert(workerThread != QThread::currentThread()); // Engine should be stopped already, but be defensive - stop(); + stop(false); auto startedWaiting = usecTimestampNow(); while (workerThread->isRunning()) { @@ -941,13 +941,15 @@ void ScriptEngine::stopAllTimersForEntityScript(const EntityItemID& entityID) { } -void ScriptEngine::stop() { +void ScriptEngine::stop(bool marshal) { _isStopping = true; // this can be done on any thread // marshal us over to the correct thread - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "stop"); - return; + if (marshal) { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "stop"); + return; + } } if (!_isFinished) { _isFinished = true; diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index ef7e075021..4d39365626 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -84,7 +84,7 @@ public: //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts - Q_INVOKABLE void stop(); // this can be called from any thread + Q_INVOKABLE void stop(bool marshal); // this can be called from any thread // Stop any evaluating scripts and wait for the scripting thread to finish. void waitTillDoneRunning(); diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 5e5b8bfde9..6575a12c99 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -160,7 +160,7 @@ void ScriptEngines::shutdownScripting() { scriptEngine->disconnect(this); // Gracefully stop the engine's scripting thread - scriptEngine->stop(); + scriptEngine->stop(false); // We need to wait for the engine to be done running before we proceed, because we don't // want any of the scripts final "scriptEnding()" or pending "update()" methods from accessing @@ -359,7 +359,10 @@ QStringList ScriptEngines::getRunningScripts() { QList urls = _scriptEnginesHash.keys(); QStringList result; for (auto url : urls) { - result.append(url.toString()); + ScriptEngine* engine = getScriptEngineInternal(url); + if (engine) { + result.append(url.toString()); + } } return result; } @@ -388,7 +391,7 @@ void ScriptEngines::stopAllScripts(bool restart) { reloadScript(scriptName); }); } - it.value()->stop(); + it.value()->stop(true); qCDebug(scriptengine) << "stopping script..." << it.key(); } } @@ -411,7 +414,7 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { reloadScript(scriptName); }); } - scriptEngine->stop(); + scriptEngine->stop(false); stoppedScript = true; qCDebug(scriptengine) << "stopping script..." << scriptURL; } @@ -459,7 +462,7 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL } auto scriptEngine = getScriptEngine(scriptUrl); - if (scriptEngine) { + if (scriptEngine && !scriptEngine->isStopping()) { return scriptEngine; } @@ -484,19 +487,21 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL return scriptEngine; } -ScriptEngine* ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { +ScriptEngine* ScriptEngines::getScriptEngineInternal(const QUrl& rawScriptURL) { ScriptEngine* result = nullptr; - { - QReadLocker lock(&_scriptEnginesHashLock); - const QUrl scriptURL = normalizeScriptURL(rawScriptURL); - auto it = _scriptEnginesHash.find(scriptURL); - if (it != _scriptEnginesHash.end() && !it.value()->isStopping()) { - result = it.value(); - } + const QUrl scriptURL = normalizeScriptURL(rawScriptURL); + auto it = _scriptEnginesHash.find(scriptURL); + if (it != _scriptEnginesHash.end()) { + result = it.value(); } return result; } +ScriptEngine* ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { + QReadLocker lock(&_scriptEnginesHashLock); + return getScriptEngineInternal(rawScriptURL); +} + // FIXME - change to new version of ScriptCache loading notification void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) { UserActivityLogger::getInstance().loadedScript(rawScriptURL); diff --git a/libraries/script-engine/src/ScriptEngines.h b/libraries/script-engine/src/ScriptEngines.h index a9c273b2a7..6d887ce95f 100644 --- a/libraries/script-engine/src/ScriptEngines.h +++ b/libraries/script-engine/src/ScriptEngines.h @@ -87,6 +87,7 @@ protected: void onScriptEngineLoaded(const QString& scriptFilename); void onScriptEngineError(const QString& scriptFilename); void launchScriptEngine(ScriptEngine* engine); + ScriptEngine* getScriptEngineInternal(const QUrl& rawScriptURL); QReadWriteLock _scriptEnginesHashLock; QHash _scriptEnginesHash; From 49769f7d2969626c515ff554ef9aa1ed716081e6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 25 May 2016 13:39:13 -0700 Subject: [PATCH 8/8] trying again -- frantic clicking on reload no longer appears to wedge things --- assignment-client/src/Agent.cpp | 2 +- .../src/EntityTreeRenderer.cpp | 2 +- libraries/script-engine/src/ScriptEngine.cpp | 9 ++---- libraries/script-engine/src/ScriptEngine.h | 2 +- libraries/script-engine/src/ScriptEngines.cpp | 29 ++++++++----------- libraries/script-engine/src/ScriptEngines.h | 1 - 6 files changed, 18 insertions(+), 27 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 327f6de695..65e193dec6 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -476,7 +476,7 @@ void Agent::aboutToFinish() { setIsAvatar(false);// will stop timers for sending identity packets if (_scriptEngine) { - _scriptEngine->stop(false); + _scriptEngine->stop(); } // our entity tree is going to go away so tell that to the EntityScriptingInterface diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index bc3c6b2441..56f6438e70 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -114,7 +114,7 @@ void EntityTreeRenderer::clear() { // Unload and stop the engine here (instead of in its deleter) to // avoid marshalling unload signals back to this thread _entitiesScriptEngine->unloadAllEntityScripts(); - _entitiesScriptEngine->stop(false); + _entitiesScriptEngine->stop(); } if (_wantScripts && !_shuttingDown) { diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 61ab8c0c63..a5e3be8a43 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -290,7 +290,7 @@ void ScriptEngine::waitTillDoneRunning() { assert(workerThread != QThread::currentThread()); // Engine should be stopped already, but be defensive - stop(false); + stop(); auto startedWaiting = usecTimestampNow(); while (workerThread->isRunning()) { @@ -944,12 +944,9 @@ void ScriptEngine::stopAllTimersForEntityScript(const EntityItemID& entityID) { void ScriptEngine::stop(bool marshal) { _isStopping = true; // this can be done on any thread - // marshal us over to the correct thread if (marshal) { - if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "stop"); - return; - } + QMetaObject::invokeMethod(this, "stop"); + return; } if (!_isFinished) { _isFinished = true; diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 4d39365626..1077dce686 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -84,7 +84,7 @@ public: //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE - this is intended to be a public interface for Agent scripts, and local scripts, but not for EntityScripts - Q_INVOKABLE void stop(bool marshal); // this can be called from any thread + Q_INVOKABLE void stop(bool marshal = false); // Stop any evaluating scripts and wait for the scripting thread to finish. void waitTillDoneRunning(); diff --git a/libraries/script-engine/src/ScriptEngines.cpp b/libraries/script-engine/src/ScriptEngines.cpp index 6575a12c99..29c223f4b3 100644 --- a/libraries/script-engine/src/ScriptEngines.cpp +++ b/libraries/script-engine/src/ScriptEngines.cpp @@ -160,7 +160,7 @@ void ScriptEngines::shutdownScripting() { scriptEngine->disconnect(this); // Gracefully stop the engine's scripting thread - scriptEngine->stop(false); + scriptEngine->stop(); // We need to wait for the engine to be done running before we proceed, because we don't // want any of the scripts final "scriptEnding()" or pending "update()" methods from accessing @@ -359,10 +359,7 @@ QStringList ScriptEngines::getRunningScripts() { QList urls = _scriptEnginesHash.keys(); QStringList result; for (auto url : urls) { - ScriptEngine* engine = getScriptEngineInternal(url); - if (engine) { - result.append(url.toString()); - } + result.append(url.toString()); } return result; } @@ -383,7 +380,7 @@ void ScriptEngines::stopAllScripts(bool restart) { // Stop and possibly restart all currently running scripts for (QHash::const_iterator it = _scriptEnginesHash.constBegin(); it != _scriptEnginesHash.constEnd(); it++) { - if (it.value()->isFinished()) { + if (it.value()->isFinished() || it.value()->isStopping()) { continue; } if (restart && it.value()->isUserLoaded()) { @@ -414,7 +411,7 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { reloadScript(scriptName); }); } - scriptEngine->stop(false); + scriptEngine->stop(); stoppedScript = true; qCDebug(scriptengine) << "stopping script..." << scriptURL; } @@ -487,21 +484,19 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL return scriptEngine; } -ScriptEngine* ScriptEngines::getScriptEngineInternal(const QUrl& rawScriptURL) { +ScriptEngine* ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { ScriptEngine* result = nullptr; - const QUrl scriptURL = normalizeScriptURL(rawScriptURL); - auto it = _scriptEnginesHash.find(scriptURL); - if (it != _scriptEnginesHash.end()) { - result = it.value(); + { + QReadLocker lock(&_scriptEnginesHashLock); + const QUrl scriptURL = normalizeScriptURL(rawScriptURL); + auto it = _scriptEnginesHash.find(scriptURL); + if (it != _scriptEnginesHash.end()) { + result = it.value(); + } } return result; } -ScriptEngine* ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { - QReadLocker lock(&_scriptEnginesHashLock); - return getScriptEngineInternal(rawScriptURL); -} - // FIXME - change to new version of ScriptCache loading notification void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) { UserActivityLogger::getInstance().loadedScript(rawScriptURL); diff --git a/libraries/script-engine/src/ScriptEngines.h b/libraries/script-engine/src/ScriptEngines.h index 6d887ce95f..a9c273b2a7 100644 --- a/libraries/script-engine/src/ScriptEngines.h +++ b/libraries/script-engine/src/ScriptEngines.h @@ -87,7 +87,6 @@ protected: void onScriptEngineLoaded(const QString& scriptFilename); void onScriptEngineError(const QString& scriptFilename); void launchScriptEngine(ScriptEngine* engine); - ScriptEngine* getScriptEngineInternal(const QUrl& rawScriptURL); QReadWriteLock _scriptEnginesHashLock; QHash _scriptEnginesHash;