From 35bf26aba421eb36d8d308a0a5138388faf67ef4 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 28 Jul 2011 18:39:34 +1000 Subject: Fix alias warnings in QDeclarativeGuard --- src/declarative/qml/qdeclarativedata_p.h | 30 +------- src/declarative/qml/qdeclarativeengine.cpp | 2 +- src/declarative/qml/qdeclarativeguard_p.h | 107 ++++++++++++++++++++------- src/declarative/util/qdeclarativestate_p_p.h | 4 +- 4 files changed, 88 insertions(+), 55 deletions(-) diff --git a/src/declarative/qml/qdeclarativedata_p.h b/src/declarative/qml/qdeclarativedata_p.h index 2a5eace..4f22b8f 100644 --- a/src/declarative/qml/qdeclarativedata_p.h +++ b/src/declarative/qml/qdeclarativedata_p.h @@ -55,10 +55,10 @@ #include #include -#include "private/qdeclarativeguard_p.h" QT_BEGIN_NAMESPACE +class QDeclarativeGuardImpl; class QDeclarativeCompiledData; class QDeclarativeAbstractBinding; class QDeclarativeContext; @@ -134,7 +134,7 @@ public: quint32 objectDataRefCount; QDeclarativePropertyCache *propertyCache; - QDeclarativeGuard *guards; + QDeclarativeGuardImpl *guards; static QDeclarativeData *get(const QObject *object, bool create = false) { QObjectPrivate *priv = QObjectPrivate::get(const_cast(object)); @@ -160,32 +160,6 @@ private: mutable QDeclarativeDataExtended *extendedData; }; -template -void QDeclarativeGuard::addGuard() -{ - Q_ASSERT(!prev); - - if (QObjectPrivate::get(o)->wasDeleted) - return; - - QDeclarativeData *data = QDeclarativeData::get(o, true); - next = data->guards; - if (next) reinterpret_cast *>(next)->prev = &next; - data->guards = reinterpret_cast *>(this); - prev = &data->guards; -} - -template -void QDeclarativeGuard::remGuard() -{ - Q_ASSERT(prev); - - if (next) reinterpret_cast *>(next)->prev = prev; - *prev = next; - next = 0; - prev = 0; -} - QT_END_NAMESPACE #endif // QDECLARATIVEDATA_P_H diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index e9feff4..1899b34 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1154,7 +1154,7 @@ void QDeclarativeData::destroyed(QObject *object) context->destroy(); while (guards) { - QDeclarativeGuard *guard = guards; + QDeclarativeGuard *guard = static_cast *>(guards); *guard = (QObject *)0; guard->objectDestroyed(object); } diff --git a/src/declarative/qml/qdeclarativeguard_p.h b/src/declarative/qml/qdeclarativeguard_p.h index a085258..393f2b0 100644 --- a/src/declarative/qml/qdeclarativeguard_p.h +++ b/src/declarative/qml/qdeclarativeguard_p.h @@ -55,16 +55,30 @@ #include #include +#include QT_BEGIN_NAMESPACE +class QDeclarativeGuardImpl +{ +public: + inline QDeclarativeGuardImpl(); + inline QDeclarativeGuardImpl(QObject *); + inline QDeclarativeGuardImpl(const QDeclarativeGuardImpl &); + inline ~QDeclarativeGuardImpl(); + + QObject *o; + QDeclarativeGuardImpl *next; + QDeclarativeGuardImpl **prev; + + inline void addGuard(); + inline void remGuard(); +}; + class QObject; template -class QDeclarativeGuard +class QDeclarativeGuard : private QDeclarativeGuardImpl { - QObject *o; - QDeclarativeGuard *next; - QDeclarativeGuard **prev; friend class QDeclarativeData; public: inline QDeclarativeGuard(); @@ -74,6 +88,9 @@ public: inline QDeclarativeGuard &operator=(const QDeclarativeGuard &o); inline QDeclarativeGuard &operator=(T *); + + inline T *object() const; + inline void setObject(T *g); inline bool isNull() const { return !o; } @@ -89,67 +106,107 @@ public: protected: virtual void objectDestroyed(T *) {} - -private: - inline void addGuard(); - inline void remGuard(); }; -QT_END_NAMESPACE - Q_DECLARE_METATYPE(QDeclarativeGuard) -#include "private/qdeclarativedata_p.h" +QDeclarativeGuardImpl::QDeclarativeGuardImpl() +: o(0), next(0), prev(0) +{ +} -QT_BEGIN_NAMESPACE +QDeclarativeGuardImpl::QDeclarativeGuardImpl(QObject *g) +: o(g), next(0), prev(0) +{ + if (o) addGuard(); +} + +QDeclarativeGuardImpl::QDeclarativeGuardImpl(const QDeclarativeGuardImpl &g) +: o(g.o), next(0), prev(0) +{ + if (o) addGuard(); +} + +QDeclarativeGuardImpl::~QDeclarativeGuardImpl() +{ + if (prev) remGuard(); + o = 0; +} + +void QDeclarativeGuardImpl::addGuard() +{ + Q_ASSERT(!prev); + + if (QObjectPrivate::get(o)->wasDeleted) + return; + + QDeclarativeData *data = QDeclarativeData::get(o, true); + next = data->guards; + if (next) next->prev = &next; + data->guards = this; + prev = &data->guards; +} + +void QDeclarativeGuardImpl::remGuard() +{ + Q_ASSERT(prev); + + if (next) next->prev = prev; + *prev = next; + next = 0; + prev = 0; +} template QDeclarativeGuard::QDeclarativeGuard() -: o(0), next(0), prev(0) { } template QDeclarativeGuard::QDeclarativeGuard(T *g) -: o(g), next(0), prev(0) +: QDeclarativeGuardImpl(g) { - if (o) addGuard(); } template QDeclarativeGuard::QDeclarativeGuard(const QDeclarativeGuard &g) -: o(g.o), next(0), prev(0) +: QDeclarativeGuardImpl(g) { - if (o) addGuard(); } template QDeclarativeGuard::~QDeclarativeGuard() { - if (prev) remGuard(); - o = 0; } template QDeclarativeGuard &QDeclarativeGuard::operator=(const QDeclarativeGuard &g) { - if (g.o != o) { - if (prev) remGuard(); - o = g.o; - if (o) addGuard(); - } + setObject(g.object()); return *this; } template QDeclarativeGuard &QDeclarativeGuard::operator=(T *g) { + setObject(g); + return *this; +} + +template +T *QDeclarativeGuard::object() const +{ + return static_cast(o); +}; + +template +void QDeclarativeGuard::setObject(T *g) +{ if (g != o) { if (prev) remGuard(); o = g; if (o) addGuard(); } - return *this; } QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h index ec18f59..195b935 100644 --- a/src/declarative/util/qdeclarativestate_p_p.h +++ b/src/declarative/util/qdeclarativestate_p_p.h @@ -206,7 +206,9 @@ public: struct OperationGuard : public QDeclarativeGuard { - OperationGuard(QObject *obj, QList *l) : list(l) { (QDeclarativeGuard&)*this = obj; } + OperationGuard(QObject *obj, QList *l) : list(l) { + setObject(static_cast(obj)); + } QList *list; void objectDestroyed(QDeclarativeStateOperation *) { // we assume priv will always be destroyed after objectDestroyed calls -- cgit v0.12 From f7839148306215f153a8467edcaffa3d2ec53c79 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 28 Jul 2011 18:39:55 +1000 Subject: Fix alias warnings in QDeclarativeVME --- src/declarative/qml/qdeclarativevme.cpp | 72 +++++++++++++++++++++++++++++++-- src/declarative/qml/qdeclarativevme_p.h | 32 ++------------- 2 files changed, 72 insertions(+), 32 deletions(-) diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 06aed98..221e52c 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -74,6 +74,27 @@ QT_BEGIN_NAMESPACE +// A simple stack wrapper around QVarLengthArray +template +class QDeclarativeVMEStack : private QVarLengthArray +{ +private: + typedef QVarLengthArray VLA; + int _index; + +public: + inline QDeclarativeVMEStack(); + inline bool isEmpty() const; + inline const T &top() const; + inline void push(const T &o); + inline T pop(); + inline int count() const; + inline const T &at(int index) const; +}; + +// We do this so we can forward declare the type in the qdeclarativevme_p.h header +class QDeclarativeVMEObjectStack : public QDeclarativeVMEStack {}; + QDeclarativeVME::QDeclarativeVME() { } @@ -99,10 +120,12 @@ struct ListInstance QDeclarativeListProperty qListProperty; }; +Q_DECLARE_TYPEINFO(ListInstance, Q_PRIMITIVE_TYPE | Q_MOVABLE_TYPE); + QObject *QDeclarativeVME::run(QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, int start, int count, const QBitField &bindingSkipList) { - QDeclarativeVMEStack stack; + QDeclarativeVMEObjectStack stack; if (start == -1) start = 0; if (count == -1) count = comp->bytecode.count(); @@ -121,7 +144,7 @@ void QDeclarativeVME::runDeferred(QObject *object) QDeclarativeCompiledData *comp = data->deferredComponent; int start = data->deferredIdx + 1; int count = data->deferredComponent->bytecode.at(data->deferredIdx).defer.deferCount; - QDeclarativeVMEStack stack; + QDeclarativeVMEObjectStack stack; stack.push(object); run(stack, ctxt, comp, start, count, QBitField()); @@ -143,7 +166,7 @@ static void removeBindingOnProperty(QObject *o, int index) #define CLEAN_PROPERTY(o, index) if (fastHasBinding(o, index)) removeBindingOnProperty(o, index) -QObject *QDeclarativeVME::run(QDeclarativeVMEStack &stack, +QObject *QDeclarativeVME::run(QDeclarativeVMEObjectStack &stack, QDeclarativeContextData *ctxt, QDeclarativeCompiledData *comp, int start, int count, @@ -1054,5 +1077,48 @@ QDeclarativeCompiledData::TypeReference::createInstance(QDeclarativeContextData } } +template +QDeclarativeVMEStack::QDeclarativeVMEStack() +: _index(-1) +{ +} + +template +bool QDeclarativeVMEStack::isEmpty() const { + return _index == -1; +} + +template +const T &QDeclarativeVMEStack::top() const { + return at(_index); +} + +template +void QDeclarativeVMEStack::push(const T &o) { + _index++; + + Q_ASSERT(_index <= VLA::size()); + if (_index == VLA::size()) + append(o); + else + VLA::data()[_index] = o; +} + +template +T QDeclarativeVMEStack::pop() { + Q_ASSERT(_index >= 0); + --_index; + return VLA::data()[_index + 1]; +} + +template +int QDeclarativeVMEStack::count() const { + return _index + 1; +} + +template +const T &QDeclarativeVMEStack::at(int index) const { + return VLA::data()[index]; +} QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativevme_p.h b/src/declarative/qml/qdeclarativevme_p.h index 6b7b93f..b7f110f 100644 --- a/src/declarative/qml/qdeclarativevme_p.h +++ b/src/declarative/qml/qdeclarativevme_p.h @@ -58,6 +58,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -67,34 +68,7 @@ class QDeclarativeCompiledData; class QDeclarativeCompiledData; class QDeclarativeContextData; -template -class QDeclarativeVMEStack { -public: - QDeclarativeVMEStack() : index(-1), maxSize(N), data((T *)fixedData) {} - ~QDeclarativeVMEStack() { if (data != (T *)fixedData) qFree(data); } - - bool isEmpty() const { return index == -1; } - const T &top() const { return data[index]; } - void push(const T &i) { ++index; if (index == maxSize) realloc(); data[index] = i; } - const T &pop() { --index; return data[index + 1]; } - int count() const { return index + 1; } - const T &at(int idx) { return data[idx]; } - -private: - void realloc() { - maxSize += N; - if (data != (T *)fixedData) { - data = (T*)qRealloc(data, maxSize * sizeof(T)); - } else { - data = (T*)qMalloc(maxSize * sizeof(T)); - } - } - int index; - int maxSize; - T *data; - char fixedData[N * sizeof(T)]; -}; - +class QDeclarativeVMEObjectStack; class QDeclarativeVME { public: @@ -109,7 +83,7 @@ public: QList errors() const; private: - QObject *run(QDeclarativeVMEStack &, + QObject *run(QDeclarativeVMEObjectStack &, QDeclarativeContextData *, QDeclarativeCompiledData *, int start, int count, const QBitField &); -- cgit v0.12 From 3f989ba80a9a3794d25f985b2a46d0c13078d350 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 28 Jul 2011 18:40:10 +1000 Subject: Fix alias warnings in MetaCallArgument --- .../qml/qdeclarativeobjectscriptclass.cpp | 114 ++++++++++++--------- 1 file changed, 65 insertions(+), 49 deletions(-) diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index 53f702c..f6f593c 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -680,14 +680,30 @@ private: inline void cleanup(); - char data[4 * sizeof(void *)]; + union { + float floatValue; + double doubleValue; + quint32 intValue; + bool boolValue; + QObject *qobjectPtr; + + char allocData[sizeof(QVariant)]; + }; + + // Pointers to allocData + union { + QString *qstringPtr; + QVariant *qvariantPtr; + QList *qlistPtr; + QScriptValue *qscriptValuePtr; + }; + int type; - bool isObjectType; }; } MetaCallArgument::MetaCallArgument() -: type(QVariant::Invalid), isObjectType(false) +: type(QVariant::Invalid) { } @@ -699,22 +715,22 @@ MetaCallArgument::~MetaCallArgument() void MetaCallArgument::cleanup() { if (type == QMetaType::QString) { - ((QString *)&data)->~QString(); - } else if (type == -1 || type == qMetaTypeId()) { - ((QVariant *)&data)->~QVariant(); + qstringPtr->~QString(); + } else if (type == -1 || type == QMetaType::QVariant) { + qvariantPtr->~QVariant(); } else if (type == qMetaTypeId()) { - ((QScriptValue *)&data)->~QScriptValue(); + qscriptValuePtr->~QScriptValue(); } else if (type == qMetaTypeId >()) { - ((QList *)&data)->~QList(); + qlistPtr->~QList(); } } void *MetaCallArgument::dataPtr() { if (type == -1) - return ((QVariant *)data)->data(); - else - return (void *)&data; + return qvariantPtr->data(); + else + return (void *)&allocData; } void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) @@ -725,7 +741,7 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (callType == qMetaTypeId()) { - new (&data) QScriptValue(engine->undefinedValue()); + qscriptValuePtr = new (&allocData) QScriptValue(engine->undefinedValue()); type = callType; } else if (callType == QMetaType::Int || callType == QMetaType::UInt || @@ -734,20 +750,20 @@ void MetaCallArgument::initAsType(int callType, QDeclarativeEngine *e) callType == QMetaType::Float) { type = callType; } else if (callType == QMetaType::QObjectStar) { - *((QObject **)&data) = 0; + qobjectPtr = 0; type = callType; } else if (callType == QMetaType::QString) { - new (&data) QString(); + qstringPtr = new (&allocData) QString(); type = callType; } else if (callType == qMetaTypeId()) { type = callType; - new (&data) QVariant(); + qvariantPtr = new (&allocData) QVariant(); } else if (callType == qMetaTypeId >()) { type = callType; - new (&data) QList(); + qlistPtr = new (&allocData) QList(); } else { type = -1; - new (&data) QVariant(callType, (void *)0); + qvariantPtr = new (&allocData) QVariant(callType, (void *)0); } } @@ -756,59 +772,60 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, if (type != 0) { cleanup(); type = 0; } if (callType == qMetaTypeId()) { - new (&data) QScriptValue(value); + qscriptValuePtr = new (&allocData) QScriptValue(value); type = qMetaTypeId(); } else if (callType == QMetaType::Int) { - *((int *)&data) = int(value.toInt32()); + intValue = quint32(value.toInt32()); type = callType; } else if (callType == QMetaType::UInt) { - *((uint *)&data) = uint(value.toUInt32()); + intValue = quint32(value.toUInt32()); type = callType; } else if (callType == QMetaType::Bool) { - *((bool *)&data) = value.toBool(); + boolValue = value.toBool(); type = callType; } else if (callType == QMetaType::Double) { - *((double *)&data) = double(value.toNumber()); + doubleValue = double(value.toNumber()); type = callType; } else if (callType == QMetaType::Float) { - *((float *)&data) = float(value.toNumber()); + floatValue = float(value.toNumber()); type = callType; } else if (callType == QMetaType::QString) { if (value.isNull() || value.isUndefined()) - new (&data) QString(); + qstringPtr = new (&allocData) QString(); else - new (&data) QString(value.toString()); + qstringPtr = new (&allocData) QString(value.toString()); type = callType; } else if (callType == QMetaType::QObjectStar) { - *((QObject **)&data) = value.toQObject(); + qobjectPtr = value.toQObject(); type = callType; } else if (callType == qMetaTypeId()) { - new (&data) QVariant(QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value)); + QVariant other = QDeclarativeEnginePrivate::get(engine)->scriptValueToVariant(value); + qvariantPtr = new (&allocData) QVariant(other); type = callType; } else if (callType == qMetaTypeId >()) { - QList *list = new (&data) QList(); + qlistPtr = new (&allocData) QList(); if (value.isArray()) { int length = value.property(QLatin1String("length")).toInt32(); for (int ii = 0; ii < length; ++ii) { QScriptValue arrayItem = value.property(ii); QObject *d = arrayItem.toQObject(); - list->append(d); + qlistPtr->append(d); } } else if (QObject *d = value.toQObject()) { - list->append(d); + qlistPtr->append(d); } type = callType; } else { - new (&data) QVariant(); + qvariantPtr = new (&allocData) QVariant(); type = -1; QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(engine); QVariant v = priv->scriptValueToVariant(value); if (v.userType() == callType) { - *((QVariant *)&data) = v; + *qvariantPtr = v; } else if (v.canConvert((QVariant::Type)callType)) { - *((QVariant *)&data) = v; - ((QVariant *)&data)->convert((QVariant::Type)callType); + *qvariantPtr = v; + qvariantPtr->convert((QVariant::Type)callType); } else if (const QMetaObject *mo = priv->rawMetaObjectForType(callType)) { QObject *obj = priv->toQObject(v); @@ -818,9 +835,9 @@ void MetaCallArgument::fromScriptValue(int callType, QDeclarativeEngine *engine, if (!objMo) obj = 0; } - *((QVariant *)&data) = QVariant(callType, &obj); + *qvariantPtr = QVariant(callType, &obj); } else { - *((QVariant *)&data) = QVariant(callType, (void *)0); + *qvariantPtr = QVariant(callType, (void *)0); } } } @@ -830,27 +847,26 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e); if (type == qMetaTypeId()) { - return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)&data)); + return QScriptDeclarativeClass::Value(engine, *qscriptValuePtr); } else if (type == QMetaType::Int) { - return QScriptDeclarativeClass::Value(engine, *((int *)&data)); + return QScriptDeclarativeClass::Value(engine, int(intValue)); } else if (type == QMetaType::UInt) { - return QScriptDeclarativeClass::Value(engine, *((uint *)&data)); + return QScriptDeclarativeClass::Value(engine, uint(intValue)); } else if (type == QMetaType::Bool) { - return QScriptDeclarativeClass::Value(engine, *((bool *)&data)); + return QScriptDeclarativeClass::Value(engine, boolValue); } else if (type == QMetaType::Double) { - return QScriptDeclarativeClass::Value(engine, *((double *)&data)); + return QScriptDeclarativeClass::Value(engine, doubleValue); } else if (type == QMetaType::Float) { - return QScriptDeclarativeClass::Value(engine, *((float *)&data)); + return QScriptDeclarativeClass::Value(engine, floatValue); } else if (type == QMetaType::QString) { - return QScriptDeclarativeClass::Value(engine, *((QString *)&data)); + return QScriptDeclarativeClass::Value(engine, *qstringPtr); } else if (type == QMetaType::QObjectStar) { - QObject *object = *((QObject **)&data); - if (object) - QDeclarativeData::get(object, true)->setImplicitDestructible(); + if (qobjectPtr) + QDeclarativeData::get(qobjectPtr, true)->setImplicitDestructible(); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); - return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object)); + return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(qobjectPtr)); } else if (type == qMetaTypeId >()) { - QList &list = *(QList*)&data; + QList &list = *qlistPtr; QScriptValue rv = engine->newArray(list.count()); QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e); for (int ii = 0; ii < list.count(); ++ii) { @@ -861,7 +877,7 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) return QScriptDeclarativeClass::Value(engine, rv); } else if (type == -1 || type == qMetaTypeId()) { QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(e); - QScriptValue rv = ep->scriptValueFromVariant(*((QVariant *)&data)); + QScriptValue rv = ep->scriptValueFromVariant(*qvariantPtr); if (rv.isQObject()) { QObject *object = rv.toQObject(); if (object) -- cgit v0.12 From fc1f498f3cedeacfd6d0f41ffc75b3432391db8d Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 28 Jul 2011 18:40:25 +1000 Subject: Fix alias warnings in QML compiled bindings --- .../qml/qdeclarativecompiledbindings.cpp | 26 ++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index 313fe58..7f2cac2 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -143,17 +143,17 @@ struct Register { void setNaN() { setqreal(qSNaN()); } bool isUndefined() const { return type == 0; } - void setQObject(QObject *o) { *((QObject **)data) = o; type = QMetaType::QObjectStar; } - QObject *getQObject() const { return *((QObject **)data); } + void setQObject(QObject *o) { qobjectValue = o; type = QMetaType::QObjectStar; } + QObject *getQObject() const { return qobjectValue; } - void setqreal(qreal v) { *((qreal *)data) = v; type = QMetaType::QReal; } - qreal getqreal() const { return *((qreal *)data); } + void setqreal(qreal v) { qrealValue = v; type = QMetaType::QReal; } + qreal getqreal() const { return qrealValue; } - void setint(int v) { *((int *)data) = v; type = QMetaType::Int; } - int getint() const { return *((int *)data); } + void setint(int v) { intValue = v; type = QMetaType::Int; } + int getint() const { return intValue; } - void setbool(bool v) { *((bool *)data) = v; type = QMetaType::Bool; } - bool getbool() const { return *((bool *)data); } + void setbool(bool v) { boolValue = v; type = QMetaType::Bool; } + bool getbool() const { return boolValue; } QVariant *getvariantptr() { return (QVariant *)typeDataPtr(); } QString *getstringptr() { return (QString *)typeDataPtr(); } @@ -171,7 +171,15 @@ struct Register { void settype(int t) { type = t; } int type; // Optional type - void *data[2]; // Object stored here + union { + QObject *qobjectValue; + qreal qrealValue; + int intValue; + bool boolValue; + char data[sizeof(QVariant)]; + qint64 q_for_alignment_1; + double q_for_alignment_2; + }; #ifdef REGISTER_CLEANUP_DEBUG Register() { -- cgit v0.12 From 9b996fcb591715981e2b13cfbce4ea285747dc0f Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 29 Jul 2011 14:06:10 +1000 Subject: Compile in namespace --- src/declarative/qml/qdeclarativeguard_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/qml/qdeclarativeguard_p.h b/src/declarative/qml/qdeclarativeguard_p.h index 393f2b0..4d84951 100644 --- a/src/declarative/qml/qdeclarativeguard_p.h +++ b/src/declarative/qml/qdeclarativeguard_p.h @@ -108,8 +108,6 @@ protected: virtual void objectDestroyed(T *) {} }; -Q_DECLARE_METATYPE(QDeclarativeGuard) - QDeclarativeGuardImpl::QDeclarativeGuardImpl() : o(0), next(0), prev(0) { @@ -211,4 +209,6 @@ void QDeclarativeGuard::setObject(T *g) QT_END_NAMESPACE +Q_DECLARE_METATYPE(QDeclarativeGuard) + #endif // QDECLARATIVEGUARD_P_H -- cgit v0.12 From 29bc712a2086781b88ff8b66e6f9c3bf964d6b14 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 29 Jul 2011 14:14:09 +1000 Subject: Doc --- doc/src/declarative/qtbinding.qdoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index b35ddc5..70b77b2 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -507,12 +507,16 @@ the \l {Extending QML Functionalities using C++} reference documentation for more information. -\section2 Using enumeration values as signal parameters +\section2 Using enumeration values as signal and method parameters C++ signals may pass enumeration values as signal parameters to QML, providing that the enumeration and the signal are declared within the same class, or that the enumeration value is one of those declared in the \l {Qt}{Qt Namespace}. +Likewise, invokable C++ methods parameters may be enumeration values providing that the enumeration and +the method is declared within the same class, or that the enumeration value is one of thise declared in the +\l {Qt}{Qt Namespace}. + Additionally, if a C++ signal with an enum parameter should be connectable to a QML function using the \l {Connecting signals to methods and other signals}{connect()} function, the enum type must be registered using qRegisterMetaType(). -- cgit v0.12 From cb75850db1db7f21d48f1b96d1a7ac0a6af37412 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 29 Jul 2011 14:16:43 +1000 Subject: Doc --- doc/src/declarative/qtbinding.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index 70b77b2..80cca06 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -514,7 +514,7 @@ and the signal are declared within the same class, or that the enumeration value in the \l {Qt}{Qt Namespace}. Likewise, invokable C++ methods parameters may be enumeration values providing that the enumeration and -the method is declared within the same class, or that the enumeration value is one of thise declared in the +the method are declared within the same class, or that the enumeration value is one of those declared in the \l {Qt}{Qt Namespace}. Additionally, if a C++ signal with an enum parameter should be connectable to a QML function using the -- cgit v0.12 From 422f4e8ec53b917fad09a3e671fd93048dde72ed Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Fri, 29 Jul 2011 16:54:44 +1000 Subject: Rework threading internals in XmlListModel to avoid global static QTBUG-20629 reports a crash on destruction of XmlListModel when cleaning up the global static for the QDeclarativeXmlQuery object. The fix restructures the internals to be like the threading structure used for QDeclarativePixmapReader which doesn't use a global static. Task-number: QTBUG-20629 Reviewed-by: Martin Jones --- src/declarative/util/qdeclarativexmllistmodel.cpp | 296 +++++++++++++++------- 1 file changed, 205 insertions(+), 91 deletions(-) diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 6f9245b..5236757 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -147,114 +147,226 @@ struct XmlQueryJob QString prefix; }; -class QDeclarativeXmlQuery : public QObject + +class QDeclarativeXmlQueryEngine; +class QDeclarativeXmlQueryThreadObject : public QObject { Q_OBJECT public: - QDeclarativeXmlQuery(QObject *parent=0) - : QObject(parent), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1) { - qRegisterMetaType("QDeclarativeXmlQueryResult"); - moveToThread(&m_thread); - m_thread.start(QThread::IdlePriority); - } + QDeclarativeXmlQueryThreadObject(QDeclarativeXmlQueryEngine *); - ~QDeclarativeXmlQuery() { - if(m_thread.isRunning()) { - m_thread.quit(); - m_thread.wait(); - } - } - - void abort(int id) { - QMutexLocker ml(&m_mutex); - if (id != -1) { - m_jobs.remove(id); - } - } - - int doQuery(QString query, QString namespaces, QByteArray data, QList* roleObjects, QStringList keyRoleResultsCache) { - { - QMutexLocker m1(&m_mutex); - m_queryIds.ref(); - if (m_queryIds <= 0) - m_queryIds = 1; - } - - XmlQueryJob job; - job.queryId = m_queryIds; - job.data = data; - job.query = QLatin1String("doc($src)") + query; - job.namespaces = namespaces; - job.keyRoleResultsCache = keyRoleResultsCache; - - for (int i=0; icount(); i++) { - if (!roleObjects->at(i)->isValid()) { - job.roleQueries << QString(); - continue; - } - job.roleQueries << roleObjects->at(i)->query(); - job.roleQueryErrorId << static_cast(roleObjects->at(i)); - if (roleObjects->at(i)->isKey()) - job.keyRoleQueries << job.roleQueries.last(); - } + void processJobs(); + virtual bool event(QEvent *e); - { - QMutexLocker ml(&m_mutex); - m_jobs.insert(m_queryIds, job); - } +private: + QDeclarativeXmlQueryEngine *m_queryEngine; +}; - QMetaObject::invokeMethod(this, "processQuery", Qt::QueuedConnection, Q_ARG(int, job.queryId)); - return job.queryId; - } -private slots: - void processQuery(int queryId) { - XmlQueryJob job; +class QDeclarativeXmlQueryEngine : public QThread +{ + Q_OBJECT +public: + QDeclarativeXmlQueryEngine(QDeclarativeEngine *eng); + ~QDeclarativeXmlQueryEngine(); - { - QMutexLocker ml(&m_mutex); - if (!m_jobs.contains(queryId)) - return; - job = m_jobs.value(queryId); - } + int doQuery(QString query, QString namespaces, QByteArray data, QList* roleObjects, QStringList keyRoleResultsCache); + void abort(int id); - QDeclarativeXmlQueryResult result; - result.queryId = job.queryId; - doQueryJob(&job, &result); - doSubQueryJob(&job, &result); + void processJobs(); - { - QMutexLocker ml(&m_mutex); - if (m_jobs.contains(queryId)) { - emit queryCompleted(result); - m_jobs.remove(queryId); - } - } - } + static QDeclarativeXmlQueryEngine *instance(QDeclarativeEngine *engine); -Q_SIGNALS: +signals: void queryCompleted(const QDeclarativeXmlQueryResult &); void error(void*, const QString&); protected: - + void run(); private: + void processQuery(XmlQueryJob *job); void doQueryJob(XmlQueryJob *job, QDeclarativeXmlQueryResult *currentResult); void doSubQueryJob(XmlQueryJob *job, QDeclarativeXmlQueryResult *currentResult); void getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const; void addIndexToRangeList(QList *ranges, int index) const; -private: QMutex m_mutex; - QThread m_thread; - QMap m_jobs; + QDeclarativeXmlQueryThreadObject *m_threadObject; + QList m_jobs; + QSet m_cancelledJobs; QAtomicInt m_queryIds; + + QDeclarativeEngine *m_engine; + QObject *m_eventLoopQuitHack; + + static QHash queryEngines; + static QMutex queryEnginesMutex; }; +QHash QDeclarativeXmlQueryEngine::queryEngines; +QMutex QDeclarativeXmlQueryEngine::queryEnginesMutex; + + +QDeclarativeXmlQueryThreadObject::QDeclarativeXmlQueryThreadObject(QDeclarativeXmlQueryEngine *e) + : m_queryEngine(e) +{ +} + +void QDeclarativeXmlQueryThreadObject::processJobs() +{ + QCoreApplication::postEvent(this, new QEvent(QEvent::User)); +} + +bool QDeclarativeXmlQueryThreadObject::event(QEvent *e) +{ + if (e->type() == QEvent::User) { + m_queryEngine->processJobs(); + return true; + } else { + return QObject::event(e); + } +} + + + +QDeclarativeXmlQueryEngine::QDeclarativeXmlQueryEngine(QDeclarativeEngine *eng) +: QThread(eng), m_threadObject(0), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1), m_engine(eng), m_eventLoopQuitHack(0) +{ + qRegisterMetaType("QDeclarativeXmlQueryResult"); -Q_GLOBAL_STATIC(QDeclarativeXmlQuery, globalXmlQuery) + m_eventLoopQuitHack = new QObject; + m_eventLoopQuitHack->moveToThread(this); + connect(m_eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection); + start(QThread::IdlePriority); +} -void QDeclarativeXmlQuery::doQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult) +QDeclarativeXmlQueryEngine::~QDeclarativeXmlQueryEngine() +{ + queryEnginesMutex.lock(); + queryEngines.remove(m_engine); + queryEnginesMutex.unlock(); + + m_eventLoopQuitHack->deleteLater(); + wait(); +} + +int QDeclarativeXmlQueryEngine::doQuery(QString query, QString namespaces, QByteArray data, QList* roleObjects, QStringList keyRoleResultsCache) { + { + QMutexLocker m1(&m_mutex); + m_queryIds.ref(); + if (m_queryIds <= 0) + m_queryIds = 1; + } + + XmlQueryJob job; + job.queryId = m_queryIds; + job.data = data; + job.query = QLatin1String("doc($src)") + query; + job.namespaces = namespaces; + job.keyRoleResultsCache = keyRoleResultsCache; + + for (int i=0; icount(); i++) { + if (!roleObjects->at(i)->isValid()) { + job.roleQueries << QString(); + continue; + } + job.roleQueries << roleObjects->at(i)->query(); + job.roleQueryErrorId << static_cast(roleObjects->at(i)); + if (roleObjects->at(i)->isKey()) + job.keyRoleQueries << job.roleQueries.last(); + } + + { + QMutexLocker ml(&m_mutex); + m_jobs.append(job); + if (m_threadObject) + m_threadObject->processJobs(); + } + + return job.queryId; +} + +void QDeclarativeXmlQueryEngine::abort(int id) +{ + QMutexLocker ml(&m_mutex); + if (id != -1) { + m_cancelledJobs.insert(id); + if (m_threadObject) + m_threadObject->processJobs(); + } +} + +void QDeclarativeXmlQueryEngine::run() +{ + m_mutex.lock(); + m_threadObject = new QDeclarativeXmlQueryThreadObject(this); + m_mutex.unlock(); + + processJobs(); + exec(); + + delete m_threadObject; + m_threadObject = 0; +} + +void QDeclarativeXmlQueryEngine::processJobs() +{ + QMutexLocker locker(&m_mutex); + + while (true) { + if (m_cancelledJobs.isEmpty() && m_jobs.isEmpty()) + return; + + if (!m_cancelledJobs.isEmpty()) { + for (QList::Iterator it = m_jobs.begin(); it != m_jobs.end(); ++it) { + int queryId = (*it).queryId; + if (m_cancelledJobs.remove(queryId)) + it = m_jobs.erase(it); + } + m_cancelledJobs.clear(); + } + + if (!m_jobs.isEmpty()) { + XmlQueryJob currentJob = m_jobs.takeLast(); + + locker.unlock(); + processQuery(¤tJob); + locker.relock(); + } + } +} + +QDeclarativeXmlQueryEngine *QDeclarativeXmlQueryEngine::instance(QDeclarativeEngine *engine) +{ + queryEnginesMutex.lock(); + QDeclarativeXmlQueryEngine *queryEng = queryEngines.value(engine); + if (!queryEng) { + queryEng = new QDeclarativeXmlQueryEngine(engine); + queryEngines.insert(engine, queryEng); + } + queryEnginesMutex.unlock(); + + return queryEng; +} + +void QDeclarativeXmlQueryEngine::processQuery(XmlQueryJob *job) +{ + QDeclarativeXmlQueryResult result; + result.queryId = job->queryId; + doQueryJob(job, &result); + doSubQueryJob(job, &result); + + { + QMutexLocker ml(&m_mutex); + if (m_cancelledJobs.contains(job->queryId)) { + m_cancelledJobs.remove(job->queryId); + } else { + emit queryCompleted(result); + } + } +} + +void QDeclarativeXmlQueryEngine::doQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult) { Q_ASSERT(currentJob->queryId != -1); @@ -293,7 +405,7 @@ void QDeclarativeXmlQuery::doQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQu currentResult->size = (count > 0 ? count : 0); } -void QDeclarativeXmlQuery::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const +void QDeclarativeXmlQueryEngine::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const { const QStringList &keysQueries = currentJob.keyRoleQueries; QString keysQuery; @@ -314,7 +426,7 @@ void QDeclarativeXmlQuery::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QS } } -void QDeclarativeXmlQuery::addIndexToRangeList(QList *ranges, int index) const { +void QDeclarativeXmlQueryEngine::addIndexToRangeList(QList *ranges, int index) const { if (ranges->isEmpty()) ranges->append(qMakePair(index, 1)); else if (ranges->last().first + ranges->last().second == index) @@ -323,7 +435,7 @@ void QDeclarativeXmlQuery::addIndexToRangeList(QList * ranges->append(qMakePair(index, 1)); } -void QDeclarativeXmlQuery::doSubQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult) +void QDeclarativeXmlQueryEngine::doSubQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult) { Q_ASSERT(currentJob->queryId != -1); @@ -583,10 +695,6 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListPropertyisComponentComplete = false; + + QDeclarativeXmlQueryEngine *queryEngine = QDeclarativeXmlQueryEngine::instance(qmlEngine(this)); + connect(queryEngine, SIGNAL(queryCompleted(QDeclarativeXmlQueryResult)), + SLOT(queryCompleted(QDeclarativeXmlQueryResult))); + connect(queryEngine, SIGNAL(error(void*,QString)), + SLOT(queryError(void*,QString))); } void QDeclarativeXmlListModel::componentComplete() @@ -881,7 +995,7 @@ void QDeclarativeXmlListModel::reload() if (!d->isComponentComplete) return; - globalXmlQuery()->abort(d->queryId); + QDeclarativeXmlQueryEngine::instance(qmlEngine(this))->abort(d->queryId); d->queryId = -1; if (d->size < 0) @@ -897,7 +1011,7 @@ void QDeclarativeXmlListModel::reload() } if (!d->xml.isEmpty()) { - d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache); + d->queryId = QDeclarativeXmlQueryEngine::instance(qmlEngine(this))->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache); d->notifyQueryStarted(false); } else if (d->src.isEmpty()) { @@ -958,7 +1072,7 @@ void QDeclarativeXmlListModel::requestFinished() d->queryId = XMLLISTMODEL_CLEAR_ID; QTimer::singleShot(0, this, SLOT(dataCleared())); } else { - d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache); + d->queryId = QDeclarativeXmlQueryEngine::instance(qmlEngine(this))->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache); } disconnect(d->reply, 0, this, 0); d->reply->deleteLater(); -- cgit v0.12 From 29d988d113aac1a193d3af6247a6e8231f3f3c9e Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 4 Aug 2011 12:00:53 +1000 Subject: Don't release register prematurely Task-number: QTBUG-20648 --- src/declarative/qml/qdeclarativecompiledbindings.cpp | 5 ++--- .../declarative/qdeclarativeecmascript/data/qtbug_20648.qml | 7 +++++++ .../qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp | 10 ++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20648.qml diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp index 7f2cac2..51ffc10 100644 --- a/src/declarative/qml/qdeclarativecompiledbindings.cpp +++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp @@ -2396,7 +2396,7 @@ bool QDeclarativeBindingCompilerPrivate::parseConditional(QDeclarativeJS::AST::N skip.skip.reg = -1; bytecode << skip; - // Release to allow reuse of reg + // Release to allow reuse of reg in else path releaseReg(ok.reg); bytecode[skipIdx].skip.count = bytecode.count() - skipIdx - 1; @@ -2406,8 +2406,7 @@ bool QDeclarativeBindingCompilerPrivate::parseConditional(QDeclarativeJS::AST::N if (!parseExpression(expression->ko, ko)) return false; if (ko.unknownType) return false; - // Release to allow reuse of reg - releaseReg(ko.reg); + // Do not release reg here, so that its ownership passes to the caller bytecode[skipIdx2].skip.count = bytecode.count() - skipIdx2 - 1; if (ok != ko) diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20648.qml b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20648.qml new file mode 100644 index 0000000..40f21ef --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/qtbug_20648.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +QtObject { + property bool hd: true + + property real test: ((hd ? 100 : 20) + 0) +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 71214a3..bf7c9a4 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -177,6 +177,7 @@ private slots: void aliasWritesOverrideBindings(); void pushCleanContext(); void realToInt(); + void qtbug_20648(); void include(); @@ -3090,6 +3091,15 @@ void tst_qdeclarativeecmascript::realToInt() QCOMPARE(object->value(), int(8)); } +void tst_qdeclarativeecmascript::qtbug_20648() +{ + QDeclarativeComponent component(&engine, TEST_FILE("qtbug_20648.qml")); + QObject *o = component.create(); + QVERIFY(o != 0); + QCOMPARE(o->property("test").toInt(), 100); + delete o; +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" -- cgit v0.12 From 922b77c50dd3ae4f772d541e82d2e5f30a05b400 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 4 Aug 2011 14:27:35 +1000 Subject: Compile on symbian --- src/declarative/qml/qdeclarativevme.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 221e52c..a23f89d 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -1099,7 +1099,7 @@ void QDeclarativeVMEStack::push(const T &o) { Q_ASSERT(_index <= VLA::size()); if (_index == VLA::size()) - append(o); + VLA::append(o); else VLA::data()[_index] = o; } -- cgit v0.12 From ce36e8afa47e3625737208b5a912f9f191a59678 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Tue, 9 Aug 2011 14:23:50 +1000 Subject: Don't endless loop Task-number: QTBUG-20699 Reviewed-by: Michael Brasser --- src/gui/graphicsview/qgraphicsitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index ef53963..2ac2bdf 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -3297,7 +3297,7 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim } if (climb) { - while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible()) + while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible() && f->d_ptr->focusScopeItem != f) f = f->d_ptr->focusScopeItem; } -- cgit v0.12 From f55ecc080d0c5eca4e65a235c63ab13867c86874 Mon Sep 17 00:00:00 2001 From: Bea Lam Date: Thu, 11 Aug 2011 13:11:52 +1000 Subject: Fix race condition in processJobs() Don't modify list of running jobs when a job is aborted since the job may have just started. Wait till the next time processJobs() is invoked for a new job and discard the aborted job at that time. Regression from 422f4e8ec53b917fad09a3e671fd93048dde72ed Task-number: QTBUG-20841 --- src/declarative/util/qdeclarativexmllistmodel.cpp | 31 ++++++++--------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 5236757..77fc7de 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -289,11 +289,8 @@ int QDeclarativeXmlQueryEngine::doQuery(QString query, QString namespaces, QByte void QDeclarativeXmlQueryEngine::abort(int id) { QMutexLocker ml(&m_mutex); - if (id != -1) { + if (id != -1) m_cancelledJobs.insert(id); - if (m_threadObject) - m_threadObject->processJobs(); - } } void QDeclarativeXmlQueryEngine::run() @@ -314,25 +311,19 @@ void QDeclarativeXmlQueryEngine::processJobs() QMutexLocker locker(&m_mutex); while (true) { - if (m_cancelledJobs.isEmpty() && m_jobs.isEmpty()) + if (m_jobs.isEmpty()) return; - if (!m_cancelledJobs.isEmpty()) { - for (QList::Iterator it = m_jobs.begin(); it != m_jobs.end(); ++it) { - int queryId = (*it).queryId; - if (m_cancelledJobs.remove(queryId)) - it = m_jobs.erase(it); - } - m_cancelledJobs.clear(); - } - - if (!m_jobs.isEmpty()) { - XmlQueryJob currentJob = m_jobs.takeLast(); - - locker.unlock(); - processQuery(¤tJob); - locker.relock(); + XmlQueryJob currentJob = m_jobs.takeLast(); + while (m_cancelledJobs.remove(currentJob.queryId)) { + if (m_jobs.isEmpty()) + return; + currentJob = m_jobs.takeLast(); } + + locker.unlock(); + processQuery(¤tJob); + locker.relock(); } } -- cgit v0.12