Remove some aggregation deadlocks.

You are not allowed to add components that belong to other aggregate
(including aggregates themselves). Warn in this case instead of locking
up.

Task-number: QTCREATORBUG-4926
Change-Id: I4908fb9019efbc2fa3b7c3c57e08cc1d7f8f3e2c
Reviewed-on: http://codereview.qt.nokia.com/679
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Bill King <bill.king@nokia.com>
This commit is contained in:
con
2011-06-23 16:20:38 +02:00
committed by Bill King
parent 78fa1bb0aa
commit f3e22da48c
2 changed files with 17 additions and 2 deletions

View File

@@ -33,6 +33,7 @@
#include "aggregate.h" #include "aggregate.h"
#include <QtCore/QWriteLocker> #include <QtCore/QWriteLocker>
#include <QtCore/QDebug>
/*! /*!
\namespace Aggregation \namespace Aggregation
@@ -228,6 +229,8 @@ void Aggregate::deleteSelf(QObject *obj)
\fn void Aggregate::add(QObject *component) \fn void Aggregate::add(QObject *component)
Adds the \a component to the aggregate. Adds the \a component to the aggregate.
You can't add a component that is part of a different aggregate
or an aggregate itself.
\sa Aggregate::remove() \sa Aggregate::remove()
*/ */
@@ -240,8 +243,10 @@ void Aggregate::add(QObject *component)
Aggregate *parentAggregation = aggregateMap().value(component); Aggregate *parentAggregation = aggregateMap().value(component);
if (parentAggregation == this) if (parentAggregation == this)
return; return;
if (parentAggregation) if (parentAggregation) {
parentAggregation->remove(component); qWarning() << "Cannot add a component that belongs to a different aggregate" << component;
return;
}
m_components.append(component); m_components.append(component);
connect(component, SIGNAL(destroyed(QObject*)), this, SLOT(deleteSelf(QObject*))); connect(component, SIGNAL(destroyed(QObject*)), this, SLOT(deleteSelf(QObject*)));
aggregateMap().insert(component, this); aggregateMap().insert(component, this);

View File

@@ -185,6 +185,7 @@ void tst_Aggregate::queryAll()
void tst_Aggregate::parentAggregate() void tst_Aggregate::parentAggregate()
{ {
Aggregation::Aggregate aggregation; Aggregation::Aggregate aggregation;
Aggregation::Aggregate aggregation2;
Interface1 *component1 = new Interface1; Interface1 *component1 = new Interface1;
Interface11 *component11 = new Interface11; Interface11 *component11 = new Interface11;
QObject *component2 = new QObject; QObject *component2 = new QObject;
@@ -194,6 +195,15 @@ void tst_Aggregate::parentAggregate()
QCOMPARE(Aggregation::Aggregate::parentAggregate(component1), &aggregation); QCOMPARE(Aggregation::Aggregate::parentAggregate(component1), &aggregation);
QCOMPARE(Aggregation::Aggregate::parentAggregate(component11), &aggregation); QCOMPARE(Aggregation::Aggregate::parentAggregate(component11), &aggregation);
QCOMPARE(Aggregation::Aggregate::parentAggregate(component2), (Aggregation::Aggregate *)0); QCOMPARE(Aggregation::Aggregate::parentAggregate(component2), (Aggregation::Aggregate *)0);
// test reparenting a component to another aggregate (should warn but not work)
aggregation2.add(component11);
QCOMPARE(Aggregation::Aggregate::parentAggregate(component11), &aggregation);
// test adding an aggregate to an aggregate (should warn but not work)
aggregation.add(&aggregation2);
QCOMPARE(Aggregation::Aggregate::parentAggregate(&aggregation2), &aggregation2);
// test removing an object from an aggregation.
aggregation.remove(component11);
QCOMPARE(Aggregation::Aggregate::parentAggregate(component11), (Aggregation::Aggregate *)0);
} }
QTEST_MAIN(tst_Aggregate) QTEST_MAIN(tst_Aggregate)