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;