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
67#include <AddressManager.h>67#include <AddressManager.h>
68#include <NetworkingConstants.h>68#include <NetworkingConstants.h>
69#include <ThreadHelpers.h>69#include <ThreadHelpers.h>
70#include <iostream>
70 71
71const QString ScriptManager::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS {72const QString ScriptManager::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS {
72 "com.highfidelity.experimental.enableExtendedJSExceptions"73 "com.highfidelity.experimental.enableExtendedJSExceptions"
@@ -366,7 +367,12 @@ bool ScriptManager::isDebugMode() const { · 293 unmodified lines
366#endif367#endif
367}368}
368 369
369ScriptManager::~ScriptManager() {}370ScriptManager::~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}
370 376
371void ScriptManager::disconnectNonEssentialSignals() {377void ScriptManager::disconnectNonEssentialSignals() {
372 disconnect();378 disconnect();
@@ -464,11 +470,14 @@ void ScriptManager::waitTillDoneRunning(bool shutdown) { · 91 unmodified lines
464 }470 }
465#else471#else
466 auto startedWaiting = usecTimestampNow();472 auto startedWaiting = usecTimestampNow();
467 while (workerThread->isRunning()) {473 while (!_isDoneRunning) {
468 // If the final evaluation takes too long, then tell the script engine to stop running474 // If the final evaluation takes too long, then tell the script engine to stop running
469 auto elapsedUsecs = usecTimestampNow() - startedWaiting;475 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.
470 // V8TODO: temporarily increased script timeout. Maybe use different timeouts for release and unoptimized debug?479 // 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;
472 if (elapsedUsecs > MAX_SCRIPT_EVALUATION_TIME) {481 if (elapsedUsecs > MAX_SCRIPT_EVALUATION_TIME) {
473 workerThread->quit();482 workerThread->quit();
474 483
@@ -485,12 +494,12 @@ void ScriptManager::waitTillDoneRunning(bool shutdown) { · 10 unmodified lines
485 494
486 // Wait for the scripting thread to stop running, as495 // Wait for the scripting thread to stop running, as
487 // flooding it with aborts/exceptions will persist it longer496 // 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;
489 if (!workerThread->wait(MAX_SCRIPT_QUITTING_TIME)) {498 if (!workerThread->wait(MAX_SCRIPT_QUITTING_TIME)) {
490 Q_ASSERT(false);499 Q_ASSERT(false);
491 workerThread->terminate();500 workerThread->terminate();
492 }501 }
493 }502 }*/
494 503
495 if (shutdown) {504 if (shutdown) {
496 // NOTE: This will be called on the main application thread (among other threads) from stopAllScripts.505 // 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
502 }511 }
503 512
504 // Avoid a pure busy wait513 // Avoid a pure busy wait
505 QThread::yieldCurrentThread();514 QThread::msleep(1);
506 }515 }
507#endif516#endif
508 517
@@ -510,6 +519,11 @@ void ScriptManager::waitTillDoneRunning(bool shutdown) { · 1 unmodified line
510 }519 }
511}520}
512 521
522void ScriptManager::removeFromScriptEngines() {
523 Q_ASSERT(_scriptEngines);
524 _scriptEngines.toStrongRef()->removeScriptEngine(shared_from_this());
525}
526
513QString ScriptManager::getFilename() const {527QString ScriptManager::getFilename() const {
514 QStringList fileNameParts = _fileNameString.split("/");528 QStringList fileNameParts = _fileNameString.split("/");
515 QString lastPart;529 QString lastPart;
@@ -987,6 +1001,7 @@ void ScriptManager::run() { · 471 unmodified lines
987 1001
988 PROFILE_RANGE(script, "ScriptMainLoop");1002 PROFILE_RANGE(script, "ScriptMainLoop");
989 1003
1004//#define SCRIPT_DELAY_DEBUG
990#ifdef SCRIPT_DELAY_DEBUG1005#ifdef SCRIPT_DELAY_DEBUG
991 {1006 {
992 auto actuallySleptUntil = clock::now();1007 auto actuallySleptUntil = clock::now();
@@ -1066,6 +1081,13 @@ void ScriptManager::run() { · 73 unmodified lines
1066 _isRunning = false;1081 _isRunning = false;
1067 emit runningStateChanged();1082 emit runningStateChanged();
1068 emit doneRunning();1083 emit doneRunning();
1084 _engine->disconnectSignalProxies();
1085 // Process all remaining events
1086 {
1087 QEventLoop loop;
1088 loop.processEvents();
1089 }
1090 _isDoneRunning = true;
1069}1091}
1070 1092
1071// NOTE: This is private because it must be called on the same thread that created the timers, which is why1093// 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
1123 return; // bail early1145 return; // bail early
1124 }1146 }
1125 1147
1148//#define SCRIPT_TIMER_PERFORMANCE_STATISTICS
1126#ifdef SCRIPT_TIMER_PERFORMANCE_STATISTICS1149#ifdef SCRIPT_TIMER_PERFORMANCE_STATISTICS
1127 _timerCallCounter++;1150 _timerCallCounter++;
1128 if (_timerCallCounter % 100 == 0) {1151 if (_timerCallCounter % 100 == 0) {