diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-11-02 17:08:16 +0000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-11-04 13:00:47 +0100 |
commit | 4a8871d3fe6c9fe16752697abf95d3a7b8fba7b7 (patch) | |
tree | e7c7d5dcefe2bdebe6d7aeb58ffcda6f5572c4c8 /src/declarative/qml/qdeclarativecontext.cpp | |
parent | f9261feb16d02e985982dd46783ea54c2cfce91b (diff) |
Don't crash if contexts are deleted during refreshExpressions
Change-Id: I23b59d33c07b017ef7355a7fe4a728d84c5d7eaa
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Diffstat (limited to 'src/declarative/qml/qdeclarativecontext.cpp')
-rw-r--r-- | src/declarative/qml/qdeclarativecontext.cpp | 87 |
1 files changed, 73 insertions, 14 deletions
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index c4fc764e7d..d7a642460c 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -653,23 +653,82 @@ void QDeclarativeContextData::setParent(QDeclarativeContextData *p, bool parentT } } -/* -Refreshes all expressions that could possibly depend on this context. Refreshing flushes all -context-tree dependent caches in the expressions, and should occur every time the context tree - *structure* (not values) changes. -*/ -void QDeclarativeContextData::refreshExpressions() +void QDeclarativeContextData::refreshExpressionsRecursive(QDeclarativeAbstractExpression *expression) { - QDeclarativeContextData *child = childContexts; - while (child) { - child->refreshExpressions(); - child = child->nextChild; - } + QDeleteWatcher w(expression); - QDeclarativeAbstractExpression *expression = expressions; - while (expression) { + if (expression->m_nextExpression) + refreshExpressionsRecursive(expression->m_nextExpression); + + if (!w.wasDeleted()) expression->refresh(); - expression = expression->m_nextExpression; +} + +void QDeclarativeContextData::refreshExpressionsRecursive() +{ + // For efficiency, we try and minimize the number of guards we have to create + if (expressions && (nextChild || childContexts)) { + QDeclarativeGuardedContextData guard(this); + + if (childContexts) + childContexts->refreshExpressionsRecursive(); + + if (guard.isNull()) return; + + if (nextChild) + nextChild->refreshExpressionsRecursive(); + + if (guard.isNull()) return; + + if (expressions) + refreshExpressionsRecursive(expressions); + + } else if (expressions) { + + refreshExpressionsRecursive(expressions); + + } else if (nextChild && childContexts) { + + QDeclarativeGuardedContextData guard(this); + + childContexts->refreshExpressionsRecursive(); + + if (!guard.isNull() && nextChild) + nextChild->refreshExpressionsRecursive(); + + } else if (nextChild) { + + nextChild->refreshExpressionsRecursive(); + + } else if (childContexts) { + + childContexts->refreshExpressionsRecursive(); + + } +} + +// Refreshes all expressions that could possibly depend on this context. Refreshing flushes all +// context-tree dependent caches in the expressions, and should occur every time the context tree +// *structure* (not values) changes. +void QDeclarativeContextData::refreshExpressions() +{ + // For efficiency, we try and minimize the number of guards we have to create + if (expressions && childContexts) { + QDeclarativeGuardedContextData guard(this); + + childContexts->refreshExpressionsRecursive(); + + if (!guard.isNull() && expressions) + refreshExpressionsRecursive(expressions); + + } else if (expressions) { + + refreshExpressionsRecursive(expressions); + + } else if (childContexts) { + + childContexts->refreshExpressionsRecursive(); + } } |