diff options
author | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2018-06-01 15:58:34 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2018-06-04 09:56:50 +0000 |
commit | c9a3d2bea1743f3f589a2604262b925806348cea (patch) | |
tree | 1d26696b42448bb1d5138437b2b558b035c24974 /src/libs/utils | |
parent | f01fbcb789d86116fac5b9d6ef2ed42862e2c944 (diff) |
RunExtensions: Support specifying thread stack size
...with runAsync().
The stack size cannot be changed after starting a thread, so specifying
the stack size with a pool does not make sense. However, starting
with Qt 5.10 a stack size can be specified for the whole thread pool, if
needed.
Change-Id: I09eded606321388c779f762b77de6223081609fe
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
Diffstat (limited to 'src/libs/utils')
-rw-r--r-- | src/libs/utils/runextensions.h | 92 |
1 files changed, 78 insertions, 14 deletions
diff --git a/src/libs/utils/runextensions.h b/src/libs/utils/runextensions.h index 49752234630..14cf5e49223 100644 --- a/src/libs/utils/runextensions.h +++ b/src/libs/utils/runextensions.h @@ -26,6 +26,7 @@ #pragma once #include "functiontraits.h" +#include "optional.h" #include "utils_global.h" #include <QCoreApplication> @@ -57,6 +58,9 @@ struct hasCallOperator }; namespace Utils { + +using StackSizeInBytes = Utils::optional<uint>; + namespace Internal { /* @@ -388,6 +392,34 @@ private: QRunnable *m_runnable; }; +template<typename Function, + typename... Args, + typename ResultType = typename Internal::resultType<Function>::type> +QFuture<ResultType> runAsync_internal(QThreadPool *pool, + StackSizeInBytes stackSize, + QThread::Priority priority, + Function &&function, + Args &&... args) +{ + Q_ASSERT(!(pool && stackSize)); // stack size cannot be changed once a thread is started + auto job = new Internal::AsyncJob<ResultType,Function,Args...> + (std::forward<Function>(function), std::forward<Args>(args)...); + job->setThreadPriority(priority); + QFuture<ResultType> future = job->future(); + if (pool) { + job->setThreadPool(pool); + pool->start(job); + } else { + auto thread = new Internal::RunnableThread(job); + if (stackSize) + thread->setStackSize(stackSize.value()); + thread->moveToThread(qApp->thread()); // make sure thread gets deleteLater on main thread + QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater); + thread->start(priority); + } + return future; +} + } // Internal /*! @@ -418,20 +450,11 @@ template <typename Function, typename... Args, QFuture<ResultType> runAsync(QThreadPool *pool, QThread::Priority priority, Function &&function, Args&&... args) { - auto job = new Internal::AsyncJob<ResultType,Function,Args...> - (std::forward<Function>(function), std::forward<Args>(args)...); - job->setThreadPriority(priority); - QFuture<ResultType> future = job->future(); - if (pool) { - job->setThreadPool(pool); - pool->start(job); - } else { - auto thread = new Internal::RunnableThread(job); - thread->moveToThread(qApp->thread()); // make sure thread gets deleteLater on main thread - QObject::connect(thread, &QThread::finished, thread, &QObject::deleteLater); - thread->start(priority); - } - return future; + return Internal::runAsync_internal(pool, + StackSizeInBytes(), + priority, + std::forward<Function>(function), + std::forward<Args>(args)...); } /*! @@ -449,6 +472,47 @@ runAsync(QThread::Priority priority, Function &&function, Args&&... args) } /*! + Runs \a function with \a args in a new thread with given thread \a stackSize and + thread priority QThread::InheritPriority . + \sa runAsync(QThreadPool*,QThread::Priority,Function&&,Args&&...) + \sa QThread::Priority + \sa QThread::setStackSize +*/ +template<typename Function, + typename... Args, + typename ResultType = typename Internal::resultType<Function>::type> +QFuture<ResultType> runAsync(Utils::StackSizeInBytes stackSize, Function &&function, Args &&... args) +{ + return Internal::runAsync_internal(static_cast<QThreadPool *>(nullptr), + stackSize, + QThread::InheritPriority, + std::forward<Function>(function), + std::forward<Args>(args)...); +} + +/*! + Runs \a function with \a args in a new thread with given thread \a stackSize and + given thread \a priority. + \sa runAsync(QThreadPool*,QThread::Priority,Function&&,Args&&...) + \sa QThread::Priority + \sa QThread::setStackSize +*/ +template<typename Function, + typename... Args, + typename ResultType = typename Internal::resultType<Function>::type> +QFuture<ResultType> runAsync(Utils::StackSizeInBytes stackSize, + QThread::Priority priority, + Function &&function, + Args &&... args) +{ + return Internal::runAsync_internal(static_cast<QThreadPool *>(nullptr), + stackSize, + priority, + std::forward<Function>(function), + std::forward<Args>(args)...); +} + +/*! Runs \a function with \a args in a new thread with thread priority QThread::InheritPriority. \sa runAsync(QThreadPool*,QThread::Priority,Function&&,Args&&...) \sa QThread::Priority |