diff options
| author | Ivan Solovev <ivan.solovev@qt.io> | 2025-03-05 15:09:28 +0100 |
|---|---|---|
| committer | Ivan Solovev <ivan.solovev@qt.io> | 2025-03-24 11:39:34 +0100 |
| commit | 3978f3d5ec0ef0bf17181f586d1438750464cc30 (patch) | |
| tree | ac03ffd3601fcd84d5decab3cbdde82fa2ba801f /src/corelib/thread/qfutureinterface.cpp | |
| parent | 4b18a8946bac34143a5eb85e669be01b8ced32fc (diff) | |
Warn if QFuture::then() is called for a QFuture with multiple results
QFuture is tricky in the sense that it can store multiple results.
The users might write the code like:
QList<int> values{1, 2, 3};
auto f = QtConcurrent::mapped(values, func)
.then([](auto val) { otherFunc(val); });
with the expectation that the lambda will be called on each mapped
value of the original input container.
However, that is not true. QtConcurrent::mapped() returns a QFuture
which has multiple results, and in this case only the first result will
be passed to the then() continuation.
We cannot detect this problem at compile-time, because we do not know
how many results will the QFuture hold. So, add at least a runtime
warning.
The warning is added in a new logging category, so that the users who
really need this behavior can disable it. The warning is implemented
as an exported out-of-line method for two reasons:
* To avoid code duplication for each template parameter of
CompactContinuation.
* To avoid exposing a Qt-specific logging category into a public header.
Such design, however, prevents us from cherry-picking the change to
older branches.
Fixes: QTBUG-133522
Change-Id: I3344b5228b50e9c9d68d0c57961bbc969f566bb9
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 | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index 3a1aae19c33..dd959f16d6e 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -7,6 +7,7 @@ #include <QtCore/qatomic.h> #include <QtCore/qcoreapplication.h> +#include <QtCore/qloggingcategory.h> #include <QtCore/qthread.h> #include <QtCore/qvarlengtharray.h> #include <private/qthreadpool_p.h> @@ -21,6 +22,8 @@ QT_WARNING_DISABLE_GCC("-Wstringop-overflow") QT_BEGIN_NAMESPACE +Q_STATIC_LOGGING_CATEGORY(lcQFutureContinuations, "qt.core.qfuture.continuations") + enum { MaxProgressEmitsPerSecond = 25 }; @@ -42,6 +45,20 @@ const auto suspendingOrSuspended = } // unnamed namespace +namespace QtPrivate { + +void qfutureWarnIfUnusedResults(qsizetype numResults) +{ + if (numResults > 1) { + qCWarning(lcQFutureContinuations, + "Parent future has %" PRIdQSIZETYPE " result(s), but only the first result " + "will be handled in the continuation.", + numResults); + } +} + +} // namespace QtPrivate + class QObjectContinuationWrapper : public QObject { Q_OBJECT |
