diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-06-24 10:35:42 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2014-08-22 21:13:44 +0200 |
commit | e59482f7f56fcb91bccff7230bed308e2687078e (patch) | |
tree | 48563e76e5da08bd43e1cf10db2908a902820ce0 | |
parent | 74325015e7b3bab83826eefb61b9ad1808b1524d (diff) | |
download | qtdeclarative-e59482f7f56fcb91bccff7230bed308e2687078e.tar.gz qtdeclarative-e59482f7f56fcb91bccff7230bed308e2687078e.tar.bz2 qtdeclarative-e59482f7f56fcb91bccff7230bed308e2687078e.zip |
Fix crash with recursively loading cached compilation units
When a cached compilation unit depends on an import that is implemented as a
Qml C++ plugin and that plugin in turn loads an asynchronous component that is
cached, we would get a crash in the typeloader and a failing assertion
(ASSERT: "d->m_mainThreadWaiting == false" in file qml/ftw/qqmlthread.cpp, line 300)
This is because we did not implement the asynchronous loading within the loader
thread for cached compilation units. This is simply done using a posted event,
using the same mechanism used for other async load methods.
Change-Id: Iefce67ab634ce26122c348dcdfc8e66b00fec671
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 19 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 2 |
2 files changed, 17 insertions, 4 deletions
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 7fc08bd11..4412f95e9 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -148,6 +148,7 @@ public: void loadWithStaticData(QQmlDataBlob *b, const QByteArray &); void loadWithStaticDataAsync(QQmlDataBlob *b, const QByteArray &); void loadWithCachedUnit(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit); + void loadWithCachedUnitAsync(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit); void callCompleted(QQmlDataBlob *b); void callDownloadProgressChanged(QQmlDataBlob *b, qreal p); void initializeEngine(QQmlExtensionInterface *, const char *); @@ -785,6 +786,12 @@ void QQmlDataLoaderThread::loadWithCachedUnit(QQmlDataBlob *b, const QQmlPrivate callMethodInThread(&This::loadWithCachedUnitThread, b, unit); } +void QQmlDataLoaderThread::loadWithCachedUnitAsync(QQmlDataBlob *b, const QQmlPrivate::CachedQmlUnit *unit) +{ + b->addref(); + postMethodToThread(&This::loadWithCachedUnitThread, b, unit); +} + void QQmlDataLoaderThread::callCompleted(QQmlDataBlob *b) { b->addref(); @@ -979,7 +986,7 @@ void QQmlDataLoader::loadWithStaticData(QQmlDataBlob *blob, const QByteArray &da } } -void QQmlDataLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit) +void QQmlDataLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode) { #ifdef DATABLOB_DEBUG qWarning("QQmlDataLoader::loadWithUnitFcatory(%s, data): %s thread", qPrintable(blob->m_url.toString()), @@ -992,12 +999,18 @@ void QQmlDataLoader::loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::C unlock(); loadWithCachedUnitThread(blob, unit); lock(); - } else { + } else if (mode == PreferSynchronous) { unlock(); m_thread->loadWithCachedUnit(blob, unit); lock(); if (!blob->isCompleteOrError()) blob->m_data.setIsAsync(true); + } else { + Q_ASSERT(mode == Asynchronous); + blob->m_data.setIsAsync(true); + unlock(); + m_thread->loadWithCachedUnitAsync(blob, unit); + lock(); } } @@ -1601,7 +1614,7 @@ QQmlTypeData *QQmlTypeLoader::getType(const QUrl &url, Mode mode) // TODO: if (compiledData == 0), is it safe to omit this insertion? m_typeCache.insert(url, typeData); if (const QQmlPrivate::CachedQmlUnit *cachedUnit = QQmlMetaType::findCachedCompilationUnit(url)) { - QQmlDataLoader::loadWithCachedUnit(typeData, cachedUnit); + QQmlDataLoader::loadWithCachedUnit(typeData, cachedUnit, mode); } else { QQmlDataLoader::load(typeData, mode); } diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index b09ac1586..dff6b363b 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -229,7 +229,7 @@ public: void load(QQmlDataBlob *, Mode = PreferSynchronous); void loadWithStaticData(QQmlDataBlob *, const QByteArray &, Mode = PreferSynchronous); - void loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit); + void loadWithCachedUnit(QQmlDataBlob *blob, const QQmlPrivate::CachedQmlUnit *unit, Mode mode = PreferSynchronous); QQmlEngine *engine() const; void initializeEngine(QQmlExtensionInterface *, const char *); |