diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index 7f1b2bef154..2236b5d1db1 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -888,6 +888,7 @@ void QFutureInterfaceBase::setContinuation(std::functioncontinuationExecuted = true; lock.unlock(); func(*this); lock.relock(); @@ -919,10 +920,11 @@ void QFutureInterfaceBase::cleanContinuation() void QFutureInterfaceBase::runContinuation() const { QMutexLocker lock(&d->continuationMutex); - if (d->continuation) { + if (d->continuation && !d->continuationExecuted) { // Save the continuation in a local function, to avoid calling // a null std::function below, in case cleanContinuation() is // called from some other thread right after unlock() below. + d->continuationExecuted = true; auto fn = std::move(d->continuation); lock.unlock(); fn(*this); diff --git a/src/corelib/thread/qfutureinterface_p.h b/src/corelib/thread/qfutureinterface_p.h index 92a10725910..c573ba8274d 100644 --- a/src/corelib/thread/qfutureinterface_p.h +++ b/src/corelib/thread/qfutureinterface_p.h @@ -162,6 +162,7 @@ public: enum ContinuationState : quint8 { Default, Canceled, Cleaned }; std::atomic continuationState { Default }; + bool continuationExecuted = false; inline QThreadPool *pool() const { return m_pool ? m_pool : QThreadPool::globalInstance(); }