Fix QProperty
This fixes two issues with QPropery: 1. QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged calls a user provided evaluaton function. That one might actually destroy the binding and delete the QPropertyBindingPrivate instance. We need however to keep it alive until the function returns. 2. There was an infinite loop between QPropertyObserverPointer::notify and QPropertyBindingPrivate::markDirtyAndNotifyObservers. This can be observed when running tst_palette in qqc2. By returning early in markDirtyAndNotifyObservers if dirty is already set, the issue is avoided. Change-Id: I1f0df05a5a9fa98554183263a25e16747c4d2274 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Simon Hausmann <hausmann@gmail.com>
This commit is contained in:
parent
41ceb88fe1
commit
c2fb27f054
@ -64,6 +64,8 @@ void QPropertyBindingPrivate::unlinkAndDeref()
|
||||
|
||||
void QPropertyBindingPrivate::markDirtyAndNotifyObservers()
|
||||
{
|
||||
if (dirty)
|
||||
return;
|
||||
dirty = true;
|
||||
if (firstObserver)
|
||||
firstObserver.notify(this, propertyDataPtr);
|
||||
@ -81,6 +83,15 @@ bool QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged()
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluating the binding might lead to the binding being broken. This can
|
||||
* cause ref to reach zero at the end of the function. However, the
|
||||
* updateGuard's destructor will then still trigger, trying to set the
|
||||
* updating bool to its old value
|
||||
* To prevent this, we create a QPropertyBindingPrivatePtr which ensures
|
||||
* that the object is still alive when updateGuard's dtor runs.
|
||||
*/
|
||||
QPropertyBindingPrivatePtr keepAlive {this};
|
||||
QScopedValueRollback<bool> updateGuard(updating, true);
|
||||
|
||||
BindingEvaluationState evaluationFrame(this);
|
||||
|
Loading…
Reference in New Issue
Block a user