aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2022-10-27 11:59:09 +0200
committerJarek Kobus <jaroslaw.kobus@qt.io>2022-11-18 16:06:18 +0000
commit30eac65e09028c2b7bf0b2f695248715b83c5fd7 (patch)
treed926095e061fa35e17d73bac88e5121b15fabde9 /src/libs
parent95609cdd576797f07c0b92032271069778515f9f (diff)
Utils: Introduce AsyncTask
AsyncTask encapsulates a function and arguments list for further asynchronous invocation (using Utils::runAsync). This is going to be a part of TaskTree hierarchy. It will enable keeping asynchronous tasks inside the tree. This means we will be able to construct a task tree consisting of a mixture of processes and asynchronous tasks. Implementation-wise this is a simple templated subclass of QObject, where template parameter is of asynchronous result's type. It holds QFutureWatcher object internally in order to track task's running state. Change-Id: I96f307cdf663cadc840465debb353ab55a2c3550 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/utils/CMakeLists.txt1
-rw-r--r--src/libs/utils/asynctask.cpp8
-rw-r--r--src/libs/utils/asynctask.h80
-rw-r--r--src/libs/utils/utils.qbs2
4 files changed, 91 insertions, 0 deletions
diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt
index 362a0b0eeb..3e0a7a836d 100644
--- a/src/libs/utils/CMakeLists.txt
+++ b/src/libs/utils/CMakeLists.txt
@@ -11,6 +11,7 @@ add_qtc_library(Utils
appmainwindow.cpp appmainwindow.h
archive.cpp archive.h
aspects.cpp aspects.h
+ asynctask.cpp asynctask.h
basetreeview.cpp basetreeview.h
benchmarker.cpp benchmarker.h
buildablehelperlibrary.cpp buildablehelperlibrary.h
diff --git a/src/libs/utils/asynctask.cpp b/src/libs/utils/asynctask.cpp
new file mode 100644
index 0000000000..ff79035472
--- /dev/null
+++ b/src/libs/utils/asynctask.cpp
@@ -0,0 +1,8 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#include "asynctask.h"
+
+namespace Utils {
+
+} // namespace Utils
diff --git a/src/libs/utils/asynctask.h b/src/libs/utils/asynctask.h
new file mode 100644
index 0000000000..3b46b5aa8b
--- /dev/null
+++ b/src/libs/utils/asynctask.h
@@ -0,0 +1,80 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
+
+#pragma once
+
+#include "utils_global.h"
+
+#include "futuresynchronizer.h"
+#include "qtcassert.h"
+#include "runextensions.h"
+
+#include <QFutureWatcher>
+
+namespace Utils {
+
+class QTCREATOR_UTILS_EXPORT AsyncTaskBase : public QObject
+{
+ Q_OBJECT
+
+signals:
+ void started();
+ void done();
+};
+
+template <typename ResultType>
+class AsyncTask : public AsyncTaskBase
+{
+public:
+ AsyncTask() { connect(&m_watcher, &QFutureWatcherBase::finished, this, &AsyncTaskBase::done); }
+ ~AsyncTask()
+ {
+ if (isDone())
+ return;
+
+ m_watcher.cancel();
+ if (!m_synchronizer)
+ m_watcher.waitForFinished();
+ }
+
+ using StartHandler = std::function<QFuture<ResultType>()>;
+
+ template <typename Function, typename ...Args>
+ void setAsyncCallData(const Function &function, const Args &...args)
+ {
+ m_startHandler = [=] {
+ return Internal::runAsync_internal(m_threadPool, m_stackSize, m_priority,
+ function, args...);
+ };
+ }
+ void setFutureSynchronizer(FutureSynchronizer *synchorizer) { m_synchronizer = synchorizer; }
+ void setThreadPool(QThreadPool *pool) { m_threadPool = pool; }
+ void setStackSizeInBytes(const StackSizeInBytes &size) { m_stackSize = size; }
+ void setPriority(QThread::Priority priority) { m_priority = priority; }
+
+ void start()
+ {
+ QTC_ASSERT(m_startHandler, qWarning("No start handler specified."); return);
+ m_watcher.setFuture(m_startHandler());
+ emit started();
+ if (m_synchronizer)
+ m_synchronizer->addFuture(m_watcher.future());
+ }
+
+ bool isDone() const { return m_watcher.isFinished(); }
+ bool isCanceled() const { return m_watcher.isCanceled(); }
+
+ QFuture<ResultType> future() const { return m_watcher.future(); }
+ ResultType result() const { return m_watcher.result(); } // TODO: warn when isRunning?
+ QList<ResultType> results() const { return m_watcher.future().results(); }
+
+private:
+ StartHandler m_startHandler;
+ FutureSynchronizer *m_synchronizer = nullptr;
+ QThreadPool *m_threadPool = nullptr;
+ QThread::Priority m_priority = QThread::InheritPriority;
+ StackSizeInBytes m_stackSize = {};
+ QFutureWatcher<ResultType> m_watcher;
+};
+
+} // namespace Utils
diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs
index 79d9561727..6415aaca9f 100644
--- a/src/libs/utils/utils.qbs
+++ b/src/libs/utils/utils.qbs
@@ -50,6 +50,8 @@ Project {
"archive.h",
"aspects.cpp",
"aspects.h",
+ "asynctask.cpp",
+ "asynctask.h",
"basetreeview.cpp",
"basetreeview.h",
"benchmarker.cpp",