summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2011-12-09 10:58:14 +0100
committerQt by Nokia <qt-info@nokia.com>2011-12-10 16:11:42 +0100
commita6ae75f92a8628c727a9c5a9961fa91c583c008e (patch)
tree7a6ee9f7b80126fc1616043fa12ff9fe66d45619 /src
parentfb8dc15ba6d24452d819ab40b1dd4227e36a9c2c (diff)
Don't overload the meaning of QObjectData::wasDeleted
The union in QObjectPrivate of declarativeData and currentChildBeingDeleted shouldn't use wasDeleted to determining the meaning of the unioned pointer. Instead, add QObjectData::isDeletingChildren, set that in QObjectPrivate::deleteChildren(), and only use the currentChildBeingDeleted member when the parent's isDeletingChildren is set. This solves aborts seen in autotests when widgets are deleting window children. The abort comes from QWeakPointer on the parent in the child's close event handler (the abort checks that wasDeleted is not set). Change-Id: I1a58449159d4a5312aad8ba12e559d05d6c43d93 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com> Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/kernel/qobject.cpp13
-rw-r--r--src/corelib/kernel/qobject.h1
2 files changed, 8 insertions, 6 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index e4ef826ffd..f6e72e3e94 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -165,6 +165,7 @@ QObjectPrivate::QObjectPrivate(int version)
pendTimer = false; // no timers yet
blockSig = false; // not blocking signals
wasDeleted = false; // double-delete catcher
+ isDeletingChildren = false; // set by deleteChildren()
sendChildEvents = true; // if we should send ChildInsert and ChildRemove events to parent
receiveChildEvents = true;
postedEvents = 0;
@@ -1774,8 +1775,8 @@ void QObject::setParent(QObject *parent)
void QObjectPrivate::deleteChildren()
{
- const bool reallyWasDeleted = wasDeleted;
- wasDeleted = true;
+ Q_ASSERT_X(!isDeletingChildren, "QObjectPrivate::deleteChildren()", "isDeletingChildren already set, did this function recurse?");
+ isDeletingChildren = true;
// delete children objects
// don't use qDeleteAll as the destructor of the child might
// delete siblings
@@ -1786,7 +1787,7 @@ void QObjectPrivate::deleteChildren()
}
children.clear();
currentChildBeingDeleted = 0;
- wasDeleted = reallyWasDeleted;
+ isDeletingChildren = false;
}
void QObjectPrivate::setParent_helper(QObject *o)
@@ -1796,13 +1797,13 @@ void QObjectPrivate::setParent_helper(QObject *o)
return;
if (parent) {
QObjectPrivate *parentD = parent->d_func();
- if (parentD->wasDeleted && wasDeleted
+ if (parentD->isDeletingChildren && wasDeleted
&& parentD->currentChildBeingDeleted == q) {
// don't do anything since QObjectPrivate::deleteChildren() already
// cleared our entry in parentD->children.
} else {
const int index = parentD->children.indexOf(q);
- if (parentD->wasDeleted) {
+ if (parentD->isDeletingChildren) {
parentD->children[index] = 0;
} else {
parentD->children.removeAt(index);
@@ -1829,7 +1830,7 @@ void QObjectPrivate::setParent_helper(QObject *o)
}
}
}
- if (!wasDeleted && declarativeData)
+ if (!isDeletingChildren && declarativeData)
QAbstractDeclarativeData::parentChanged(declarativeData, q, o);
}
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 307518d81e..cc2ccb9e5b 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -99,6 +99,7 @@ public:
uint pendTimer : 1;
uint blockSig : 1;
uint wasDeleted : 1;
+ uint isDeletingChildren : 1;
uint ownObjectName : 1;
uint sendChildEvents : 1;
uint receiveChildEvents : 1;