diff options
author | Jarek Kobus <jaroslaw.kobus@qt.io> | 2022-10-27 11:59:09 +0200 |
---|---|---|
committer | Jarek Kobus <jaroslaw.kobus@qt.io> | 2022-11-18 16:06:18 +0000 |
commit | 30eac65e09028c2b7bf0b2f695248715b83c5fd7 (patch) | |
tree | d926095e061fa35e17d73bac88e5121b15fabde9 /src/libs | |
parent | 95609cdd576797f07c0b92032271069778515f9f (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.txt | 1 | ||||
-rw-r--r-- | src/libs/utils/asynctask.cpp | 8 | ||||
-rw-r--r-- | src/libs/utils/asynctask.h | 80 | ||||
-rw-r--r-- | src/libs/utils/utils.qbs | 2 |
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", |