summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2012-12-17 00:28:44 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-12-17 19:50:33 +0100
commitcc89509f831111aadf869b1065ec1ae01f6759b8 (patch)
tree9fb2f6bea8bccd903ec6a9f1ecba2b11f0feaa9f /tests
parentc4f433d581e2d609d2eaecc4e4b999a469950eb3 (diff)
Delete the QSlotObject when disconnect()ing
When disconnect()ing through a QMetaObject::Connection, if the QObjectPrivate::Connection contains a slot object, deref it, so that it will be destroyed before the next run of cleanConnectionList. Previously, a copy of the functor passed to connect() was kept until QObjectPrivate::cleanConnectionLists was called (by adding a new signal, or the sender was destroyed), even after a successful call to disconnect(). That is, we were keeping that copy allocated without any good reason. Change-Id: Ie6074ea797df1611cb995dec07c5b5a742360833 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp47
1 files changed, 39 insertions, 8 deletions
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index 76a97f89f4..581644b19f 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -5594,12 +5594,8 @@ void tst_QObject::disconnectDoesNotLeakFunctor()
QVERIFY(c);
QCOMPARE(countedStructObjectsCount, 2);
QVERIFY(QObject::disconnect(c));
- // the connection list has been marked dirty, but not cleaned yet.
- QCOMPARE(countedStructObjectsCount, 2);
+ QCOMPARE(countedStructObjectsCount, 1);
}
- // disconnect() dropped the reference that c had to the functor;
- // the sender has been destroyed. Therefore, the QObjectPrivate::Connection
- // refcount dropped to zero and destroyed the functor.
QCOMPARE(countedStructObjectsCount, 0);
}
QCOMPARE(countedStructObjectsCount, 0);
@@ -5616,11 +5612,46 @@ void tst_QObject::disconnectDoesNotLeakFunctor()
QVERIFY(c2);
QCOMPARE(countedStructObjectsCount, 2);
QVERIFY(QObject::disconnect(c1));
- // the connection list has been marked dirty, but not cleaned yet.
- QCOMPARE(countedStructObjectsCount, 2);
+ // functor object has been destroyed
+ QCOMPARE(countedStructObjectsCount, 1);
}
- // c2 still holds a reference; c1 has been cleaned up
+ QCOMPARE(countedStructObjectsCount, 0);
+ }
+ QCOMPARE(countedStructObjectsCount, 0);
+ {
+ CountedStruct s;
+ QCOMPARE(countedStructObjectsCount, 1);
+ QTimer timer;
+
+ QMetaObject::Connection c = connect(&timer, &QTimer::timeout, s);
+ QVERIFY(c);
+ QCOMPARE(countedStructObjectsCount, 2);
+ QVERIFY(QObject::disconnect(c));
+ QCOMPARE(countedStructObjectsCount, 1);
+ }
+ QCOMPARE(countedStructObjectsCount, 0);
+ {
+ QTimer timer;
+
+ QMetaObject::Connection c = connect(&timer, &QTimer::timeout, CountedStruct());
+ QVERIFY(c);
+ QCOMPARE(countedStructObjectsCount, 1); // only one instance, in Qt internals
+ QVERIFY(QObject::disconnect(c));
+ QCOMPARE(countedStructObjectsCount, 0); // functor being destroyed
+ }
+ QCOMPARE(countedStructObjectsCount, 0);
+ {
+#if defined(Q_COMPILER_LAMBDA)
+ CountedStruct s;
+ QCOMPARE(countedStructObjectsCount, 1);
+ QTimer timer;
+
+ QMetaObject::Connection c = connect(&timer, &QTimer::timeout, [s](){});
+ QVERIFY(c);
+ QCOMPARE(countedStructObjectsCount, 2);
+ QVERIFY(QObject::disconnect(c));
QCOMPARE(countedStructObjectsCount, 1);
+#endif // Q_COMPILER_LAMBDA
}
QCOMPARE(countedStructObjectsCount, 0);
}