aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/utils
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2018-06-01 15:58:34 +0200
committerNikolai Kosjar <nikolai.kosjar@qt.io>2018-06-04 09:56:50 +0000
commitc9a3d2bea1743f3f589a2604262b925806348cea (patch)
tree1d26696b42448bb1d5138437b2b558b035c24974 /src/libs/utils
parentf01fbcb789d86116fac5b9d6ef2ed42862e2c944 (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.h92
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