diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index 71310b0ebf0..99372016195 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -74,7 +74,9 @@ public: */ QThreadPoolThread::QThreadPoolThread(QThreadPoolPrivate *manager) :manager(manager), runnable(0) -{ } +{ + setStackSize(manager->stackSize); +} /* \internal @@ -604,6 +606,30 @@ void QThreadPool::reserveThread() ++d->reservedThreads; } +/*! \property QThreadPool::stacksize + + This property contains the stack size for the thread pool worker + threads. + + The value of the property is uses when the thread pool creates + new threads only. Changing it has no effect for already created + or running threads. + + The default value is 0, which makes QThread use the operating + system default stack stize. +*/ +void QThreadPool::setStackSize(uint stackSize) +{ + Q_D(QThreadPool); + d->stackSize = stackSize; +} + +uint QThreadPool::stackSize() const +{ + Q_D(const QThreadPool); + return d->stackSize; +} + /*! Releases a thread previously reserved by a call to reserveThread(). diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h index 09b7f96f486..a65eacc996f 100644 --- a/src/corelib/thread/qthreadpool.h +++ b/src/corelib/thread/qthreadpool.h @@ -58,6 +58,7 @@ class Q_CORE_EXPORT QThreadPool : public QObject Q_PROPERTY(int expiryTimeout READ expiryTimeout WRITE setExpiryTimeout) Q_PROPERTY(int maxThreadCount READ maxThreadCount WRITE setMaxThreadCount) Q_PROPERTY(int activeThreadCount READ activeThreadCount) + Q_PROPERTY(uint stackSize READ stackSize WRITE setStackSize) friend class QFutureInterfaceBase; public: @@ -77,6 +78,9 @@ public: int activeThreadCount() const; + void setStackSize(uint stackSize); + uint stackSize() const; + void reserveThread(); void releaseThread(); diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index 0eff69d4408..8b6a8cc476b 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -96,6 +96,7 @@ public: int maxThreadCount = QThread::idealThreadCount(); int reservedThreads = 0; int activeThreads = 0; + uint stackSize = 0; bool isExiting = false; }; diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 1dcd642023b..782eed03e88 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -92,6 +92,7 @@ private slots: void tryTake(); void waitForDoneTimeout(); void destroyingWaitsForTasksToFinish(); + void stackSize(); void stressTest(); private: @@ -1136,6 +1137,39 @@ void tst_QThreadPool::destroyingWaitsForTasksToFinish() } } +// Verify that QThreadPool::stackSize is used when creating +// new threads. Note that this tests the Qt property only +// since QThread::stackSize() does not reflect the actual +// stack size used by the native thread. +void tst_QThreadPool::stackSize() +{ + uint targetStackSize = 512 * 1024; + uint threadStackSize = 1; // impossible value + + class StackSizeChecker : public QRunnable + { + public: + uint *stackSize; + + StackSizeChecker(uint *stackSize) + :stackSize(stackSize) + { + + } + + void run() + { + *stackSize = QThread::currentThread()->stackSize(); + } + }; + + QThreadPool threadPool; + threadPool.setStackSize(targetStackSize); + threadPool.start(new StackSizeChecker(&threadStackSize)); + QVERIFY(threadPool.waitForDone(30000)); // 30s timeout + QCOMPARE(threadStackSize, targetStackSize); +} + void tst_QThreadPool::stressTest() { class Task : public QRunnable