From 934c77c2c42becbb85bc5db8c900f7ed3fa00776 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 20 Oct 2011 11:25:38 +0200 Subject: [PATCH] QmlJS/C++: Fix possible crash on exit. It could crash if a thread to find exported cpp types was still running after the ModelManager was destroyed. Change-Id: Ia48fac9c2ad1296992af83af57e84cce8c4f95ae Reviewed-by: Leandro T. C. Melo --- src/plugins/qmljstools/qmljsmodelmanager.cpp | 26 ++++++++++++++++---- src/plugins/qmljstools/qmljsmodelmanager.h | 7 ++++-- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index 1912f6bc998..2be55ed8f73 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -133,6 +133,12 @@ ModelManager::ModelManager(QObject *parent): updateImportPaths(); } +ModelManager::~ModelManager() +{ + m_cppQmlTypesUpdater.cancel(); + m_cppQmlTypesUpdater.waitForFinished(); +} + void ModelManager::delayedInitialization() { CPlusPlus::CppModelManagerInterface *cppModelManager = @@ -724,27 +730,37 @@ void ModelManager::queueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc, bo void ModelManager::startCppQmlTypeUpdate() { + // if a future is still running, delay + if (m_cppQmlTypesUpdater.isRunning()) { + m_updateCppQmlTypesTimer->start(); + return; + } + CPlusPlus::CppModelManagerInterface *cppModelManager = CPlusPlus::CppModelManagerInterface::instance(); if (!cppModelManager) return; - QtConcurrent::run(&ModelManager::updateCppQmlTypes, - this, cppModelManager, m_queuedCppDocuments); + m_cppQmlTypesUpdater = QtConcurrent::run( + &ModelManager::updateCppQmlTypes, + this, cppModelManager->snapshot(), m_queuedCppDocuments); m_queuedCppDocuments.clear(); } -void ModelManager::updateCppQmlTypes(ModelManager *qmlModelManager, - CPlusPlus::CppModelManagerInterface *cppModelManager, +void ModelManager::updateCppQmlTypes(QFutureInterface &interface, + ModelManager *qmlModelManager, + CPlusPlus::Snapshot snapshot, QHash > documents) { CppDataHash newData = qmlModelManager->cppData(); - CPlusPlus::Snapshot snapshot = cppModelManager->snapshot(); FindExportedCppTypes finder(snapshot); typedef QPair DocScanPair; foreach (const DocScanPair &pair, documents) { + if (interface.isCanceled()) + return; + CPlusPlus::Document::Ptr doc = pair.first; const bool scan = pair.second; const QString fileName = doc->fileName(); diff --git a/src/plugins/qmljstools/qmljsmodelmanager.h b/src/plugins/qmljstools/qmljsmodelmanager.h index fb3e41ea1fe..9c07af2e37f 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.h +++ b/src/plugins/qmljstools/qmljsmodelmanager.h @@ -69,6 +69,7 @@ class QMLJSTOOLS_EXPORT ModelManager: public QmlJS::ModelManagerInterface public: ModelManager(QObject *parent = 0); + ~ModelManager(); void delayedInitialization(); @@ -129,8 +130,9 @@ private slots: private: static bool matchesMimeType(const Core::MimeType &fileMimeType, const Core::MimeType &knownMimeType); - static void updateCppQmlTypes(ModelManager *qmlModelManager, - CPlusPlus::CppModelManagerInterface *cppModelManager, + static void updateCppQmlTypes(QFutureInterface &interface, + ModelManager *qmlModelManager, + CPlusPlus::Snapshot snapshot, QHash > documents); mutable QMutex m_mutex; @@ -144,6 +146,7 @@ private: QTimer *m_updateCppQmlTypesTimer; QHash > m_queuedCppDocuments; + QFuture m_cppQmlTypesUpdater; CppDataHash m_cppDataHash; mutable QMutex m_cppDataMutex;