diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2012-12-17 00:28:44 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-12-17 19:50:33 +0100 |
commit | cc89509f831111aadf869b1065ec1ae01f6759b8 (patch) | |
tree | 9fb2f6bea8bccd903ec6a9f1ecba2b11f0feaa9f /tests | |
parent | c4f433d581e2d609d2eaecc4e4b999a469950eb3 (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.cpp | 47 |
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); } |