History

rework ScriptEngine lifetimes using 'smart' pointers

Seth Alves committed 9 years ago

Commit d89f2b71 parent 49ab8af18 files · +135 −146Browse files

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

Unified · Split

libraries/script-engine/src/ScriptEngines.cpp+28−34
@@ -137,16 +137,14 @@ void ScriptEngines::registerScriptInitializer(ScriptInitializer initializer) { · 136 unmodified lines
137 _scriptInitializers.push_back(initializer);137 _scriptInitializers.push_back(initializer);
138}138}
139 139
140void ScriptEngines::addScriptEngine(ScriptEngine* engine) {140void ScriptEngines::addScriptEngine(QSharedPointer<ScriptEngine> engine) {
141 if (_isStopped) {141 if (!_isStopped) {
142 engine->deleteLater();
143 } else {
144 QMutexLocker locker(&_allScriptsMutex);142 QMutexLocker locker(&_allScriptsMutex);
145 _allKnownScriptEngines.insert(engine);143 _allKnownScriptEngines.insert(engine);
146 }144 }
147}145}
148 146
149void ScriptEngines::removeScriptEngine(ScriptEngine* engine) {147void ScriptEngines::removeScriptEngine(QSharedPointer<ScriptEngine> engine) {
150 // If we're not already in the middle of stopping all scripts, then we should remove ourselves148 // If we're not already in the middle of stopping all scripts, then we should remove ourselves
151 // from the list of running scripts. We don't do this if we're in the process of stopping all scripts149 // from the list of running scripts. We don't do this if we're in the process of stopping all scripts
152 // because that method removes scripts from its list as it iterates them150 // because that method removes scripts from its list as it iterates them
@@ -161,9 +159,9 @@ void ScriptEngines::shutdownScripting() { · 8 unmodified lines
161 QMutexLocker locker(&_allScriptsMutex);159 QMutexLocker locker(&_allScriptsMutex);
162 qCDebug(scriptengine) << "Stopping all scripts.... currently known scripts:" << _allKnownScriptEngines.size();160 qCDebug(scriptengine) << "Stopping all scripts.... currently known scripts:" << _allKnownScriptEngines.size();
163 161
164 QMutableSetIterator<ScriptEngine*> i(_allKnownScriptEngines);162 QMutableSetIterator<QSharedPointer<ScriptEngine>> i(_allKnownScriptEngines);
165 while (i.hasNext()) {163 while (i.hasNext()) {
166 ScriptEngine* scriptEngine = i.next();164 QSharedPointer<ScriptEngine> scriptEngine = i.next();
167 QString scriptName = scriptEngine->getFilename();165 QString scriptName = scriptEngine->getFilename();
168 166
169 // NOTE: typically all script engines are running. But there's at least one known exception to this, the167 // NOTE: typically all script engines are running. But there's at least one known exception to this, the
@@ -187,12 +185,9 @@ void ScriptEngines::shutdownScripting() { · 17 unmodified lines
187 qCDebug(scriptengine) << "waiting on script:" << scriptName;185 qCDebug(scriptengine) << "waiting on script:" << scriptName;
188 scriptEngine->waitTillDoneRunning();186 scriptEngine->waitTillDoneRunning();
189 qCDebug(scriptengine) << "done waiting on script:" << scriptName;187 qCDebug(scriptengine) << "done waiting on script:" << scriptName;
190
191 scriptEngine->deleteLater();
192
193 // Once the script is stopped, we can remove it from our set
194 i.remove();
195 }188 }
189 // Once the script is stopped, we can remove it from our set
190 i.remove();
196 }191 }
197 qCDebug(scriptengine) << "DONE Stopping all scripts....";192 qCDebug(scriptengine) << "DONE Stopping all scripts....";
198}193}
@@ -369,9 +364,9 @@ void ScriptEngines::stopAllScripts(bool restart) { · 170 unmodified lines
369 _isReloading = true;364 _isReloading = true;
370 }365 }
371 366
372 for (QHash<QUrl, ScriptEngine*>::const_iterator it = _scriptEnginesHash.constBegin();367 for (QHash<QUrl, QSharedPointer<ScriptEngine>>::const_iterator it = _scriptEnginesHash.constBegin();
373 it != _scriptEnginesHash.constEnd(); it++) {368 it != _scriptEnginesHash.constEnd(); it++) {
374 ScriptEngine *scriptEngine = it.value();369 QSharedPointer<ScriptEngine> scriptEngine = it.value();
375 // skip already stopped scripts370 // skip already stopped scripts
376 if (scriptEngine->isFinished() || scriptEngine->isStopping()) {371 if (scriptEngine->isFinished() || scriptEngine->isStopping()) {
377 continue;372 continue;
@@ -417,11 +412,12 @@ bool ScriptEngines::stopScript(const QString& rawScriptURL, bool restart) { · 39 unmodified lines
417 412
418 QReadLocker lock(&_scriptEnginesHashLock);413 QReadLocker lock(&_scriptEnginesHashLock);
419 if (_scriptEnginesHash.contains(scriptURL)) {414 if (_scriptEnginesHash.contains(scriptURL)) {
420 ScriptEngine* scriptEngine = _scriptEnginesHash[scriptURL];415 QSharedPointer<ScriptEngine> scriptEngine = _scriptEnginesHash[scriptURL];
421 if (restart) {416 if (restart) {
422 auto scriptCache = DependencyManager::get<ScriptCache>();417 auto scriptCache = DependencyManager::get<ScriptCache>();
423 scriptCache->deleteScript(scriptURL);418 scriptCache->deleteScript(scriptURL);
424 connect(scriptEngine, &ScriptEngine::finished, this, [this](QString scriptName, ScriptEngine* engine) {419 connect(scriptEngine.data(), &ScriptEngine::finished,
420 this, [this](QString scriptName, QSharedPointer<ScriptEngine> engine) {
425 reloadScript(scriptName);421 reloadScript(scriptName);
426 });422 });
427 }423 }
@@ -449,11 +445,11 @@ void ScriptEngines::reloadAllScripts() { · 21 unmodified lines
449 stopAllScripts(true);445 stopAllScripts(true);
450}446}
451 447
452ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserLoaded, bool loadScriptFromEditor,448QSharedPointer<ScriptEngine> ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserLoaded, bool loadScriptFromEditor,
453 bool activateMainWindow, bool reload) {449 bool activateMainWindow, bool reload) {
454 if (thread() != QThread::currentThread()) {450 if (thread() != QThread::currentThread()) {
455 ScriptEngine* result { nullptr };451 QSharedPointer<ScriptEngine> result { nullptr };
456 BLOCKING_INVOKE_METHOD(this, "loadScript", Q_RETURN_ARG(ScriptEngine*, result),452 BLOCKING_INVOKE_METHOD(this, "loadScript", Q_RETURN_ARG(QSharedPointer<ScriptEngine>, result),
457 Q_ARG(QUrl, scriptFilename),453 Q_ARG(QUrl, scriptFilename),
458 Q_ARG(bool, isUserLoaded),454 Q_ARG(bool, isUserLoaded),
459 Q_ARG(bool, loadScriptFromEditor),455 Q_ARG(bool, loadScriptFromEditor),
@@ -479,19 +475,16 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL · 19 unmodified lines
479 return scriptEngine;475 return scriptEngine;
480 }476 }
481 477
482 scriptEngine = new ScriptEngine(_context, NO_SCRIPT, "about:" + scriptFilename.fileName());478 scriptEngine = QSharedPointer<ScriptEngine>(new ScriptEngine(_context, NO_SCRIPT, "about:" + scriptFilename.fileName()));
479 addScriptEngine(scriptEngine);
483 scriptEngine->setUserLoaded(isUserLoaded);480 scriptEngine->setUserLoaded(isUserLoaded);
484 connect(scriptEngine, &ScriptEngine::doneRunning, this, [scriptEngine] {
485 scriptEngine->deleteLater();
486 }, Qt::QueuedConnection);
487
488 481
489 if (scriptFilename.isEmpty() || !scriptUrl.isValid()) {482 if (scriptFilename.isEmpty() || !scriptUrl.isValid()) {
490 launchScriptEngine(scriptEngine);483 launchScriptEngine(scriptEngine);
491 } else {484 } else {
492 // connect to the appropriate signals of this script engine485 // connect to the appropriate signals of this script engine
493 connect(scriptEngine, &ScriptEngine::scriptLoaded, this, &ScriptEngines::onScriptEngineLoaded);486 connect(scriptEngine.data(), &ScriptEngine::scriptLoaded, this, &ScriptEngines::onScriptEngineLoaded);
494 connect(scriptEngine, &ScriptEngine::errorLoadingScript, this, &ScriptEngines::onScriptEngineError);487 connect(scriptEngine.data(), &ScriptEngine::errorLoadingScript, this, &ScriptEngines::onScriptEngineError);
495 488
496 // get the script engine object to load the script at the designated script URL489 // get the script engine object to load the script at the designated script URL
497 scriptEngine->loadURL(scriptUrl, reload);490 scriptEngine->loadURL(scriptUrl, reload);
@@ -500,8 +493,8 @@ ScriptEngine* ScriptEngines::loadScript(const QUrl& scriptFilename, bool isUserL · 2 unmodified lines
500 return scriptEngine;493 return scriptEngine;
501}494}
502 495
503ScriptEngine* ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) {496QSharedPointer<ScriptEngine> ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) {
504 ScriptEngine* result = nullptr;497 QSharedPointer<ScriptEngine> result;
505 {498 {
506 QReadLocker lock(&_scriptEnginesHashLock);499 QReadLocker lock(&_scriptEnginesHashLock);
507 const QUrl scriptURL = normalizeScriptURL(rawScriptURL);500 const QUrl scriptURL = normalizeScriptURL(rawScriptURL);
@@ -516,7 +509,8 @@ ScriptEngine* ScriptEngines::getScriptEngine(const QUrl& rawScriptURL) { · 8 unmodified lines
516// FIXME - change to new version of ScriptCache loading notification509// FIXME - change to new version of ScriptCache loading notification
517void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) {510void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) {
518 UserActivityLogger::getInstance().loadedScript(rawScriptURL);511 UserActivityLogger::getInstance().loadedScript(rawScriptURL);
519 ScriptEngine* scriptEngine = qobject_cast<ScriptEngine*>(sender());512 QSharedPointer<BaseScriptEngine> baseScriptEngine = qobject_cast<ScriptEngine*>(sender())->sharedFromThis();
513 QSharedPointer<ScriptEngine> scriptEngine = qSharedPointerCast<ScriptEngine>(baseScriptEngine);
520 514
521 launchScriptEngine(scriptEngine);515 launchScriptEngine(scriptEngine);
522 516
@@ -532,12 +526,12 @@ void ScriptEngines::onScriptEngineLoaded(const QString& rawScriptURL) { · 9 unmodified lines
532 emit scriptCountChanged();526 emit scriptCountChanged();
533}527}
534 528
535void ScriptEngines::launchScriptEngine(ScriptEngine* scriptEngine) {529void ScriptEngines::launchScriptEngine(QSharedPointer<ScriptEngine> scriptEngine) {
536 connect(scriptEngine, &ScriptEngine::finished, this, &ScriptEngines::onScriptFinished, Qt::DirectConnection);530 connect(scriptEngine.data(), &ScriptEngine::finished, this, &ScriptEngines::onScriptFinished, Qt::DirectConnection);
537 connect(scriptEngine, &ScriptEngine::loadScript, [&](const QString& scriptName, bool userLoaded) {531 connect(scriptEngine.data(), &ScriptEngine::loadScript, [&](const QString& scriptName, bool userLoaded) {
538 loadScript(scriptName, userLoaded);532 loadScript(scriptName, userLoaded);
539 });533 });
540 connect(scriptEngine, &ScriptEngine::reloadScript, [&](const QString& scriptName, bool userLoaded) {534 connect(scriptEngine.data(), &ScriptEngine::reloadScript, [&](const QString& scriptName, bool userLoaded) {
541 loadScript(scriptName, userLoaded, false, false, true);535 loadScript(scriptName, userLoaded, false, false, true);
542 });536 });
543 537
@@ -558,7 +552,7 @@ void ScriptEngines::launchScriptEngine(ScriptEngine* scriptEngine) { · 14 unmodified lines
558 }552 }
559}553}
560 554
561void ScriptEngines::onScriptFinished(const QString& rawScriptURL, ScriptEngine* engine) {555void ScriptEngines::onScriptFinished(const QString& rawScriptURL, QSharedPointer<ScriptEngine> engine) {
562 bool removed = false;556 bool removed = false;
563 {557 {
564 QWriteLocker lock(&_scriptEnginesHashLock);558 QWriteLocker lock(&_scriptEnginesHashLock);