History

Merge pull request #574 from overte-org/fix/script_reload2

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

ksuprynowicz committed 3 years ago

Commit 6dc9c1a2 parents 19710d2 1ab46f626 files · +231 −84Browse files

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

Unified · Split

libraries/script-engine/src/ScriptManager.cpp+29−6
@@ -67,6 +67,7 @@ · 66 unmodified lines
6767 #include <AddressManager.h>
6868 #include <NetworkingConstants.h>
6969 #include <ThreadHelpers.h>
70+#include <iostream>
7071
7172 const QString ScriptManager::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS {
7273 "com.highfidelity.experimental.enableExtendedJSExceptions"
@@ -366,7 +367,12 @@ bool ScriptManager::isDebugMode() const { · 293 unmodified lines
366367 #endif
367368 }
368369
369−ScriptManager::~ScriptManager() {}
370+ScriptManager::~ScriptManager() {
371+ qDebug() << "ScriptManager::~ScriptManager() : Script manager deleted, type: " << _type << " name: " << _fileNameString;
372+ if (_type == ScriptManager::Type::ENTITY_CLIENT) {
373+ printf("ScriptManager::~ScriptManager");
374+ }
375+}
370376
371377 void ScriptManager::disconnectNonEssentialSignals() {
372378 disconnect();
@@ -464,11 +470,14 @@ void ScriptManager::waitTillDoneRunning(bool shutdown) { · 91 unmodified lines
464470 }
465471 #else
466472 auto startedWaiting = usecTimestampNow();
467− while (workerThread->isRunning()) {
473+ while (!_isDoneRunning) {
468474 // If the final evaluation takes too long, then tell the script engine to stop running
469475 auto elapsedUsecs = usecTimestampNow() - startedWaiting;
476+ // TODO: This part was very unsafe and was causing crashes all the time.
477+ // I disabled it for now until we find a safer solution.
478+ // With it disabled now we get clean shutdowns and restarts.
470479 // V8TODO: temporarily increased script timeout. Maybe use different timeouts for release and unoptimized debug?
471− static const auto MAX_SCRIPT_EVALUATION_TIME = USECS_PER_SECOND;
480+ /*static const auto MAX_SCRIPT_EVALUATION_TIME = 10 * USECS_PER_SECOND;
472481 if (elapsedUsecs > MAX_SCRIPT_EVALUATION_TIME) {
473482 workerThread->quit();
474483
@@ -485,12 +494,12 @@ void ScriptManager::waitTillDoneRunning(bool shutdown) { · 10 unmodified lines
485494
486495 // Wait for the scripting thread to stop running, as
487496 // flooding it with aborts/exceptions will persist it longer
488− static const auto MAX_SCRIPT_QUITTING_TIME = 0.5 * MSECS_PER_SECOND;
497+ static const auto MAX_SCRIPT_QUITTING_TIME = 50 * MSECS_PER_SECOND;
489498 if (!workerThread->wait(MAX_SCRIPT_QUITTING_TIME)) {
490499 Q_ASSERT(false);
491500 workerThread->terminate();
492501 }
493− }
502+ }*/
494503
495504 if (shutdown) {
496505 // NOTE: This will be called on the main application thread (among other threads) from stopAllScripts.
@@ -502,7 +511,7 @@ void ScriptManager::waitTillDoneRunning(bool shutdown) { · 5 unmodified lines
502511 }
503512
504513 // Avoid a pure busy wait
505− QThread::yieldCurrentThread();
514+ QThread::msleep(1);
506515 }
507516 #endif
508517
@@ -510,6 +519,11 @@ void ScriptManager::waitTillDoneRunning(bool shutdown) { · 1 unmodified line
510519 }
511520 }
512521
522+void ScriptManager::removeFromScriptEngines() {
523+ Q_ASSERT(_scriptEngines);
524+ _scriptEngines.toStrongRef()->removeScriptEngine(shared_from_this());
525+}
526+
513527 QString ScriptManager::getFilename() const {
514528 QStringList fileNameParts = _fileNameString.split("/");
515529 QString lastPart;
@@ -987,6 +1001,7 @@ void ScriptManager::run() { · 471 unmodified lines
9871001
9881002 PROFILE_RANGE(script, "ScriptMainLoop");
9891003
1004+//#define SCRIPT_DELAY_DEBUG
9901005 #ifdef SCRIPT_DELAY_DEBUG
9911006 {
9921007 auto actuallySleptUntil = clock::now();
@@ -1066,6 +1081,13 @@ void ScriptManager::run() { · 73 unmodified lines
10661081 _isRunning = false;
10671082 emit runningStateChanged();
10681083 emit doneRunning();
1084+ _engine->disconnectSignalProxies();
1085+ // Process all remaining events
1086+ {
1087+ QEventLoop loop;
1088+ loop.processEvents();
1089+ }
1090+ _isDoneRunning = true;
10691091 }
10701092
10711093 // NOTE: This is private because it must be called on the same thread that created the timers, which is why
@@ -1123,6 +1145,7 @@ void ScriptManager::timerFired() { · 51 unmodified lines
11231145 return; // bail early
11241146 }
11251147
1148+//#define SCRIPT_TIMER_PERFORMANCE_STATISTICS
11261149 #ifdef SCRIPT_TIMER_PERFORMANCE_STATISTICS
11271150 _timerCallCounter++;
11281151 if (_timerCallCounter % 100 == 0) {