diff options
Diffstat (limited to 'src/corelib/thread')
-rw-r--r-- | src/corelib/thread/qfutureinterface.cpp | 30 | ||||
-rw-r--r-- | src/corelib/thread/qfutureinterface.h | 5 | ||||
-rw-r--r-- | src/corelib/thread/qpromise.h | 6 |
3 files changed, 33 insertions, 8 deletions
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index b34385897c..e640114bb0 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -110,14 +110,36 @@ static inline int switch_from_to(QAtomicInt &a, int from, int to) void QFutureInterfaceBase::cancel() { + cancel(CancelMode::CancelOnly); +} + +void QFutureInterfaceBase::cancel(QFutureInterfaceBase::CancelMode mode) +{ QMutexLocker locker(&d->m_mutex); - if (d->state.loadRelaxed() & Canceled) - return; - switch_from_to(d->state, suspendingOrSuspended, Canceled); + const auto oldState = d->state.loadRelaxed(); + + switch (mode) { + case CancelMode::CancelAndFinish: + if ((oldState & Finished) && (oldState & Canceled)) + return; + switch_from_to(d->state, suspendingOrSuspended | Running, Canceled | Finished); + break; + case CancelMode::CancelOnly: + if (oldState & Canceled) + return; + switch_from_to(d->state, suspendingOrSuspended, Canceled); + break; + } + d->waitCondition.wakeAll(); d->pausedWaitCondition.wakeAll(); - d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Canceled)); + + if (!(oldState & Canceled)) + d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Canceled)); + if (mode == CancelMode::CancelAndFinish && !(oldState & Finished)) + d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Finished)); + d->isValid = false; } diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h index ecc31d6ec3..e813031d59 100644 --- a/src/corelib/thread/qfutureinterface.h +++ b/src/corelib/thread/qfutureinterface.h @@ -154,6 +154,8 @@ public: int loadState() const; void cancel(); + void cancelAndFinish() { cancel(CancelMode::CancelAndFinish); } + void setSuspended(bool suspend); void toggleSuspended(); void reportSuspended() const; @@ -216,6 +218,9 @@ protected: bool launchAsync() const; bool isRunningOrPending() const; + + enum class CancelMode { CancelOnly, CancelAndFinish }; + void cancel(CancelMode mode); }; inline void swap(QFutureInterfaceBase &lhs, QFutureInterfaceBase &rhs) noexcept diff --git a/src/corelib/thread/qpromise.h b/src/corelib/thread/qpromise.h index a1ac8eaf27..3cecbd8306 100644 --- a/src/corelib/thread/qpromise.h +++ b/src/corelib/thread/qpromise.h @@ -70,10 +70,8 @@ public: return; // Otherwise, if computation is not finished at this point, cancel // potential waits - if (!(state & QFutureInterfaceBase::State::Finished)) { - d.cancel(); - finish(); // required to finalize the state - } + if (!(state & QFutureInterfaceBase::State::Finished)) + d.cancelAndFinish(); // cancel and finalize the state } // Core QPromise APIs |