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);
|
||||
Q_ASSERT(count > 0);
|
||||
if (--count <= 0) {
|
||||
promise.reportResult(futures);
|
||||
promise.reportFinished();
|
||||
promise.addResult(futures);
|
||||
promise.finish();
|
||||
}
|
||||
}
|
||||
|
||||
QAtomicInteger<qsizetype> count;
|
||||
QFutureInterface<ResultFutures> promise;
|
||||
QPromise<ResultFutures> promise;
|
||||
ResultFutures futures;
|
||||
};
|
||||
|
||||
@ -1025,13 +1025,13 @@ struct WhenAnyContext
|
||||
void checkForCompletion(qsizetype, T &&result)
|
||||
{
|
||||
if (!ready.fetchAndStoreRelaxed(true)) {
|
||||
promise.reportResult(std::forward<T>(result));
|
||||
promise.reportFinished();
|
||||
promise.addResult(std::forward<T>(result));
|
||||
promise.finish();
|
||||
}
|
||||
}
|
||||
|
||||
QAtomicInt ready = false;
|
||||
QFutureInterface<ResultType> promise;
|
||||
QPromise<ResultType> promise;
|
||||
};
|
||||
|
||||
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);
|
||||
context->futures.resize(size);
|
||||
context->promise.reportStarted();
|
||||
context->promise.start();
|
||||
|
||||
qsizetype idx = 0;
|
||||
for (auto it = first; it != last; ++it, ++idx) {
|
||||
@ -1085,7 +1085,7 @@ QFuture<OutputSequence> whenAllImpl(Futures &&... futures)
|
||||
constexpr qsizetype size = sizeof...(Futures);
|
||||
auto context = QSharedPointer<QtPrivate::WhenAllContext<OutputSequence>>::create(size);
|
||||
context->futures.resize(size);
|
||||
context->promise.reportStarted();
|
||||
context->promise.start();
|
||||
|
||||
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();
|
||||
context->promise.reportStarted();
|
||||
context->promise.start();
|
||||
|
||||
qsizetype idx = 0;
|
||||
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>...>;
|
||||
|
||||
auto context = QSharedPointer<QtPrivate::WhenAnyContext<ResultType>>::create();
|
||||
context->promise.reportStarted();
|
||||
context->promise.start();
|
||||
|
||||
QtPrivate::addCompletionHandlers(context, std::make_tuple(std::forward<Futures>(futures)...));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user