diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-03-17 09:07:38 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-03-17 09:08:54 (GMT) |
commit | d54b11fef6403693de09277a645c9666f8eea6a2 (patch) | |
tree | 46b37c15ef196dc7b2b3af6779a22b26340ecb88 | |
parent | fd63689b6202fac71e2b037f70a3ee808ba571ec (diff) | |
download | Qt-d54b11fef6403693de09277a645c9666f8eea6a2.zip Qt-d54b11fef6403693de09277a645c9666f8eea6a2.tar.gz Qt-d54b11fef6403693de09277a645c9666f8eea6a2.tar.bz2 |
Fix crash
If the notifier gets swapped out during emitting, the endpoint is also
invalidated. Thus the "disconnected" writeback must track the endpoint
not just the Notifier.
-rw-r--r-- | src/declarative/qml/qdeclarativeexpression.cpp | 1 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativenotifier.cpp | 14 | ||||
-rw-r--r-- | src/declarative/qml/qdeclarativenotifier_p.h | 2 |
3 files changed, 9 insertions, 8 deletions
diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 20863c7..9eed345 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -98,6 +98,7 @@ QDeclarativeExpressionPrivate::~QDeclarativeExpressionPrivate() if (data) { delete [] data->guardList; data->guardList = 0; + data->guardListLength = 0; data->q = 0; data->release(); data = 0; diff --git a/src/declarative/qml/qdeclarativenotifier.cpp b/src/declarative/qml/qdeclarativenotifier.cpp index 8e5904c..b12bf77 100644 --- a/src/declarative/qml/qdeclarativenotifier.cpp +++ b/src/declarative/qml/qdeclarativenotifier.cpp @@ -47,23 +47,23 @@ void QDeclarativeNotifier::emitNotify(QDeclarativeNotifierEndpoint *endpoint) { QDeclarativeNotifierEndpoint::Notifier *n = endpoint->asNotifier(); - QDeclarativeNotifierEndpoint::Notifier **oldDisconnected = n->disconnected; - n->disconnected = &n; + QDeclarativeNotifierEndpoint **oldDisconnected = n->disconnected; + n->disconnected = &endpoint; if (n->next) emitNotify(n->next); - if (n) { + if (endpoint) { void *args[] = { 0 }; QMetaObject::metacall(endpoint->target, QMetaObject::InvokeMetaMethod, endpoint->targetMethod, args); - if (n) - n->disconnected = oldDisconnected; + if (endpoint) + endpoint->asNotifier()->disconnected = oldDisconnected; } - if (oldDisconnected) *oldDisconnected = n; + if (oldDisconnected) *oldDisconnected = endpoint; } void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &other) @@ -89,7 +89,7 @@ void QDeclarativeNotifierEndpoint::copyAndClear(QDeclarativeNotifierEndpoint &ot other_n->notifier = n->notifier; other_n->disconnected = n->disconnected; - if (other_n->disconnected) *other_n->disconnected = other_n; + if (other_n->disconnected) *other_n->disconnected = &other; if (n->next) { other_n->next = n->next; diff --git a/src/declarative/qml/qdeclarativenotifier_p.h b/src/declarative/qml/qdeclarativenotifier_p.h index 2a8087e..2a9660d 100644 --- a/src/declarative/qml/qdeclarativenotifier_p.h +++ b/src/declarative/qml/qdeclarativenotifier_p.h @@ -91,7 +91,7 @@ private: struct Notifier { QDeclarativeNotifier *notifier; - Notifier **disconnected; + QDeclarativeNotifierEndpoint **disconnected; QDeclarativeNotifierEndpoint *next; QDeclarativeNotifierEndpoint **prev; |