From 48d93e0d854b3f9a2486a2393fee38496fd57bd9 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Tue, 1 Jul 2014 14:48:07 +0200 Subject: [PATCH] Avoid race condition in QQmlEngine on shutdown. The QQmlTypeLoader was deleted (and its thread shut down) when the QQmlEnginePrivate was destroyed. However, the QQmlTypeLoader runs a thread which would happiliy make calls on the engine and its managed data. Fix this by stopping the QQmlTypeLoader's thread right away in QQmlEngine. Task-number: QTBUG-39905 Change-Id: Ida8e95d083f79237c74b036fd3521133a9fa4ac7 Reviewed-by: Erik Verbruggen --- src/qml/qml/qqmlengine.cpp | 2 ++ src/qml/qml/qqmltypeloader.cpp | 15 ++++++++++++--- src/qml/qml/qqmltypeloader_p.h | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 17e5c55..46fc329 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -904,6 +904,8 @@ QQmlEngine::~QQmlEngine() if (d->isDebugging) QQmlDebugServer::instance()->removeEngine(this); + d->typeLoader.invalidate(); + // Emit onDestruction signals for the root context before // we destroy the contexts, engine, Singleton Types etc. that // may be required to handle the destruction signal. diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 1afc5bb..c5a4d65 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -897,11 +897,20 @@ QQmlDataLoader::QQmlDataLoader(QQmlEngine *engine) /*! \internal */ QQmlDataLoader::~QQmlDataLoader() { + invalidate(); +} + +void QQmlDataLoader::invalidate() +{ for (NetworkReplies::Iterator iter = m_networkReplies.begin(); iter != m_networkReplies.end(); ++iter) (*iter)->release(); + m_networkReplies.clear(); - shutdownThread(); - delete m_thread; + if (m_thread) { + shutdownThread(); + delete m_thread; + m_thread = 0; + } } void QQmlDataLoader::lock() @@ -1228,7 +1237,7 @@ void QQmlDataLoader::setCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::Cached void QQmlDataLoader::shutdownThread() { - if (!m_thread->isShutdown()) + if (m_thread && !m_thread->isShutdown()) m_thread->shutdown(); } diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index b09ac15..3d0b77e 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -233,6 +233,7 @@ public: QQmlEngine *engine() const; void initializeEngine(QQmlExtensionInterface *, const char *); + void invalidate(); protected: void shutdownThread(); -- 2.7.4