diff options
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qfutureinterface.h | 17 | ||||
-rw-r--r-- | src/corelib/thread/qpromise.qdoc | 3 | ||||
-rw-r--r-- | src/corelib/thread/qresultstore.cpp | 14 | ||||
-rw-r--r-- | src/corelib/thread/qresultstore.h | 23 |
4 files changed, 49 insertions, 8 deletions
diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h index 6c7c511cc0..9296c63f0b 100644 --- a/src/corelib/thread/qfutureinterface.h +++ b/src/corelib/thread/qfutureinterface.h @@ -270,11 +270,12 @@ inline void QFutureInterface<T>::reportResult(const T *result, int index) if (store.filterMode()) { const int resultCountBefore = store.count(); - store.addResult<T>(index, result); - this->reportResultsReady(resultCountBefore, store.count()); + if (store.addResult<T>(index, result) != -1) + this->reportResultsReady(resultCountBefore, store.count()); } else { const int insertIndex = store.addResult<T>(index, result); - this->reportResultsReady(insertIndex, insertIndex + 1); + if (insertIndex != -1) + this->reportResultsReady(insertIndex, insertIndex + 1); } } @@ -289,7 +290,8 @@ void QFutureInterface<T>::reportAndMoveResult(T &&result, int index) const int oldResultCount = store.count(); const int insertIndex = store.moveResult(index, std::forward<T>(result)); - if (!store.filterMode() || oldResultCount < store.count()) // Let's make sure it's not in pending results. + // Let's make sure it's not in pending results. + if (insertIndex != -1 && (!store.filterMode() || oldResultCount < store.count())) reportResultsReady(insertIndex, store.count()); } @@ -317,11 +319,12 @@ inline void QFutureInterface<T>::reportResults(const QList<T> &_results, int beg if (store.filterMode()) { const int resultCountBefore = store.count(); - store.addResults(beginIndex, &_results, count); - this->reportResultsReady(resultCountBefore, store.count()); + if (store.addResults(beginIndex, &_results, count) != -1) + this->reportResultsReady(resultCountBefore, store.count()); } else { const int insertIndex = store.addResults(beginIndex, &_results, count); - this->reportResultsReady(insertIndex, insertIndex + _results.count()); + if (insertIndex != -1) + this->reportResultsReady(insertIndex, insertIndex + _results.count()); } } diff --git a/src/corelib/thread/qpromise.qdoc b/src/corelib/thread/qpromise.qdoc index 9c7925da95..4b7b497b3f 100644 --- a/src/corelib/thread/qpromise.qdoc +++ b/src/corelib/thread/qpromise.qdoc @@ -112,6 +112,9 @@ Adds \a result to the internal result collection at \a index position. If index is unspecified, \a result is added to the end of the collection. + \note addResult() rejects \a result if there's already another result in the + collection stored at the same index. + You can get a result at a specific index by calling QFuture::resultAt(). \note It is possible to specify an arbitrary index and request result at diff --git a/src/corelib/thread/qresultstore.cpp b/src/corelib/thread/qresultstore.cpp index b6af27dfa9..a239954dbe 100644 --- a/src/corelib/thread/qresultstore.cpp +++ b/src/corelib/thread/qresultstore.cpp @@ -144,6 +144,11 @@ bool ResultIteratorBase::canIncrementVectorIndex() const return (m_vectorIndex + 1 < mapIterator.value().m_count); } +bool ResultIteratorBase::isValid() const +{ + return mapIterator.value().isValid(); +} + ResultStoreBase::ResultStoreBase() : insertIndex(0), resultCount(0), m_filterMode(false), filteredResults(0) { } @@ -196,6 +201,15 @@ int ResultStoreBase::insertResultItem(int index, ResultItem &resultItem) return storeIndex; } +bool ResultStoreBase::containsValidResultItem(int index) const +{ + // index might refer to either visible or pending result + const bool inPending = m_filterMode && index != -1 && index > insertIndex; + const auto &store = inPending ? pendingResults : m_results; + auto it = findResult(store, index); + return it != ResultIteratorBase(store.end()) && it.isValid(); +} + void ResultStoreBase::syncPendingResults() { // check if we can insert any of the pending results: diff --git a/src/corelib/thread/qresultstore.h b/src/corelib/thread/qresultstore.h index 5f8c7f150a..0a1382fd79 100644 --- a/src/corelib/thread/qresultstore.h +++ b/src/corelib/thread/qresultstore.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -87,6 +87,8 @@ public: bool operator!=(const ResultIteratorBase &other) const; bool isVector() const; bool canIncrementVectorIndex() const; + bool isValid() const; + protected: QMap<int, ResultItem>::const_iterator mapIterator; int m_vectorIndex; @@ -139,6 +141,7 @@ public: protected: int insertResultItem(int index, ResultItem &resultItem); void insertResultItemIfValid(int index, ResultItem &resultItem); + bool containsValidResultItem(int index) const; void syncPendingResults(); void syncResultCount(); int updateInsertIndex(int index, int _count); @@ -169,6 +172,9 @@ public: template <typename T> int addResult(int index, const T *result) { + if (containsValidResultItem(index)) // reject if already present + return -1; + if (result == nullptr) return addResult(index, static_cast<void *>(nullptr)); @@ -178,18 +184,27 @@ public: template <typename T> int moveResult(int index, T &&result) { + if (containsValidResultItem(index)) // reject if already present + return -1; + return addResult(index, static_cast<void *>(new T(std::move_if_noexcept(result)))); } template<typename T> int addResults(int index, const QList<T> *results) { + if (containsValidResultItem(index)) // reject if already present + return -1; + return addResults(index, new QList<T>(*results), results->count(), results->count()); } template<typename T> int addResults(int index, const QList<T> *results, int totalCount) { + if (containsValidResultItem(index)) // reject if already present + return -1; + if (m_filterMode == true && results->count() != totalCount && 0 == results->count()) return addResults(index, nullptr, 0, totalCount); @@ -198,12 +213,18 @@ public: int addCanceledResult(int index) { + if (containsValidResultItem(index)) // reject if already present + return -1; + return addResult(index, static_cast<void *>(nullptr)); } template <typename T> int addCanceledResults(int index, int _count) { + if (containsValidResultItem(index)) // reject if already present + return -1; + QList<T> empty; return addResults(index, &empty, _count); } |