summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorChristian Strømme <christian.stromme@digia.com>2012-10-25 12:32:52 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-11-01 16:09:29 +0100
commit731ba8ed08f80644b403556638c7f6229e678ebe (patch)
tree437ce138749ffc39a6ee17d77b1fc0d393d44aa7 /tests/auto
parentd45cebbf4d6a8fd2406f41e151a63c9f241879f7 (diff)
Fix for leak in QFuture
To avoid leaking when converting a QFuture<T> to a QFuture<void> we need to have a separate ref. counter for QFuture<T>. When the last QFuture<T> goes out of scope, we need to clean out the result data. Task-number: QTBUG-27224 Change-Id: I965a64a11fffbb191ab979cdd030a9aafd4436c2 Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp43
-rw-r--r--tests/auto/corelib/thread/qfuture/tst_qfuture.cpp30
2 files changed, 65 insertions, 8 deletions
diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
index c50e3839b5..b6bc5b085b 100644
--- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
+++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp
@@ -43,6 +43,7 @@
#include <qdebug.h>
#include <QThread>
+#include <QMutex>
#include <QtTest/QtTest>
@@ -75,6 +76,7 @@ private slots:
void stlContainers();
void qFutureAssignmentLeak();
void stressTest();
+ void persistentResultTest();
public slots:
void throttling();
};
@@ -2395,5 +2397,46 @@ void tst_QtConcurrentMap::stressTest()
}
}
+struct LockedCounter
+{
+ LockedCounter(QMutex *mutex, QAtomicInt *ai)
+ : mtx(mutex),
+ ref(ai) {}
+
+ typedef int result_type;
+ int operator()(int x)
+ {
+ QMutexLocker locker(mtx);
+ ref->ref();
+ return ++x;
+ }
+
+ QMutex *mtx;
+ QAtomicInt *ref;
+};
+
+// The Thread engine holds the last reference
+// to the QFuture, so this should not leak
+// or fail.
+void tst_QtConcurrentMap::persistentResultTest()
+{
+ QFuture<void> voidFuture;
+ QMutex mtx;
+ QAtomicInt ref;
+ LockedCounter lc(&mtx, &ref);
+ QList<int> list;
+ {
+ list << 1 << 2 << 3;
+ mtx.lock();
+ QFuture<int> future = QtConcurrent::mapped(list
+ ,lc);
+ voidFuture = future;
+ }
+ QCOMPARE(ref.loadAcquire(), 0);
+ mtx.unlock(); // Unblock
+ voidFuture.waitForFinished();
+ QCOMPARE(ref.loadAcquire(), 3);
+}
+
QTEST_MAIN(tst_QtConcurrentMap)
#include "tst_qtconcurrentmap.moc"
diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
index 81ba1b0fd9..6d73755cfc 100644
--- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
+++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp
@@ -1251,18 +1251,32 @@ void tst_QFuture::throttling()
void tst_QFuture::voidConversions()
{
- QFutureInterface<int> iface;
- iface.reportStarted();
+ {
+ QFutureInterface<int> iface;
+ iface.reportStarted();
- QFuture<int> intFuture(&iface);
+ QFuture<int> intFuture(&iface);
+ int value = 10;
+ iface.reportFinished(&value);
- int value = 10;
- iface.reportFinished(&value);
+ QFuture<void> voidFuture(intFuture);
+ voidFuture = intFuture;
+
+ QVERIFY(voidFuture == intFuture);
+ }
- QFuture<void> voidFuture(intFuture);
- voidFuture = intFuture;
+ {
+ QFuture<void> voidFuture;
+ {
+ QFutureInterface<QList<int> > iface;
+ iface.reportStarted();
- QVERIFY(voidFuture == intFuture);
+ QFuture<QList<int> > listFuture(&iface);
+ iface.reportResult(QList<int>() << 1 << 2 << 3);
+ voidFuture = listFuture;
+ }
+ QCOMPARE(voidFuture.resultCount(), 0);
+ }
}