From 8be2b24705da4bce99b3a3d588aedcfe2eb3f886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20S=C3=B8rvig?= Date: Tue, 5 May 2009 14:29:44 +0200 Subject: Fix memory leak in QFuture The held results were not cleared by QFutureInterface::operator=(QFutureInterface) Add call to resultStore().clear(), similar to the destructor. This needs to be done in the header since we know the template type here. Task-number: 252208 Reviewed-by: brad --- src/corelib/concurrent/qfutureinterface.h | 2 ++ tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp | 31 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/corelib/concurrent/qfutureinterface.h b/src/corelib/concurrent/qfutureinterface.h index 85d03c9..345bebe 100644 --- a/src/corelib/concurrent/qfutureinterface.h +++ b/src/corelib/concurrent/qfutureinterface.h @@ -165,6 +165,8 @@ public: QFutureInterface &operator=(const QFutureInterface &other) { + if (referenceCountIsOne()) + resultStore().clear(); QFutureInterfaceBase::operator=(other); return *this; } diff --git a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp index 139eb6e..116f46e 100644 --- a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -74,6 +74,7 @@ private slots: void incrementalResults(); void noDetatch(); void stlContainers(); + void qFutureAssignmentLeak(); void stressTest(); public slots: void throttling(); @@ -2323,6 +2324,36 @@ void tst_map::stlContainers() #endif } +InstanceCounter ic_fn(const InstanceCounter & ic) +{ + return InstanceCounter(ic); +}; + +// Verify that held results are deleted when a future is +// assigned over with operator == +void tst_map::qFutureAssignmentLeak() +{ + currentInstanceCount = 0; + peakInstanceCount = 0; + QFuture future; + { + QList list; + for (int i=0;i<1000;++i) + list += InstanceCounter(); + future = QtConcurrent::mapped(list, ic_fn); + future.waitForFinished(); + + future = QtConcurrent::mapped(list, ic_fn); + future.waitForFinished(); + + future = QtConcurrent::mapped(list, ic_fn); + future.waitForFinished(); + } + + QCOMPARE(int(currentInstanceCount), 1000); + future = QFuture(); + QCOMPARE(int(currentInstanceCount), 0); +} inline void increment(int &num) { -- cgit v0.12