aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-08-26 09:51:49 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-08-26 11:21:16 +0200
commite525c551394ba2827e4494bfb72ff43171e9b7e1 (patch)
treea7223403990a45bbaf8037600f282c1d01a6e811 /src
parent1075dca1b50926f52daddf099b5f5a9fbb5da6c7 (diff)
parente9e6f70d355499d551a26960d236644f92ea38af (diff)
Merge "Merge remote-tracking branch 'origin/5.3' into 5.4" into refs/staging/5.4
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp4
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp2
-rw-r--r--src/qml/qml/qqmlincubator.cpp2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp18
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h12
-rw-r--r--src/qml/qml/qqmltypeloader.cpp19
-rw-r--r--src/qml/qml/qqmltypeloader_p.h2
-rw-r--r--src/qml/qml/qqmlvme.cpp2
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h2
-rw-r--r--src/qml/types/qqmlinstantiator.cpp1
-rw-r--r--src/qml/types/qqmllistmodel.cpp8
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp2
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp12
-rw-r--r--src/quick/util/qquickstatechangescript.cpp2
14 files changed, 63 insertions, 25 deletions
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 2c975fef70..f7940c9602 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -644,7 +644,7 @@ public:
inline ArrayElementLessThan(ExecutionContext *context, Object *thisObject, const ValueRef comparefn)
: m_context(context), thisObject(thisObject), m_comparefn(comparefn) {}
- bool operator()(const Value &v1, const Value &v2) const;
+ bool operator()(Value v1, Value v2) const;
private:
ExecutionContext *m_context;
@@ -653,7 +653,7 @@ private:
};
-bool ArrayElementLessThan::operator()(const Value &v1, const Value &v2) const
+bool ArrayElementLessThan::operator()(Value v1, Value v2) const
{
Scope scope(m_context);
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 9e53d51d79..49032e5bcf 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -478,7 +478,7 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
if (pos == end) // 12
return Encode(std::numeric_limits<double>::quiet_NaN());
bool overflow = false;
- qint64 v_overflow;
+ qint64 v_overflow = 0;
unsigned overflow_digit_count = 0;
int d = toInt(*pos++, R);
if (d == -1)
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index edd5573a02..b40ac5fdeb 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -376,7 +376,7 @@ finishIncubate:
enginePriv->erroredBindings->removeError();
}
}
- } else {
+ } else if (!creator.isNull()) {
vmeGuard.guard(creator.data());
}
}
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 4efe72d862..0ad60e01ab 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1021,6 +1021,13 @@ void QQmlObjectCreator::recordError(const QV4::CompiledData::Location &location,
errors << error;
}
+void QQmlObjectCreator::registerObjectWithContextById(int objectIndex, QObject *instance) const
+{
+ QHash<int, int>::ConstIterator idEntry = objectIndexToId.find(objectIndex);
+ if (idEntry != objectIndexToId.constEnd())
+ context->setIdProperty(idEntry.value(), instance);
+}
+
QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isContextObject)
{
QQmlObjectCreationProfiler profiler(sharedState->profiler.profiler);
@@ -1120,10 +1127,6 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
parserStatus->d = &sharedState->allParserStatusCallbacks.top();
}
- QHash<int, int>::ConstIterator idEntry = objectIndexToId.find(index);
- if (idEntry != objectIndexToId.constEnd())
- context->setIdProperty(idEntry.value(), instance);
-
// Register the context object in the context early on in order for pending binding
// initialization to find it available.
if (isContextObject)
@@ -1147,8 +1150,10 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo
}
}
- if (isComponent)
+ if (isComponent) {
+ registerObjectWithContextById(index, instance);
return instance;
+ }
QQmlRefPointer<QQmlPropertyCache> cache = propertyCaches.at(index);
Q_ASSERT(!cache.isNull());
@@ -1313,6 +1318,9 @@ bool QQmlObjectCreator::populateInstance(int index, QObject *instance, QObject *
} else {
vmeMetaObject = QQmlVMEMetaObject::get(_qobject);
}
+
+ registerObjectWithContextById(index, _qobject);
+
qSwap(_propertyCache, cache);
qSwap(_vmeMetaObject, vmeMetaObject);
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index 5c6a4b4476..6919281b77 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -42,6 +42,8 @@
#include <private/qrecursionwatcher_p.h>
#include <private/qqmlprofiler_p.h>
+#include <qpointer.h>
+
QT_BEGIN_NAMESPACE
class QQmlAbstractBinding;
@@ -55,7 +57,7 @@ struct QQmlObjectCreatorSharedState : public QSharedData
QQmlContextData *creationContext;
QFiniteStack<QQmlAbstractBinding*> allCreatedBindings;
QFiniteStack<QQmlParserStatus*> allParserStatusCallbacks;
- QFiniteStack<QObject*> allCreatedObjects;
+ QFiniteStack<QPointer<QObject> > allCreatedObjects;
QV4::Value *allJavaScriptObjects; // pointer to vector on JS stack to reference JS wrappers during creation phase.
QQmlComponentAttached *componentAttached;
QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks;
@@ -81,8 +83,8 @@ public:
QList<QQmlError> errors;
- QQmlContextData *parentContextData() const { return parentContext; }
- QFiniteStack<QObject*> &allCreatedObjects() const { return sharedState->allCreatedObjects; }
+ QQmlContextData *parentContextData() { return parentContext.contextData(); }
+ QFiniteStack<QPointer<QObject> > &allCreatedObjects() const { return sharedState->allCreatedObjects; }
private:
QQmlObjectCreator(QQmlContextData *contextData, QQmlCompiledData *compiledData, QQmlObjectCreatorSharedState *inheritedSharedState);
@@ -103,6 +105,8 @@ private:
QString stringAt(int idx) const { return qmlUnit->stringAt(idx); }
void recordError(const QV4::CompiledData::Location &location, const QString &description);
+ void registerObjectWithContextById(int objectIndex, QObject *instance) const;
+
enum Phase {
Startup,
CreatingObjects,
@@ -115,7 +119,7 @@ private:
QQmlEngine *engine;
QQmlCompiledData *compiledData;
const QV4::CompiledData::Unit *qmlUnit;
- QQmlContextData *parentContext;
+ QQmlGuardedContextData parentContext;
QQmlContextData *context;
const QHash<int, QQmlCompiledData::TypeReference*> &resolvedTypes;
const QVector<QQmlPropertyCache *> &propertyCaches;
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 72a62ed065..6913019562 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -140,6 +140,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 *);
@@ -777,6 +778,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();
@@ -980,7 +987,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()),
@@ -993,12 +1000,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();
}
}
@@ -1602,7 +1615,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 06838478b9..3d3ad28091 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -221,7 +221,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 *);
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 23cf74eaf7..6ecc3bda2e 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -105,7 +105,7 @@ void QQmlVMEGuard::guard(QQmlObjectCreator *creator)
{
clear();
- QFiniteStack<QObject*> &objects = creator->allCreatedObjects();
+ QFiniteStack<QPointer<QObject> > &objects = creator->allCreatedObjects();
m_objectCount = objects.count();
m_objects = new QPointer<QObject>[m_objectCount];
for (int ii = 0; ii < m_objectCount; ++ii)
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index f8002a43ad..a7def0ad50 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -135,7 +135,7 @@ public:
QV4::ExecutionEngine *v4;
QQmlDelegateModelItemMetaType * const metaType;
QQmlContextData *contextData;
- QObject *object;
+ QPointer<QObject> object;
QPointer<QQmlDelegateModelAttached> attached;
QQDMIncubationTask *incubationTask;
int objectRef;
diff --git a/src/qml/types/qqmlinstantiator.cpp b/src/qml/types/qqmlinstantiator.cpp
index eba2d4b668..891011081d 100644
--- a/src/qml/types/qqmlinstantiator.cpp
+++ b/src/qml/types/qqmlinstantiator.cpp
@@ -368,6 +368,7 @@ void QQmlInstantiator::setModel(const QVariant &v)
if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) {
if (d->ownModel) {
delete d->instanceModel;
+ prevModel = 0;
d->ownModel = false;
}
d->instanceModel = vim;
diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp
index 4fca11b511..25879972ca 100644
--- a/src/qml/types/qqmllistmodel.cpp
+++ b/src/qml/types/qqmllistmodel.cpp
@@ -802,7 +802,7 @@ int ListElement::setDoubleProperty(const ListLayout::Role &role, double d)
if (role.type == ListLayout::Role::Number) {
char *mem = getPropertyMemory(role);
- double *value = new (mem) double;
+ double *value = reinterpret_cast<double *>(mem);
bool changed = *value != d;
*value = d;
if (changed)
@@ -818,7 +818,7 @@ int ListElement::setBoolProperty(const ListLayout::Role &role, bool b)
if (role.type == ListLayout::Role::Bool) {
char *mem = getPropertyMemory(role);
- bool *value = new (mem) bool;
+ bool *value = reinterpret_cast<bool *>(mem);
bool changed = *value != b;
*value = b;
if (changed)
@@ -834,8 +834,8 @@ int ListElement::setListProperty(const ListLayout::Role &role, ListModel *m)
if (role.type == ListLayout::Role::List) {
char *mem = getPropertyMemory(role);
- ListModel **value = new (mem) ListModel *;
- if (*value) {
+ ListModel **value = reinterpret_cast<ListModel **>(mem);
+ if (*value && *value != m) {
(*value)->destroy();
delete *value;
}
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 228f0be3fe..28c84facb5 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -2808,7 +2808,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(QV4::CallContex
\brief Provides a Context2D TextMetrics interface
The TextMetrics object can be created by QtQuick::Context2D::measureText method.
- See \l{http://www.w3.org/TR/2dcontext/#textmetrics}{W3C 2d context TexMetrics} for more details.
+ See \l{http://www.w3.org/TR/2dcontext/#textmetrics}{W3C 2d context TextMetrics} for more details.
\sa Context2D::measureText
\sa width
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index b69058a504..7bf1d759f7 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -1037,6 +1037,18 @@ void QSGThreadedRenderLoop::releaseResources(Window *w, bool inDestructor)
w->thread->postEvent(new WMTryReleaseEvent(window, inDestructor, fallback));
w->thread->waitCondition.wait(&w->thread->mutex);
delete fallback;
+
+ // Avoid a shutdown race condition.
+ // If SG is invalidated and 'active' becomes false, the thread's run()
+ // method will exit. handleExposure() relies on QThread::isRunning() (because it
+ // potentially needs to start the thread again) and our mutex cannot be used to
+ // track the thread stopping, so we wait a few nanoseconds extra so the thread
+ // can exit properly.
+ if (!w->thread->active) {
+ qCDebug(QSG_LOG_RENDERLOOP) << " - waiting for render thread to exit" << w->window;
+ w->thread->wait();
+ qCDebug(QSG_LOG_RENDERLOOP) << " - render thread finished" << w->window;
+ }
}
w->thread->mutex.unlock();
}
diff --git a/src/quick/util/qquickstatechangescript.cpp b/src/quick/util/qquickstatechangescript.cpp
index 89fa22205f..02a9507ce9 100644
--- a/src/quick/util/qquickstatechangescript.cpp
+++ b/src/quick/util/qquickstatechangescript.cpp
@@ -67,7 +67,7 @@ public:
A StateChangeScript is run upon entering a state. You can optionally use
ScriptAction to specify the point in the transition at which
- the StateChangeScript should to be run.
+ the StateChangeScript should be run.
\snippet qml/states/statechangescript.qml state and transition