diff options
-rw-r--r-- | src/corelib/concurrent/qfutureinterface.h | 2 | ||||
-rw-r--r-- | tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp | 31 |
2 files changed, 33 insertions, 0 deletions
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<InstanceCounter> future; + { + QList<InstanceCounter> 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<InstanceCounter>(); + QCOMPARE(int(currentInstanceCount), 0); +} inline void increment(int &num) { |