summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qfutureinterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread/qfutureinterface.cpp')
-rw-r--r--src/corelib/thread/qfutureinterface.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp
index e640114bb0..7512d6174a 100644
--- a/src/corelib/thread/qfutureinterface.cpp
+++ b/src/corelib/thread/qfutureinterface.cpp
@@ -835,7 +835,17 @@ void QFutureInterfaceBasePrivate::setState(QFutureInterfaceBase::State newState)
void QFutureInterfaceBase::setContinuation(std::function<void(const QFutureInterfaceBase &)> func)
{
+ setContinuation(func, nullptr);
+}
+
+void QFutureInterfaceBase::setContinuation(std::function<void(const QFutureInterfaceBase &)> func,
+ QFutureInterfaceBasePrivate *continuationFutureData)
+{
QMutexLocker lock(&d->continuationMutex);
+
+ if (continuationFutureData)
+ continuationFutureData->parentData = d;
+
// If the state is ready, run continuation immediately,
// otherwise save it for later.
if (isFinished()) {
@@ -855,6 +865,24 @@ void QFutureInterfaceBase::runContinuation() const
}
}
+bool QFutureInterfaceBase::isChainCanceled() const
+{
+ if (isCanceled())
+ return true;
+
+ auto parent = d->parentData;
+ while (parent) {
+ // If the future is in Canceled state because it had an exception, we want to
+ // continue checking the chain of parents for cancellation, otherwise if the exception
+ // is handeled inside the chain, it won't be interrupted even though cancellation has
+ // been requested.
+ if ((parent->state.loadRelaxed() & Canceled) && !parent->hasException)
+ return true;
+ parent = parent->parentData;
+ }
+ return false;
+}
+
void QFutureInterfaceBase::setLaunchAsync(bool value)
{
d->launchAsync = value;