aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-06-24 10:35:42 +0200
committerSimon Hausmann <simon.hausmann@digia.com>2014-08-22 21:13:44 +0200
commite59482f7f56fcb91bccff7230bed308e2687078e (patch)
tree48563e76e5da08bd43e1cf10db2908a902820ce0
parent74325015e7b3bab83826eefb61b9ad1808b1524d (diff)
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.cpp19
-rw-r--r--src/qml/qml/qqmltypeloader_p.h2
2 files changed, 17 insertions, 4 deletions
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 7fc08bd114..4412f95e9b 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 b09ac15861..dff6b363bb 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 *);