diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2019-10-25 08:41:37 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2019-10-28 08:13:45 +0200 |
commit | fe790f1537d17fca586a2c6ea7f57c02cfab1b88 (patch) | |
tree | 16ca2da51f5ab317d2e4561e16dd395b358dd222 /src | |
parent | 048ca3b1c5227de50fc755270dc316767b465936 (diff) |
QNode::updateNode: ensure postConstructorInit of node is called
When a QNode subclass is created doing Subclass(parent) with parent != nullptr
QNodePrivate::_q_postContrustorInit is called through a queued invocation
due to the fact that the QNode ctor is called before the subclass ctor is
(and we need the class to be fully constructed to do proper initialization).
When adding a QNode subclass created as described above, and immediately
referencing it as a property of another QNode, we can end up in cases where
the backend gets aware of the node being referenced in the relationship and
tries to create its backend. Unfortunately due to the queued invocation of
_q_postConstructorInit, the frontend node has yet to be fully initialized,
resulting in the creation of the backend node to assert/crash.
Therefore, when updateNode is called (whenever a subnode is referenced in a
relationship) we now ensure that postConstructorInit gets (or has already been)
called.
Change-Id: Iea6e0b5a59c676f5db2946bec2f8c345accc32b0
Task-number: QTBUG-79350
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/nodes/qnode.cpp | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp index cfe83f4db..739b46cfe 100644 --- a/src/core/nodes/qnode.cpp +++ b/src/core/nodes/qnode.cpp @@ -683,6 +683,11 @@ void QNodePrivate::update() void QNodePrivate::updateNode(QNode *node, const char *property, ChangeFlag change) { if (m_changeArbiter) { + // Ensure node has its postConstructorInit called if we reach this + // point, we could otherwise endup referencing a node that has yet + // to be created in the backend + QNodePrivate::get(node)->_q_ensureBackendNodeCreated(); + Q_Q(QNode); m_changeArbiter->addDirtyFrontEndNode(q, node, property, change); } |