summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp')
-rw-r--r--tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp b/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp
new file mode 100644
index 0000000000..4825ee80d5
--- /dev/null
+++ b/tests/auto/corelib/thread/qpromise/snippet_qpromise.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Note: this file is published under a license that is different from a default
+// test sources license. This is intentional to comply with default
+// snippet license.
+
+#include <QCoreApplication>
+#include <QtTest/QtTest>
+
+#include <qfuture.h>
+#include <qfuturewatcher.h>
+#include <qpromise.h>
+#include <qpointer.h>
+#include <qsharedpointer.h>
+
+class snippet_QPromise
+{
+public:
+ static void basicExample();
+ static void multithreadExample();
+ static void suspendExample();
+};
+
+void snippet_QPromise::basicExample()
+{
+//! [basic]
+ QPromise<int> promise;
+ QFuture<int> future = promise.future();
+
+ // Note: calling reportStarted() prior to thread creation to enforce order
+ // of calls: first promise.reportStarted() then future.waitForFinished()
+ promise.reportStarted(); // notifies QFuture that the computation is started
+
+ QPointer<QThread> thread(QThread::create([] (QPromise<int> promise) {
+ promise.addResult(42);
+ promise.reportFinished(); // notifies QFuture that the computation is finished
+ }, std::move(promise)));
+ thread->start();
+
+ future.waitForFinished(); // blocks until QPromise::reportFinished is called
+ future.result(); // returns 42
+//! [basic]
+
+ QCOMPARE(future.result(), 42);
+ thread->wait();
+}
+
+void snippet_QPromise::multithreadExample()
+{
+//! [multithread_init]
+ QSharedPointer<QPromise<int>> sharedPromise(new QPromise<int>());
+ QFuture<int> future = sharedPromise->future();
+
+ // ...
+//! [multithread_init]
+
+ sharedPromise->reportStarted();
+
+//! [multithread_main]
+ // here, QPromise is shared between threads via a smart pointer
+ QPointer<QThread> threads[] = {
+ QPointer<QThread>(QThread::create([] (auto sharedPromise) {
+ sharedPromise->addResult(0, 0); // adds value 0 by index 0
+ }, sharedPromise)),
+ QPointer<QThread>(QThread::create([] (auto sharedPromise) {
+ sharedPromise->addResult(-1, 1); // adds value -1 by index 1
+ }, sharedPromise)),
+ QPointer<QThread>(QThread::create([] (auto sharedPromise) {
+ sharedPromise->addResult(-2, 2); // adds value -2 by index 2
+ }, sharedPromise)),
+ // ...
+ };
+ // start all threads
+ for (auto& t : threads)
+ t->start();
+
+ // ...
+
+ future.resultAt(0); // waits until result at index 0 becomes available. returns value 0
+ future.resultAt(1); // waits until result at index 1 becomes available. returns value -1
+ future.resultAt(2); // waits until result at index 2 becomes available. returns value -2
+//! [multithread_main]
+
+ QCOMPARE(future.resultAt(0), 0);
+ QCOMPARE(future.resultAt(1), -1);
+ QCOMPARE(future.resultAt(2), -2);
+
+ for (auto& t : threads)
+ t->wait();
+ sharedPromise->reportFinished();
+}
+
+void snippet_QPromise::suspendExample()
+{
+//! [suspend_start]
+ // Create promise and future
+ QPromise<int> promise;
+ QFuture<int> future = promise.future();
+
+ promise.reportStarted();
+ // Start a computation thread that supports suspension and cancellation
+ QPointer<QThread> thread(QThread::create([] (QPromise<int> promise) {
+ for (int i = 0; i < 100; ++i) {
+ promise.addResult(i);
+ promise.suspendIfRequested(); // support suspension
+ if (promise.isCanceled()) // support cancellation
+ break;
+ }
+ promise.reportFinished();
+ }, std::move(promise)));
+ thread->start();
+//! [suspend_start]
+
+//! [suspend_suspend]
+ future.suspend();
+//! [suspend_suspend]
+
+ // wait in calling thread until future.isSuspended() becomes true or do
+ // something meanwhile
+ while (!future.isSuspended()) {
+ QThread::msleep(50);
+ }
+
+//! [suspend_intermediateResults]
+ future.resultCount(); // returns some number between 0 and 100
+ for (int i = 0; i < future.resultCount(); ++i) {
+ // process results available before suspension
+ }
+//! [suspend_intermediateResults]
+
+ // at least one result is available due to the logic inside a thread
+ QVERIFY(future.resultCount() > 0);
+ QVERIFY(future.resultCount() <= 100);
+ for (int i = 0; i < future.resultCount(); ++i) {
+ QCOMPARE(future.resultAt(i), i);
+ }
+
+//! [suspend_end]
+ future.resume(); // resumes computation, this call will unblock the promise
+ // alternatively, call future.cancel() to stop the computation
+
+ future.waitForFinished();
+ future.results(); // returns all computation results - array of values from 0 to 99
+//! [suspend_end]
+
+ thread->wait();
+
+ QCOMPARE(future.resultCount(), 100);
+ QVector<int> expected(100);
+ std::iota(expected.begin(), expected.end(), 0);
+ QCOMPARE(future.results(), expected);
+}