Read QThreadPool::objectName thread-safe

QThreadPool allows method calls from any thread, but QObject does not
so copy objectName so we may use it locally under our own lock.

Pick-to: 6.3 6.2
Task-number: QTBUG-99775
Change-Id: Ib28910649f5d0f9ce698c7da495069635d608d03
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
Allan Sandfeld Jensen 2022-01-13 11:28:27 +01:00
parent 3f32dcd1dd
commit 552c4a9655
2 changed files with 10 additions and 6 deletions

View File

@ -273,13 +273,9 @@ bool QThreadPoolPrivate::tooManyThreadsActive() const
*/
void QThreadPoolPrivate::startThread(QRunnable *runnable)
{
Q_Q(QThreadPool);
Q_ASSERT(runnable != nullptr);
QScopedPointer<QThreadPoolThread> thread(new QThreadPoolThread(this));
QString objectName;
if (QString myName = q->objectName(); !myName.isEmpty())
objectName = myName;
else
if (objectName.isEmpty())
objectName = QLatin1String("Thread (pooled)");
thread->setObjectName(objectName);
Q_ASSERT(!allThreads.contains(thread.data())); // if this assert hits, we have an ABA problem (deleted threads don't get removed here)
@ -476,7 +472,14 @@ void QThreadPoolPrivate::stealAndRunRunnable(QRunnable *runnable)
*/
QThreadPool::QThreadPool(QObject *parent)
: QObject(*new QThreadPoolPrivate, parent)
{ }
{
Q_D(QThreadPool);
connect(this, &QObject::objectNameChanged, this, [d](const QString &newName) {
// We keep a copy of the name under our own lock, so we can access it thread-safely.
QMutexLocker locker(&d->mutex);
d->objectName = newName;
});
}
/*!
Destroys the QThreadPool.

View File

@ -176,6 +176,7 @@ public:
QQueue<QThreadPoolThread *> expiredThreads;
QList<QueuePage *> queue;
QWaitCondition noActiveThreads;
QString objectName;
int expiryTimeout = 30000;
int requestedMaxThreadCount = QThread::idealThreadCount(); // don't use this directly