History

Fix most of the crash causes on script engine reload/shutdown

Karol Suprynowicz committed 3 years ago

Commit 166f7221 parent d62a40d25 files · +221 −83Browse files

Showing the changes to libraries/script-engine/src/ScriptEngines.cpp (1 of 25 files). Show all

Unified · Split

libraries/script-engine/src/ScriptEngines.cpp+38−29
@@ -21,6 +21,7 @@ · 20 unmodified lines
2121 #include <UserActivityLogger.h>
2222 #include <PathUtils.h>
2323 #include <shared/FileUtils.h>
24+#include <QtConcurrent/QtConcurrent>
2425
2526 #include "ScriptCache.h"
2627 #include "ScriptEngine.h"
@@ -404,42 +405,49 @@ QStringList ScriptEngines::getRunningScripts() { · 377 unmodified lines
404405 }
405406
406407 void ScriptEngines::stopAllScripts(bool restart) {
407− QReadLocker lock(&_scriptManagersHashLock);
408+ QtConcurrent::run([this, restart] {
409+ QHash<QUrl, ScriptManagerPointer> scriptManagersHashCopy;
408410
409− if (_isReloading) {
410− return;
411− }
411+ {
412+ QReadLocker lock(&_scriptManagersHashLock);
413+ scriptManagersHashCopy = _scriptManagersHash;
414+ }
412415
413− for (QHash<QUrl, ScriptManagerPointer>::const_iterator it = _scriptManagersHash.constBegin();
414− it != _scriptManagersHash.constEnd(); it++) {
415− ScriptManagerPointer scriptManager = it.value();
416− // skip already stopped scripts
417− if (scriptManager->isFinished() || scriptManager->isStopping()) {
418− continue;
416+ if (_isReloading) {
417+ return;
419418 }
420419
421− bool isOverrideScript = it.key().toString().compare(this->_defaultScriptsOverride.toString()) == 0;
422− // queue user scripts if restarting
423− if (restart && (scriptManager->isUserLoaded() || isOverrideScript)) {
424− _isReloading = true;
425− ScriptManager::Type type = scriptManager->getType();
420+ for (QHash<QUrl, ScriptManagerPointer>::const_iterator it = scriptManagersHashCopy.constBegin();
421+ it != scriptManagersHashCopy.constEnd(); it++) {
422+ ScriptManagerPointer scriptManager = it.value();
423+ // skip already stopped scripts
424+ if (scriptManager->isFinished() || scriptManager->isStopping()) {
425+ continue;
426+ }
426427
427− connect(scriptManager.get(), &ScriptManager::finished, this, [this, type, isOverrideScript](QString scriptName) {
428− reloadScript(scriptName, !isOverrideScript)->setType(type);
429− });
430− }
428+ bool isOverrideScript = it.key().toString().compare(this->_defaultScriptsOverride.toString()) == 0;
429+ // queue user scripts if restarting
430+ if (restart && (scriptManager->isUserLoaded() || isOverrideScript)) {
431+ _isReloading = true;
432+ ScriptManager::Type type = scriptManager->getType();
431433
432− // stop all scripts
433− scriptManager->stop();
434− }
434+ connect(scriptManager.get(), &ScriptManager::finished, this,
435+ [this, type, isOverrideScript](QString scriptName) {
436+ reloadScript(scriptName, !isOverrideScript)->setType(type);
437+ });
438+ }
435439
436− if (restart) {
437− qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading";
438− QTimer::singleShot(RELOAD_ALL_SCRIPTS_TIMEOUT, this, [&] {
439− _isReloading = false;
440− });
441− emit scriptsReloading();
442− }
440+ // stop all scripts
441+ scriptManager->stop();
442+ scriptManager->waitTillDoneRunning();
443+ }
444+
445+ if (restart) {
446+ qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading";
447+ QTimer::singleShot(RELOAD_ALL_SCRIPTS_TIMEOUT, this, [&] { _isReloading = false; });
448+ emit scriptsReloading();
449+ }
450+ });
443451 }
444452
445453 bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) {
@@ -612,6 +620,7 @@ void ScriptEngines::onScriptFinished(const QString& rawScriptURL, ScriptManagerP · 166 unmodified lines
612620 }
613621 }
614622
623+ // Could this cause deadlocks when script engine invokes a blocking method on main thread?
615624 manager->waitTillDoneRunning();
616625 removeScriptEngine(manager);
617626