diff options
-rw-r--r-- | src/corelib/doc/snippets/code/src_corelib_thread_qfuture.cpp | 14 | ||||
-rw-r--r-- | src/corelib/thread/qfuture.qdoc | 9 | ||||
-rw-r--r-- | src/corelib/thread/qfutureinterface.cpp | 4 | ||||
-rw-r--r-- | tests/auto/corelib/thread/qfuture/tst_qfuture.cpp | 30 |
4 files changed, 57 insertions, 0 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_thread_qfuture.cpp b/src/corelib/doc/snippets/code/src_corelib_thread_qfuture.cpp index 091d98539b..cf85dab226 100644 --- a/src/corelib/doc/snippets/code/src_corelib_thread_qfuture.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_thread_qfuture.cpp @@ -385,3 +385,17 @@ QFuture<QFuture<QFuture<int>>>> outerFuture; QFuture<int> unwrappedFuture = outerFuture.unwrap(); //! [30] + +//! [31] +QPromise<int> p; + +QFuture<int> f1 = p.future(); +f1.then([](int) { qDebug("first"); }); + +QFuture<int> f2 = p.future(); +f2.then([](int) { qDebug("second"); }); + +p.start(); +p.addResult(42); +p.finish(); +//! [31] diff --git a/src/corelib/thread/qfuture.qdoc b/src/corelib/thread/qfuture.qdoc index 570f7de8e3..50ec206afd 100644 --- a/src/corelib/thread/qfuture.qdoc +++ b/src/corelib/thread/qfuture.qdoc @@ -75,6 +75,15 @@ If \c testFuture gets canceled, its state is propagated to the next then(), which will be also canceled. So in this case \c {Block 6} will be called. + The future can have only one continuation. Consider the following example: + + \snippet code/src_corelib_thread_qfuture.cpp 31 + + In this case \c f1 and \c f2 are effectively the same QFuture object, as + they share the same internal state. As a result, calling + \l {QFuture::}{then} on \c f2 will overwrite the continuation specified for + \c {f1}. So, only \c {"second"} will be printed when this code is executed. + QFuture also offers ways to interact with a running computation. For instance, the computation can be canceled with the cancel() function. To suspend or resume the computation, use the setSuspended() function or one of diff --git a/src/corelib/thread/qfutureinterface.cpp b/src/corelib/thread/qfutureinterface.cpp index ed46052fa7..e656527e04 100644 --- a/src/corelib/thread/qfutureinterface.cpp +++ b/src/corelib/thread/qfutureinterface.cpp @@ -834,6 +834,10 @@ void QFutureInterfaceBase::setContinuation(std::function<void(const QFutureInter // store the move-only continuation, to guarantee that the associated // future's data stays alive. if (d->continuationState != QFutureInterfaceBasePrivate::Cleaned) { + if (d->continuation) { + qWarning() << "Adding a continuation to a future which already has a continuation. " + "The existing continuation is overwritten."; + } d->continuation = std::move(func); d->continuationData = continuationFutureData; } diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index 06bb53896d..09cb0836d8 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -223,6 +223,7 @@ private slots: void whenAnyDifferentTypesWithCanceled(); void whenAnyDifferentTypesWithFailed(); + void continuationOverride(); void continuationsDontLeak(); void cancelAfterFinishWithContinuations(); @@ -4665,6 +4666,35 @@ void tst_QFuture::whenAnyDifferentTypesWithFailed() #endif } +void tst_QFuture::continuationOverride() +{ + QPromise<int> p; + bool firstExecuted = false; + bool secondExecuted = false; + + QTest::ignoreMessage(QtWarningMsg, + "Adding a continuation to a future which already has a continuation. " + "The existing continuation is overwritten."); + + QFuture<int> f1 = p.future(); + f1.then([&firstExecuted](int) { + firstExecuted = true; + }); + + QFuture<int> f2 = p.future(); + f2.then([&secondExecuted](int) { + secondExecuted = true; + }); + + p.start(); + p.addResult(42); + p.finish(); + + QVERIFY(p.future().isFinished()); + QVERIFY(!firstExecuted); + QVERIFY(secondExecuted); +} + struct InstanceCounter { InstanceCounter() { ++count; } |