diff options
author | Sona Kurazyan <sona.kurazyan@qt.io> | 2021-10-06 10:04:54 +0200 |
---|---|---|
committer | Sona Kurazyan <sona.kurazyan@qt.io> | 2021-10-08 17:17:20 +0200 |
commit | ce59ccb3341223cda4f7ef2469d86326c6a116e8 (patch) | |
tree | 9084f53c7f50d349694a77a9e665a984ba1776de /src/corelib/thread/qfutureinterface.cpp | |
parent | 22248a4e96a49dbccfeb5c3deb26941a1f40a66e (diff) |
Optimize QPromise destructor
Unify cancel and finish in QPromise destructor in a single call. This
saves us one extra mutex lock and atomic state change.
Task-number: QTBUG-84977
Change-Id: Iac06302c39a2863008b27325fcf6792d4f58c8ae
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/thread/qfutureinterface.cpp')
-rw-r--r-- | src/corelib/thread/qfutureinterface.cpp | 30 |
1 files changed, 26 insertions, 4 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; } |