Revert "Port QThreadPool to the new property system"

This reverts commit 8f8405e04642b98663d4752d4ae76c304ae33b01.

Reason for revert: Appears not entirely thread-safe and caused QTBUG-90705

Change-Id: I390c0b1a555a18e6a095b52010371d017071e26b
Fixes: QTBUG-90705
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
This commit is contained in:
Allan Sandfeld Jensen 2021-01-28 12:36:59 +00:00
parent bd520ccc3c
commit f2c3b52c6c
4 changed files with 31 additions and 120 deletions

View File

@ -163,7 +163,7 @@ void QThreadPoolThread::registerThreadInactive()
/*
\internal
*/
QThreadPoolPrivate::QThreadPoolPrivate()
QThreadPoolPrivate:: QThreadPoolPrivate()
{ }
bool QThreadPoolPrivate::tryStart(QRunnable *task)
@ -223,8 +223,10 @@ void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority)
int QThreadPoolPrivate::activeThreadCount() const
{
return int(allThreads.count() - expiredThreads.count() - waitingThreads.count()
+ reservedThreads);
return (allThreads.count()
- expiredThreads.count()
- waitingThreads.count()
+ reservedThreads);
}
void QThreadPoolPrivate::tryToStartMoreThreads()
@ -603,15 +605,11 @@ int QThreadPool::expiryTimeout() const
void QThreadPool::setExpiryTimeout(int expiryTimeout)
{
Q_D(QThreadPool);
if (d->expiryTimeout == expiryTimeout)
return;
d->expiryTimeout = expiryTimeout;
}
QBindable<int> QThreadPool::bindableExpiryTimeout()
{
Q_D(QThreadPool);
return &d->expiryTimeout;
}
/*! \property QThreadPool::maxThreadCount
\brief the maximum number of threads used by the thread pool.
@ -633,18 +631,11 @@ void QThreadPool::setMaxThreadCount(int maxThreadCount)
Q_D(QThreadPool);
QMutexLocker locker(&d->mutex);
const auto maxThreadCountChanged = maxThreadCount != d->maxThreadCount;
// Rewrite the value in any case, to make sure the binding is cleared.
if (maxThreadCount == d->maxThreadCount)
return;
d->maxThreadCount = maxThreadCount;
if (maxThreadCountChanged)
d->tryToStartMoreThreads();
}
QBindable<int> QThreadPool::bindableMaxThreadCount()
{
Q_D(QThreadPool);
return &d->maxThreadCount;
d->tryToStartMoreThreads();
}
/*! \property QThreadPool::activeThreadCount
@ -707,12 +698,6 @@ uint QThreadPool::stackSize() const
return d->stackSize;
}
QBindable<uint> QThreadPool::bindableStackSize()
{
Q_D(QThreadPool);
return &d->stackSize;
}
/*!
Releases a thread previously reserved by a call to reserveThread().

View File

@ -56,10 +56,10 @@ class Q_CORE_EXPORT QThreadPool : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QThreadPool)
Q_PROPERTY(int expiryTimeout READ expiryTimeout WRITE setExpiryTimeout BINDABLE bindableExpiryTimeout)
Q_PROPERTY(int maxThreadCount READ maxThreadCount WRITE setMaxThreadCount BINDABLE bindableMaxThreadCount)
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 BINDABLE bindableStackSize)
Q_PROPERTY(uint stackSize READ stackSize WRITE setStackSize)
friend class QFutureInterfaceBase;
public:
@ -76,17 +76,14 @@ public:
int expiryTimeout() const;
void setExpiryTimeout(int expiryTimeout);
QBindable<int> bindableExpiryTimeout();
int maxThreadCount() const;
void setMaxThreadCount(int maxThreadCount);
QBindable<int> bindableMaxThreadCount();
int activeThreadCount() const;
void setStackSize(uint stackSize);
uint stackSize() const;
QBindable<uint> bindableStackSize();
void reserveThread();
void releaseThread();

View File

@ -58,7 +58,6 @@
#include "QtCore/qset.h"
#include "QtCore/qqueue.h"
#include "private/qobject_p.h"
#include "private/qproperty_p.h"
QT_REQUIRE_CONFIG(thread);
@ -174,17 +173,11 @@ public:
QList<QueuePage *> queue;
QWaitCondition noActiveThreads;
Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QThreadPoolPrivate, int, expiryTimeout, 30000)
void setMaxThreadCount(int count) { q_func()->setMaxThreadCount(count); }
Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QThreadPoolPrivate, int, maxThreadCount,
&QThreadPoolPrivate::setMaxThreadCount,
QThread::idealThreadCount())
int expiryTimeout = 30000;
int maxThreadCount = QThread::idealThreadCount();
int reservedThreads = 0;
int activeThreads = 0;
Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QThreadPoolPrivate, uint, stackSize, 0)
uint stackSize = 0;
};
QT_END_NAMESPACE

View File

@ -104,23 +104,8 @@ private slots:
void stressTest();
void takeAllAndIncreaseMaxThreadCount();
void waitForDoneAfterTake();
void bindings();
private:
class WaitingTask : public QRunnable
{
public:
QSemaphore waitForStarted, waitToFinish;
WaitingTask() { setAutoDelete(false); }
void run() override
{
waitForStarted.release();
waitToFinish.acquire();
}
};
QMutex m_functionTestMutex;
};
@ -486,6 +471,20 @@ void tst_QThreadPool::setMaxThreadCount()
void tst_QThreadPool::setMaxThreadCountStartsAndStopsThreads()
{
class WaitingTask : public QRunnable
{
public:
QSemaphore waitForStarted, waitToFinish;
WaitingTask() { setAutoDelete(false); }
void run() override
{
waitForStarted.release();
waitToFinish.acquire();
}
};
QThreadPool threadPool;
threadPool.setMaxThreadCount(1);
@ -1306,68 +1305,5 @@ void tst_QThreadPool::waitForDoneAfterTake()
}
void tst_QThreadPool::bindings()
{
{
QThreadPool pool;
// expiryTimeout property
QProperty<int> expiryTimeout;
pool.bindableExpiryTimeout().setBinding(Qt::makePropertyBinding(expiryTimeout));
expiryTimeout = 1000;
QCOMPARE(pool.expiryTimeout(), 1000);
QProperty<int> expiryTimeoutObserver;
expiryTimeoutObserver.setBinding(pool.bindableExpiryTimeout().makeBinding());
pool.setExpiryTimeout(100);
QCOMPARE(expiryTimeoutObserver, 100);
// stackSize property
QProperty<uint> stackSize;
pool.bindableStackSize().setBinding(Qt::makePropertyBinding(stackSize));
stackSize = 1000;
QCOMPARE(pool.stackSize(), 1000);
QProperty<uint> stackSizeObserver;
stackSizeObserver.setBinding(pool.bindableStackSize().makeBinding());
pool.setStackSize(100);
QCOMPARE(stackSizeObserver, 100);
}
// maxThreadCount property
{
// Make sure changing the max thread count via binding starts new threads
QThreadPool pool;
WaitingTask task;
pool.setMaxThreadCount(1);
pool.start(&task);
pool.start(&task);
QVERIFY(task.waitForStarted.tryAcquire(1, 1000));
// thread limit is 1, cannot start more tasks
QVERIFY(!task.waitForStarted.tryAcquire(1, 1000));
QCOMPARE(pool.activeThreadCount(), 1);
QProperty<int> maxThreadCount;
pool.bindableMaxThreadCount().setBinding(Qt::makePropertyBinding(maxThreadCount));
maxThreadCount = 2;
QCOMPARE(pool.maxThreadCount(), 2);
// increasing thread count should allow starting more tasks
QVERIFY(task.waitForStarted.tryAcquire(1, 1000));
QCOMPARE(pool.activeThreadCount(), 2);
task.waitToFinish.release(2);
pool.waitForDone();
QProperty<int> maxThreadCountObserver;
maxThreadCountObserver.setBinding(pool.bindableMaxThreadCount().makeBinding());
pool.setMaxThreadCount(10);
QCOMPARE(maxThreadCountObserver, 10);
}
}
QTEST_MAIN(tst_QThreadPool);
#include "tst_qthreadpool.moc"