diff options
author | Andrei Golubev <andrei.golubev@qt.io> | 2021-03-24 16:47:33 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-04-27 07:39:49 +0000 |
commit | 8e95bba272bc2aadc2e2dd4ad66dab489cb70387 (patch) | |
tree | 3c07b75d4b9460e4e26e9d1b37c88a682f389127 /tests/auto/corelib/tools/qlist/tst_qlist.cpp | |
parent | ad496ea3b5ae79172af3a0231a65ae7c7ee44492 (diff) |
Resurrect data moves in QList
Use the data moves to readjust the free space in the QList,
which ultimately fixes the out-of-memory issues caused by
cases like:
forever {
list.prepend(list.back());
list.removeLast();
}
Task-number: QTBUG-91801
Task-number: QTBUG-91360
Task-number: QTBUG-93019
Change-Id: Iacff69cbf36b8b5b176bb2663df635ec972c875c
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
(cherry picked from commit a0253f5f0249024580050e4ec22d50cb139ef8d9)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests/auto/corelib/tools/qlist/tst_qlist.cpp')
-rw-r--r-- | tests/auto/corelib/tools/qlist/tst_qlist.cpp | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/tests/auto/corelib/tools/qlist/tst_qlist.cpp b/tests/auto/corelib/tools/qlist/tst_qlist.cpp index d977e1cb97..c4b338f0f2 100644 --- a/tests/auto/corelib/tools/qlist/tst_qlist.cpp +++ b/tests/auto/corelib/tools/qlist/tst_qlist.cpp @@ -347,8 +347,13 @@ private slots: void emplaceWithElementFromTheSameContainer_data(); void fromReadOnlyData() const; - void qtbug_90359() const; + void reinsertToBeginInt_qtbug91360() const { reinsertToBegin<int>(); } + void reinsertToBeginMovable_qtbug91360() const { reinsertToBegin<Movable>(); } + void reinsertToBeginCustom_qtbug91360() const { reinsertToBegin<Custom>(); } + void reinsertToEndInt_qtbug91360() const { reinsertToEnd<int>(); } + void reinsertToEndMovable_qtbug91360() const { reinsertToEnd<Movable>(); } + void reinsertToEndCustom_qtbug91360() const { reinsertToEnd<Custom>(); } private: template<typename T> void copyConstructor() const; @@ -378,6 +383,10 @@ private: template<typename T> void detachThreadSafety() const; template<typename T> void emplaceImpl() const; template<typename T> void emplaceConsistentWithStdVectorImpl() const; + template<typename T> + void reinsertToBegin() const; + template<typename T> + void reinsertToEnd() const; }; @@ -3264,5 +3273,53 @@ void tst_QList::qtbug_90359() const QCOMPARE(actual, expected); } +template<typename T> +void tst_QList::reinsertToBegin() const +{ + QList<T> list(1); + const auto reinsert = [](QList<T> &list) { + list.prepend(list.back()); + list.removeLast(); + }; + + // this constant is big enough for the QList to stop reallocating, after + // all, size is always less than 3 + const int maxIters = 128; + for (int i = 0; i < maxIters; ++i) { + reinsert(list); + } + + // if QList continues to grow, it's an error + qsizetype capacity = list.capacity(); + for (int i = 0, enoughIters = int(capacity) * 2; i < enoughIters; ++i) { + reinsert(list); + QCOMPARE(capacity, list.capacity()); + } +} + +template<typename T> +void tst_QList::reinsertToEnd() const +{ + QList<T> list(1); + const auto reinsert = [](QList<T> &list) { + list.append(list.front()); + list.removeFirst(); + }; + + // this constant is big enough for the QList to stop reallocating, after + // all, size is always less than 3 + const int maxIters = 128; + for (int i = 0; i < maxIters; ++i) { + reinsert(list); + } + + // if QList continues to grow, it's an error + qsizetype capacity = list.capacity(); + for (int i = 0, enoughIters = int(capacity) * 2; i < enoughIters; ++i) { + reinsert(list); + QCOMPARE(capacity, list.capacity()); + } +} + QTEST_MAIN(tst_QList) #include "tst_qlist.moc" |