diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 60caa217ef7..f9fe58375e8 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1791,9 +1791,16 @@ bool TaskTree::isRunning() const return d->m_root && d->m_root->isRunning(); } -bool TaskTree::runBlocking(const QFuture &future, int timeoutMs) +bool TaskTree::runBlocking() { - if (isRunning() || future.isCanceled()) + QPromise dummy; + dummy.start(); + return runBlocking(dummy.future()); +} + +bool TaskTree::runBlocking(const QFuture &future) +{ + if (future.isCanceled()) return false; bool ok = false; @@ -1812,17 +1819,7 @@ bool TaskTree::runBlocking(const QFuture &future, int timeoutMs) connect(this, &TaskTree::done, &loop, [finalize] { finalize(true); }); connect(this, &TaskTree::errorOccurred, &loop, [finalize] { finalize(false); }); - start(); - if (!isRunning()) - return ok; - - QTimer timer; - if (timeoutMs) { - timer.setSingleShot(true); - timer.setInterval(timeoutMs); - connect(&timer, &QTimer::timeout, this, &TaskTree::stop); - timer.start(); - } + QTimer::singleShot(0, this, &TaskTree::start); loop.exec(QEventLoop::ExcludeUserInputEvents); if (!ok) { @@ -1832,11 +1829,19 @@ bool TaskTree::runBlocking(const QFuture &future, int timeoutMs) return ok; } -bool TaskTree::runBlocking(int timeoutMs) +bool TaskTree::runBlocking(const Group &recipe, milliseconds timeout) { QPromise dummy; dummy.start(); - return runBlocking(dummy.future(), timeoutMs); + return TaskTree::runBlocking(recipe, dummy.future(), timeout); +} + +bool TaskTree::runBlocking(const Group &recipe, const QFuture &future, milliseconds timeout) +{ + const Group root = timeout == milliseconds::max() ? recipe + : Group { recipe.withTimeout(timeout) }; + TaskTree taskTree(root); + return taskTree.runBlocking(future); } int TaskTree::taskCount() const diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 1d596316cae..b4119219a1b 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -390,8 +390,12 @@ public: // Helper methods. They execute a local event loop with ExcludeUserInputEvents. // The passed future is used for listening to the cancel event. // Don't use it in main thread. To be used in non-main threads or in auto tests. - bool runBlocking(const QFuture &future, int timeoutMs = 0); - bool runBlocking(int timeoutMs = 0); + bool runBlocking(); + bool runBlocking(const QFuture &future); + static bool runBlocking(const Group &recipe, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()); + static bool runBlocking(const Group &recipe, const QFuture &future, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()); int taskCount() const; int progressMaximum() const { return taskCount(); } diff --git a/src/libs/utils/filestreamer.cpp b/src/libs/utils/filestreamer.cpp index d24b61dbde3..693849b7c59 100644 --- a/src/libs/utils/filestreamer.cpp +++ b/src/libs/utils/filestreamer.cpp @@ -375,8 +375,7 @@ static void transfer(QPromise &promise, const FilePath &source, const File if (promise.isCanceled()) return; - TaskTree taskTree(transferTask(source, destination)); - if (!taskTree.runBlocking(promise.future())) + if (!TaskTree::runBlocking(transferTask(source, destination), promise.future())) promise.future().cancel(); } diff --git a/src/plugins/remotelinux/filesystemaccess_test.cpp b/src/plugins/remotelinux/filesystemaccess_test.cpp index dda6e417615..2edb78fa7b3 100644 --- a/src/plugins/remotelinux/filesystemaccess_test.cpp +++ b/src/plugins/remotelinux/filesystemaccess_test.cpp @@ -503,8 +503,8 @@ void FileSystemAccessTest::testFileStreamer() } }; - TaskTree taskTree(root); - QVERIFY(taskTree.runBlocking(10000)); + using namespace std::chrono_literals; + QVERIFY(TaskTree::runBlocking(root, 10000ms)); QVERIFY(localData); QCOMPARE(*localData, data); diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 8c2173585b1..294bea71b7e 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -2202,15 +2202,15 @@ void tst_Tasking::testTree() { QFETCH(TestData, testData); - TaskTree taskTree(testData.root); - QCOMPARE(taskTree.taskCount(), testData.taskCount); + TaskTree taskTree({testData.root.withTimeout(1000ms)}); + QCOMPARE(taskTree.taskCount() - 1, testData.taskCount); // -1 for the timeout task above Log actualLog; const auto collectLog = [&actualLog](CustomStorage *storage) { actualLog = storage->m_log; }; taskTree.onStorageDone(testData.storage, collectLog); - const OnDone result = taskTree.runBlocking(2000) ? OnDone::Success : OnDone::Failure; + const OnDone result = taskTree.runBlocking() ? OnDone::Success : OnDone::Failure; QCOMPARE(taskTree.isRunning(), false); - QCOMPARE(taskTree.progressValue(), testData.taskCount); + QCOMPARE(taskTree.progressValue(), taskTree.progressMaximum()); QCOMPARE(actualLog, testData.expectedLog); QCOMPARE(CustomStorage::instanceCount(), 0); diff --git a/tests/auto/utils/async/tst_async.cpp b/tests/auto/utils/async/tst_async.cpp index 01c3306a3bf..5d4a81dc961 100644 --- a/tests/auto/utils/async/tst_async.cpp +++ b/tests/auto/utils/async/tst_async.cpp @@ -8,6 +8,8 @@ using namespace Utils; +using namespace std::chrono_literals; + class tst_Async : public QObject { Q_OBJECT @@ -438,8 +440,8 @@ void tst_Async::taskTree() AsyncTask(setupIntAsync, handleIntAsync), }; - TaskTree tree(root); - QVERIFY(tree.runBlocking(1000)); + + QVERIFY(TaskTree::runBlocking(root, 1000ms)); QCOMPARE(value, 16); } @@ -575,8 +577,7 @@ void tst_Async::mapReduce() QFETCH(double, sum); QFETCH(QList, results); - TaskTree tree(root); - QVERIFY(tree.runBlocking(1000)); + QVERIFY(TaskTree::runBlocking(root, 1000ms)); QCOMPARE(s_results, results); QCOMPARE(s_sum, sum); } diff --git a/tests/manual/subdirfileiterator/tst_subdirfileiterator.cpp b/tests/manual/subdirfileiterator/tst_subdirfileiterator.cpp index 66dd7737816..882a9993a26 100644 --- a/tests/manual/subdirfileiterator/tst_subdirfileiterator.cpp +++ b/tests/manual/subdirfileiterator/tst_subdirfileiterator.cpp @@ -135,8 +135,7 @@ private slots: tasks.append(AsyncTask(onSetup(parentDir.filePath(dirName), templateFile))); } - TaskTree taskTree(tasks); - QVERIFY(taskTree.runBlocking()); + QVERIFY(TaskTree::runBlocking(tasks)); } void cleanupTestCase() @@ -161,8 +160,7 @@ private slots: tasks.append(AsyncTask(onSetup(parentDir.filePath(dirName)))); } - TaskTree taskTree(tasks); - QVERIFY(taskTree.runBlocking()); + QVERIFY(TaskTree::runBlocking(tasks)); m_tempDir.reset(); Singleton::deleteAll();