Create QFutures returned by QtFuture::when* methods via QPromise
This is required to ensure that the continuation attached to a QFuture returned by QtFuture::when* methods is cleaned in the destructor of the associated QPromise, so that it doesn't keep any ref-counted copies to the shared data, thus preventing it from being deleted. Task-number: QTBUG-99534 Pick-to: 6.3 Change-Id: If4e2929b2e638d6b48c95f0aef9dc886066cedbe Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
614847eae9
commit
afdae3618a
@ -1006,13 +1006,13 @@ struct WhenAllContext
|
|||||||
futures[index] = std::forward<T>(future);
|
futures[index] = std::forward<T>(future);
|
||||||
Q_ASSERT(count > 0);
|
Q_ASSERT(count > 0);
|
||||||
if (--count <= 0) {
|
if (--count <= 0) {
|
||||||
promise.reportResult(futures);
|
promise.addResult(futures);
|
||||||
promise.reportFinished();
|
promise.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QAtomicInteger<qsizetype> count;
|
QAtomicInteger<qsizetype> count;
|
||||||
QFutureInterface<ResultFutures> promise;
|
QPromise<ResultFutures> promise;
|
||||||
ResultFutures futures;
|
ResultFutures futures;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1025,13 +1025,13 @@ struct WhenAnyContext
|
|||||||
void checkForCompletion(qsizetype, T &&result)
|
void checkForCompletion(qsizetype, T &&result)
|
||||||
{
|
{
|
||||||
if (!ready.fetchAndStoreRelaxed(true)) {
|
if (!ready.fetchAndStoreRelaxed(true)) {
|
||||||
promise.reportResult(std::forward<T>(result));
|
promise.addResult(std::forward<T>(result));
|
||||||
promise.reportFinished();
|
promise.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QAtomicInt ready = false;
|
QAtomicInt ready = false;
|
||||||
QFutureInterface<ResultType> promise;
|
QPromise<ResultType> promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<qsizetype Index, typename ContextType, typename... Ts>
|
template<qsizetype Index, typename ContextType, typename... Ts>
|
||||||
@ -1066,7 +1066,7 @@ QFuture<OutputSequence> whenAllImpl(InputIt first, InputIt last)
|
|||||||
|
|
||||||
auto context = QSharedPointer<QtPrivate::WhenAllContext<OutputSequence>>::create(size);
|
auto context = QSharedPointer<QtPrivate::WhenAllContext<OutputSequence>>::create(size);
|
||||||
context->futures.resize(size);
|
context->futures.resize(size);
|
||||||
context->promise.reportStarted();
|
context->promise.start();
|
||||||
|
|
||||||
qsizetype idx = 0;
|
qsizetype idx = 0;
|
||||||
for (auto it = first; it != last; ++it, ++idx) {
|
for (auto it = first; it != last; ++it, ++idx) {
|
||||||
@ -1085,7 +1085,7 @@ QFuture<OutputSequence> whenAllImpl(Futures &&... futures)
|
|||||||
constexpr qsizetype size = sizeof...(Futures);
|
constexpr qsizetype size = sizeof...(Futures);
|
||||||
auto context = QSharedPointer<QtPrivate::WhenAllContext<OutputSequence>>::create(size);
|
auto context = QSharedPointer<QtPrivate::WhenAllContext<OutputSequence>>::create(size);
|
||||||
context->futures.resize(size);
|
context->futures.resize(size);
|
||||||
context->promise.reportStarted();
|
context->promise.start();
|
||||||
|
|
||||||
QtPrivate::addCompletionHandlers(context, std::make_tuple(std::forward<Futures>(futures)...));
|
QtPrivate::addCompletionHandlers(context, std::make_tuple(std::forward<Futures>(futures)...));
|
||||||
|
|
||||||
@ -1106,7 +1106,7 @@ QFuture<QtFuture::WhenAnyResult<typename Future<ValueType>::type>> whenAnyImpl(I
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto context = QSharedPointer<QtPrivate::WhenAnyContext<ResultType>>::create();
|
auto context = QSharedPointer<QtPrivate::WhenAnyContext<ResultType>>::create();
|
||||||
context->promise.reportStarted();
|
context->promise.start();
|
||||||
|
|
||||||
qsizetype idx = 0;
|
qsizetype idx = 0;
|
||||||
for (auto it = first; it != last; ++it, ++idx) {
|
for (auto it = first; it != last; ++it, ++idx) {
|
||||||
@ -1125,7 +1125,7 @@ QFuture<std::variant<std::decay_t<Futures>...>> whenAnyImpl(Futures &&... future
|
|||||||
using ResultType = std::variant<std::decay_t<Futures>...>;
|
using ResultType = std::variant<std::decay_t<Futures>...>;
|
||||||
|
|
||||||
auto context = QSharedPointer<QtPrivate::WhenAnyContext<ResultType>>::create();
|
auto context = QSharedPointer<QtPrivate::WhenAnyContext<ResultType>>::create();
|
||||||
context->promise.reportStarted();
|
context->promise.start();
|
||||||
|
|
||||||
QtPrivate::addCompletionHandlers(context, std::make_tuple(std::forward<Futures>(futures)...));
|
QtPrivate::addCompletionHandlers(context, std::make_tuple(std::forward<Futures>(futures)...));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user