forked from qt-creator/qt-creator
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 <leandro.melo@nokia.com>
This commit is contained in:
@@ -133,6 +133,12 @@ ModelManager::ModelManager(QObject *parent):
|
|||||||
updateImportPaths();
|
updateImportPaths();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ModelManager::~ModelManager()
|
||||||
|
{
|
||||||
|
m_cppQmlTypesUpdater.cancel();
|
||||||
|
m_cppQmlTypesUpdater.waitForFinished();
|
||||||
|
}
|
||||||
|
|
||||||
void ModelManager::delayedInitialization()
|
void ModelManager::delayedInitialization()
|
||||||
{
|
{
|
||||||
CPlusPlus::CppModelManagerInterface *cppModelManager =
|
CPlusPlus::CppModelManagerInterface *cppModelManager =
|
||||||
@@ -724,27 +730,37 @@ void ModelManager::queueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc, bo
|
|||||||
|
|
||||||
void ModelManager::startCppQmlTypeUpdate()
|
void ModelManager::startCppQmlTypeUpdate()
|
||||||
{
|
{
|
||||||
|
// if a future is still running, delay
|
||||||
|
if (m_cppQmlTypesUpdater.isRunning()) {
|
||||||
|
m_updateCppQmlTypesTimer->start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CPlusPlus::CppModelManagerInterface *cppModelManager =
|
CPlusPlus::CppModelManagerInterface *cppModelManager =
|
||||||
CPlusPlus::CppModelManagerInterface::instance();
|
CPlusPlus::CppModelManagerInterface::instance();
|
||||||
if (!cppModelManager)
|
if (!cppModelManager)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QtConcurrent::run(&ModelManager::updateCppQmlTypes,
|
m_cppQmlTypesUpdater = QtConcurrent::run(
|
||||||
this, cppModelManager, m_queuedCppDocuments);
|
&ModelManager::updateCppQmlTypes,
|
||||||
|
this, cppModelManager->snapshot(), m_queuedCppDocuments);
|
||||||
m_queuedCppDocuments.clear();
|
m_queuedCppDocuments.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelManager::updateCppQmlTypes(ModelManager *qmlModelManager,
|
void ModelManager::updateCppQmlTypes(QFutureInterface<void> &interface,
|
||||||
CPlusPlus::CppModelManagerInterface *cppModelManager,
|
ModelManager *qmlModelManager,
|
||||||
|
CPlusPlus::Snapshot snapshot,
|
||||||
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > documents)
|
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > documents)
|
||||||
{
|
{
|
||||||
CppDataHash newData = qmlModelManager->cppData();
|
CppDataHash newData = qmlModelManager->cppData();
|
||||||
|
|
||||||
CPlusPlus::Snapshot snapshot = cppModelManager->snapshot();
|
|
||||||
FindExportedCppTypes finder(snapshot);
|
FindExportedCppTypes finder(snapshot);
|
||||||
|
|
||||||
typedef QPair<CPlusPlus::Document::Ptr, bool> DocScanPair;
|
typedef QPair<CPlusPlus::Document::Ptr, bool> DocScanPair;
|
||||||
foreach (const DocScanPair &pair, documents) {
|
foreach (const DocScanPair &pair, documents) {
|
||||||
|
if (interface.isCanceled())
|
||||||
|
return;
|
||||||
|
|
||||||
CPlusPlus::Document::Ptr doc = pair.first;
|
CPlusPlus::Document::Ptr doc = pair.first;
|
||||||
const bool scan = pair.second;
|
const bool scan = pair.second;
|
||||||
const QString fileName = doc->fileName();
|
const QString fileName = doc->fileName();
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class QMLJSTOOLS_EXPORT ModelManager: public QmlJS::ModelManagerInterface
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ModelManager(QObject *parent = 0);
|
ModelManager(QObject *parent = 0);
|
||||||
|
~ModelManager();
|
||||||
|
|
||||||
void delayedInitialization();
|
void delayedInitialization();
|
||||||
|
|
||||||
@@ -129,8 +130,9 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static bool matchesMimeType(const Core::MimeType &fileMimeType, const Core::MimeType &knownMimeType);
|
static bool matchesMimeType(const Core::MimeType &fileMimeType, const Core::MimeType &knownMimeType);
|
||||||
static void updateCppQmlTypes(ModelManager *qmlModelManager,
|
static void updateCppQmlTypes(QFutureInterface<void> &interface,
|
||||||
CPlusPlus::CppModelManagerInterface *cppModelManager,
|
ModelManager *qmlModelManager,
|
||||||
|
CPlusPlus::Snapshot snapshot,
|
||||||
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > documents);
|
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > documents);
|
||||||
|
|
||||||
mutable QMutex m_mutex;
|
mutable QMutex m_mutex;
|
||||||
@@ -144,6 +146,7 @@ private:
|
|||||||
|
|
||||||
QTimer *m_updateCppQmlTypesTimer;
|
QTimer *m_updateCppQmlTypesTimer;
|
||||||
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > m_queuedCppDocuments;
|
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool> > m_queuedCppDocuments;
|
||||||
|
QFuture<void> m_cppQmlTypesUpdater;
|
||||||
|
|
||||||
CppDataHash m_cppDataHash;
|
CppDataHash m_cppDataHash;
|
||||||
mutable QMutex m_cppDataMutex;
|
mutable QMutex m_cppDataMutex;
|
||||||
|
|||||||
Reference in New Issue
Block a user