summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qfutureinterface.h
diff options
context:
space:
mode:
authorArno Rehn <a.rehn@menlosystems.com>2023-11-23 23:59:34 +0100
committerArno Rehn <a.rehn@menlosystems.com>2023-12-13 21:54:00 +0100
commit59e21a536f7f81625216dc7a621e7be59919da33 (patch)
treee47cee66aca00a325a1e8fda43ef9dd512821295 /src/corelib/thread/qfutureinterface.h
parent8d008b2cf48c961fbd7462813ca3ac4875c55995 (diff)
QFuture: Don't use QFutureCallOutInterface for continuations
This patch replaces the QBasicFutureWatcher that was used for continuations with context objects with a smaller QObject-based wrapper that works directly from the actual continuation. The idea stays the same: In order to run continuations in the thread of a context object, we offload the continuation invocation to the signal-slot mechanism. Previously, we've hooked into QFuture with QFutureCallOutInterface to emit a signal and trigger continuation invocation. However, it is much easier and robust to emit that signal from the continuation itself. This sidesteps the locking issues that QFutureCallOutInterface handling presents. QFutureCallOutInterface basically requires any consumer to only access the QFuture after all events have been posted and the internal mutex unlocked, i.e. on the next cycle of the event loop. Continuations do not impose this restriction; runContinuation() explicitly unlocks the internal mutex before calling the continuation. This fixes a deadlock when using QFuture::then(context, ...) where the paren future is resolved from the same thread that the context object lives in. Fixes: QTBUG-119406 Fixes: QTBUG-119103 Fixes: QTBUG-117918 Fixes: QTBUG-119579 Fixes: QTBUG-119810 Pick-to: 6.7 6.6 Change-Id: I112b16024cde6b6ee0e4d8127392864b813df5bc Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Diffstat (limited to 'src/corelib/thread/qfutureinterface.h')
-rw-r--r--src/corelib/thread/qfutureinterface.h8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h
index 151584e66b..fa5e8ea7ba 100644
--- a/src/corelib/thread/qfutureinterface.h
+++ b/src/corelib/thread/qfutureinterface.h
@@ -21,6 +21,7 @@ QT_BEGIN_NAMESPACE
template <typename T> class QFuture;
class QThreadPool;
+class QFutureInterfaceBase;
class QFutureInterfaceBasePrivate;
class QFutureWatcherBase;
class QFutureWatcherBasePrivate;
@@ -39,8 +40,10 @@ template<class Function, class ResultType>
class FailureHandler;
#endif
+void Q_CORE_EXPORT watchContinuationImpl(const QObject *context,
+ QtPrivate::QSlotObjectBase *slotObj,
+ QFutureInterfaceBase &fi);
}
-class QBasicFutureWatcher;
class Q_CORE_EXPORT QFutureInterfaceBase
{
@@ -178,7 +181,8 @@ private:
friend class QtPrivate::FailureHandler;
#endif
- friend class QBasicFutureWatcher;
+ friend Q_CORE_EXPORT void QtPrivate::watchContinuationImpl(
+ const QObject *context, QtPrivate::QSlotObjectBase *slotObj, QFutureInterfaceBase &fi);
template<class T>
friend class QPromise;