Fix most of the crash causes on script engine reload/shutdown
Showing the changes to libraries/script-engine/src/ScriptManager.cpp (1 of 26 files). Show all
Unified · Split
| @@ -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 | ||
| 71 | const QString ScriptManager::_SETTINGS_ENABLE_EXTENDED_EXCEPTIONS { | 72 | const 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 | #endif | 367 | #endif |
| 367 | } | 368 | } |
| 368 | 369 | ||
| 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 | } | ||
| 370 | 376 | ||
| 371 | void ScriptManager::disconnectNonEssentialSignals() { | 377 | void ScriptManager::disconnectNonEssentialSignals() { |
| 372 | disconnect(); | 378 | disconnect(); |
| @@ -464,11 +470,14 @@ void ScriptManager::waitTillDoneRunning(bool shutdown) { · 91 unmodified lines | |||
| 464 | } | 470 | } |
| 465 | #else | 471 | #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 running | 474 | // 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, as | 495 | // Wait for the scripting thread to stop running, as |
| 487 | // flooding it with aborts/exceptions will persist it longer | 496 | // 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 wait | 513 | // Avoid a pure busy wait |
| 505 | QThread::yieldCurrentThread(); | 514 | QThread::msleep(1); |
| 506 | } | 515 | } |
| 507 | #endif | 516 | #endif |
| 508 | 517 | ||
| @@ -510,6 +519,11 @@ void ScriptManager::waitTillDoneRunning(bool shutdown) { · 1 unmodified line | |||
| 510 | } | 519 | } |
| 511 | } | 520 | } |
| 512 | 521 | ||
| 522 | void ScriptManager::removeFromScriptEngines() { | ||
| 523 | Q_ASSERT(_scriptEngines); | ||
| 524 | _scriptEngines.toStrongRef()->removeScriptEngine(shared_from_this()); | ||
| 525 | } | ||
| 526 | |||
| 513 | QString ScriptManager::getFilename() const { | 527 | QString 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_DEBUG | 1005 | #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 why | 1093 | // 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 early | 1145 | return; // bail early |
| 1124 | } | 1146 | } |
| 1125 | 1147 | ||
| 1148 | //#define SCRIPT_TIMER_PERFORMANCE_STATISTICS | ||
| 1126 | #ifdef SCRIPT_TIMER_PERFORMANCE_STATISTICS | 1149 | #ifdef SCRIPT_TIMER_PERFORMANCE_STATISTICS |
| 1127 | _timerCallCounter++; | 1150 | _timerCallCounter++; |
| 1128 | if (_timerCallCounter % 100 == 0) { | 1151 | if (_timerCallCounter % 100 == 0) { |