diff --git a/src/corelib/thread/qfuture_impl.h b/src/corelib/thread/qfuture_impl.h index a837c3cefb7..3f95d61b99c 100644 --- a/src/corelib/thread/qfuture_impl.h +++ b/src/corelib/thread/qfuture_impl.h @@ -465,18 +465,20 @@ void Continuation::create(F &&func, } } - Continuation *continuationJob = nullptr; - if (launchAsync) { - continuationJob = new AsyncContinuation( - std::forward(func), *f, p, pool); - } else { - continuationJob = new SyncContinuation( - std::forward(func), *f, p); - } - p.setLaunchAsync(launchAsync); - auto continuation = [continuationJob, launchAsync]() mutable { + auto continuation = [func = std::forward(func), p, pool, + launchAsync](const QFutureInterfaceBase &parentData) mutable { + const auto parent = QFutureInterface(parentData).future(); + Continuation *continuationJob = nullptr; + if (launchAsync) { + continuationJob = new AsyncContinuation( + std::forward(func), parent, p, pool); + } else { + continuationJob = new SyncContinuation( + std::forward(func), parent, p); + } + bool isLaunched = continuationJob->execute(); // If continuation is successfully launched, AsyncContinuation will be deleted // by the QThreadPool which has started it. Synchronous continuation will be @@ -499,12 +501,14 @@ void Continuation::create(F &&func, { Q_ASSERT(f); - auto continuationJob = new AsyncContinuation( - std::forward(func), *f, p, pool); p.setLaunchAsync(true); p.setThreadPool(pool); - auto continuation = [continuationJob]() mutable { + auto continuation = [func = std::forward(func), p, + pool](const QFutureInterfaceBase &parentData) mutable { + const auto parent = QFutureInterface(parentData).future(); + auto continuationJob = new AsyncContinuation( + std::forward(func), parent, p, pool); bool isLaunched = continuationJob->execute(); // If continuation is successfully launched, AsyncContinuation will be deleted // by the QThreadPool which has started it. @@ -585,12 +589,12 @@ void FailureHandler::create(F &&function, QFuture *failureHandler = - new FailureHandler(std::forward(function), *future, promise); - - auto failureContinuation = [failureHandler]() mutable { - failureHandler->run(); - delete failureHandler; + auto failureContinuation = [function = std::forward(function), + promise](const QFutureInterfaceBase &parentData) mutable { + const auto parent = QFutureInterface(parentData).future(); + FailureHandler failureHandler(std::forward(function), + parent, promise); + failureHandler.run(); }; future->d.setContinuation(std::move(failureContinuation)); @@ -665,12 +669,14 @@ class CanceledHandler public: template static QFuture create(F &&handler, QFuture *future, - QFutureInterface promise) + QFutureInterface &promise) { Q_ASSERT(future); - auto canceledContinuation = [parentFuture = *future, promise, - handler = std::forward(handler)]() mutable { + auto canceledContinuation = [promise, handler = std::forward(handler)]( + const QFutureInterfaceBase &parentData) mutable { + auto parentFuture = QFutureInterface(parentData).future(); + promise.reportStarted(); if (parentFuture.isCanceled()) { diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index 57ddc7407e4..7a8ba081030 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -744,14 +744,14 @@ void QFutureInterfaceBasePrivate::setState(QFutureInterfaceBase::State newState) state.storeRelaxed(newState); } -void QFutureInterfaceBase::setContinuation(std::function func) +void QFutureInterfaceBase::setContinuation(std::function func) { QMutexLocker lock(&d->continuationMutex); // If the state is ready, run continuation immediately, // otherwise save it for later. if (isFinished()) { lock.unlock(); - func(); + func(*this); } else { d->continuation = std::move(func); } @@ -762,7 +762,7 @@ void QFutureInterfaceBase::runContinuation() const QMutexLocker lock(&d->continuationMutex); if (d->continuation) { lock.unlock(); - d->continuation(); + d->continuation(*this); } } diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h index 8467047809c..2432503cf79 100644 --- a/src/corelib/thread/qfutureinterface.h +++ b/src/corelib/thread/qfutureinterface.h @@ -192,7 +192,7 @@ private: #endif protected: - void setContinuation(std::function func); + void setContinuation(std::function func); void runContinuation() const; void setLaunchAsync(bool value); @@ -215,6 +215,7 @@ public: { refT(); } + QFutureInterface(const QFutureInterfaceBase &dd) : QFutureInterfaceBase(dd) { refT(); } ~QFutureInterface() { if (!derefT()) @@ -424,6 +425,8 @@ public: : QFutureInterfaceBase(initialState) { } + QFutureInterface(const QFutureInterfaceBase &dd) : QFutureInterfaceBase(dd) { } + static QFutureInterface canceledResult() { return QFutureInterface(State(Started | Finished | Canceled)); } diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h index 083d6d39624..df71d3d4b66 100644 --- a/src/corelib/thread/qfutureinterface_p.h +++ b/src/corelib/thread/qfutureinterface_p.h @@ -195,7 +195,7 @@ public: void setState(QFutureInterfaceBase::State state); // Wrapper for continuation - std::function continuation; + std::function continuation; QBasicMutex continuationMutex; bool launchAsync = false;