diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2014-08-26 09:51:49 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-08-26 11:21:16 +0200 |
commit | e525c551394ba2827e4494bfb72ff43171e9b7e1 (patch) | |
tree | a7223403990a45bbaf8037600f282c1d01a6e811 /src | |
parent | 1075dca1b50926f52daddf099b5f5a9fbb5da6c7 (diff) | |
parent | e9e6f70d355499d551a26960d236644f92ea38af (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.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4globalobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlincubator.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 18 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 19 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlvme.cpp | 2 | ||||
-rw-r--r-- | src/qml/types/qqmldelegatemodel_p_p.h | 2 | ||||
-rw-r--r-- | src/qml/types/qqmlinstantiator.cpp | 1 | ||||
-rw-r--r-- | src/qml/types/qqmllistmodel.cpp | 8 | ||||
-rw-r--r-- | src/quick/items/context2d/qquickcontext2d.cpp | 2 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 12 | ||||
-rw-r--r-- | src/quick/util/qquickstatechangescript.cpp | 2 |
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 |