summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qfutureinterface.cpp
diff options
context:
space:
mode:
authorSona Kurazyan <sona.kurazyan@qt.io>2021-10-06 10:04:54 +0200
committerSona Kurazyan <sona.kurazyan@qt.io>2021-10-08 17:17:20 +0200
commitce59ccb3341223cda4f7ef2469d86326c6a116e8 (patch)
tree9084f53c7f50d349694a77a9e665a984ba1776de /src/corelib/thread/qfutureinterface.cpp
parent22248a4e96a49dbccfeb5c3deb26941a1f40a66e (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.cpp30
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;
}