summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qfutureinterface.cpp
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2020-05-14 14:02:31 +0300
committerAndrei Golubev <andrei.golubev@qt.io>2020-06-09 17:21:38 +0300
commit385f0732d927f0eba8ecf990ee9bc19936475edd (patch)
treece8ba1adfb7252ad475885e6acc7ed256ec6b86f /src/corelib/thread/qfutureinterface.cpp
parent20ba86262f39886629880fa1e07383f1e3e1d52e (diff)
Add QPromise implementation
QPromise and QFuture created from it share the same internal state (namely, QFutureInterface object). QPromise provides high-level management of the shared resource, ensuring thread-safe behavior on construction and destruction (also taking into account QFuture::waitForFinished() semantics). QFuture acts as a primary controller of QPromise via action initiating methods such as suspend() or cancel(). QPromise is equipped with methods to check the status, but the actual handling of QFuture action "requests" is user-defined. [ChangeLog][QtCore][QPromise] Added QPromise class to accompany QFuture. It allows one to communicate computation results and progress to the QFuture via a shared state. Task-number: QTBUG-81586 Change-Id: Ibab9681d35fe63754bf394ad0e7923e2683e2457 Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/corelib/thread/qfutureinterface.cpp')
-rw-r--r--src/corelib/thread/qfutureinterface.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp
index 05482c40c2..1785815cf3 100644
--- a/src/corelib/thread/qfutureinterface.cpp
+++ b/src/corelib/thread/qfutureinterface.cpp
@@ -259,6 +259,37 @@ void QFutureInterfaceBase::waitForResume()
d->pausedWaitCondition.wait(&d->m_mutex);
}
+void QFutureInterfaceBase::suspendIfRequested()
+{
+ const auto canSuspend = [] (int state) {
+ // can suspend only if 1) in any suspend-related state; 2) not canceled
+ return (state & suspendingOrSuspended) && !(state & Canceled);
+ };
+
+ // return early if possible to avoid taking the mutex lock.
+ {
+ const int state = d->state.loadRelaxed();
+ if (!canSuspend(state))
+ return;
+ }
+
+ QMutexLocker lock(&d->m_mutex);
+ const int state = d->state.loadRelaxed();
+ if (!canSuspend(state))
+ return;
+
+ // Note: expecting that Suspending and Suspended are mutually exclusive
+ if (!(state & Suspended)) {
+ // switch state in case this is the first invocation
+ switch_from_to(d->state, Suspending, Suspended);
+ d->sendCallOut(QFutureCallOutEvent(QFutureCallOutEvent::Suspended));
+ }
+
+ // decrease active thread count since this thread will wait.
+ const ThreadPoolThreadReleaser releaser(d->pool());
+ d->pausedWaitCondition.wait(&d->m_mutex);
+}
+
int QFutureInterfaceBase::progressValue() const
{
const QMutexLocker lock(&d->m_mutex);
@@ -361,6 +392,11 @@ bool QFutureInterfaceBase::queryState(State state) const
return d->state.loadRelaxed() & state;
}
+int QFutureInterfaceBase::loadState() const
+{
+ return d->state.loadRelaxed();
+}
+
void QFutureInterfaceBase::waitForResult(int resultIndex)
{
d->m_exceptionStore.throwPossibleException();