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
21#include <UserActivityLogger.h>21#include <UserActivityLogger.h>
22#include <PathUtils.h>22#include <PathUtils.h>
23#include <shared/FileUtils.h>23#include <shared/FileUtils.h>
24#include <QtConcurrent/QtConcurrent>
24 25
25#include "ScriptCache.h"26#include "ScriptCache.h"
26#include "ScriptEngine.h"27#include "ScriptEngine.h"
@@ -404,42 +405,49 @@ QStringList ScriptEngines::getRunningScripts() { · 377 unmodified lines
404}405}
405 406
406void ScriptEngines::stopAllScripts(bool restart) {407void ScriptEngines::stopAllScripts(bool restart) {
407 QReadLocker lock(&_scriptManagersHashLock);408 QtConcurrent::run([this, restart] {
409 QHash<QUrl, ScriptManagerPointer> scriptManagersHashCopy;
408 410
409 if (_isReloading) {411 {
410 return;412 QReadLocker lock(&_scriptManagersHashLock);
411 }413 scriptManagersHashCopy = _scriptManagersHash;
414 }
412 415
413 for (QHash<QUrl, ScriptManagerPointer>::const_iterator it = _scriptManagersHash.constBegin();416 if (_isReloading) {
414 it != _scriptManagersHash.constEnd(); it++) {417 return;
415 ScriptManagerPointer scriptManager = it.value();
416 // skip already stopped scripts
417 if (scriptManager->isFinished() || scriptManager->isStopping()) {
418 continue;
419 }418 }
420 419
421 bool isOverrideScript = it.key().toString().compare(this->_defaultScriptsOverride.toString()) == 0;420 for (QHash<QUrl, ScriptManagerPointer>::const_iterator it = scriptManagersHashCopy.constBegin();
422 // queue user scripts if restarting421 it != scriptManagersHashCopy.constEnd(); it++) {
423 if (restart && (scriptManager->isUserLoaded() || isOverrideScript)) {422 ScriptManagerPointer scriptManager = it.value();
424 _isReloading = true;423 // skip already stopped scripts
425 ScriptManager::Type type = scriptManager->getType();424 if (scriptManager->isFinished() || scriptManager->isStopping()) {
425 continue;
426 }
426 427
427 connect(scriptManager.get(), &ScriptManager::finished, this, [this, type, isOverrideScript](QString scriptName) {428 bool isOverrideScript = it.key().toString().compare(this->_defaultScriptsOverride.toString()) == 0;
428 reloadScript(scriptName, !isOverrideScript)->setType(type);429 // queue user scripts if restarting
429 });430 if (restart && (scriptManager->isUserLoaded() || isOverrideScript)) {
430 }431 _isReloading = true;
432 ScriptManager::Type type = scriptManager->getType();
431 433
432 // stop all scripts434 connect(scriptManager.get(), &ScriptManager::finished, this,
433 scriptManager->stop();435 [this, type, isOverrideScript](QString scriptName) {
434 }436 reloadScript(scriptName, !isOverrideScript)->setType(type);
437 });
438 }
435 439
436 if (restart) {440 // stop all scripts
437 qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading";441 scriptManager->stop();
438 QTimer::singleShot(RELOAD_ALL_SCRIPTS_TIMEOUT, this, [&] {442 scriptManager->waitTillDoneRunning();
439 _isReloading = false;443 }
440 });444
441 emit scriptsReloading();445 if (restart) {
442 }446 qCDebug(scriptengine) << "stopAllScripts -- emitting scriptsReloading";
447 QTimer::singleShot(RELOAD_ALL_SCRIPTS_TIMEOUT, this, [&] { _isReloading = false; });
448 emit scriptsReloading();
449 }
450 });
443}451}
444 452
445bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) {453bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) {
@@ -612,6 +620,7 @@ void ScriptEngines::onScriptFinished(const QString& rawScriptURL, ScriptManagerP · 166 unmodified lines
612 }620 }
613 }621 }
614 622
623 // Could this cause deadlocks when script engine invokes a blocking method on main thread?
615 manager->waitTillDoneRunning();624 manager->waitTillDoneRunning();
616 removeScriptEngine(manager);625 removeScriptEngine(manager);
617 626