kdecore: rework KThreadPool::waitForDone() to not lock

also active and queued threads remain unchanged by the method, events
processing continues too (at a certain interval)

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2024-05-19 10:22:28 +03:00
parent 25e28e7076
commit 4621f48a1c

View file

@ -39,7 +39,7 @@ public:
QMutex mutex; QMutex mutex;
KThreadPool* parent; KThreadPool* parent;
int maxthreads; int maxthreads;
int activethreadcount; QAtomicInt activethreadcount;
QList<QThread*> activethreads; QList<QThread*> activethreads;
QList<QThread*> queuedthreads; QList<QThread*> queuedthreads;
}; };
@ -55,7 +55,7 @@ KThreadPoolPrivate::KThreadPoolPrivate(KThreadPool *_parent)
void KThreadPoolPrivate::appendThread(QThread *thread) void KThreadPoolPrivate::appendThread(QThread *thread)
{ {
activethreadcount++; activethreadcount.ref();
activethreads.append(thread); activethreads.append(thread);
parent->connect( parent->connect(
thread, SIGNAL(finished()), thread, SIGNAL(finished()),
@ -73,7 +73,7 @@ void KThreadPoolPrivate::_k_slotFinished()
if (thread->isFinished()) { if (thread->isFinished()) {
kDebug() << "thread finished" << thread; kDebug() << "thread finished" << thread;
iter.remove(); iter.remove();
activethreadcount--; activethreadcount.deref();
Q_ASSERT(activethreadcount >= 0); Q_ASSERT(activethreadcount >= 0);
thread->deleteLater(); thread->deleteLater();
} }
@ -116,37 +116,15 @@ void KThreadPool::start(QThread *thread, const QThread::Priority priority)
void KThreadPool::waitForDone(const int timeout) void KThreadPool::waitForDone(const int timeout)
{ {
kDebug() << "waiting for threads" << timeout; kDebug() << "waiting for threads" << timeout;
QMutexLocker locker(&d->mutex);
QElapsedTimer elapsedtimer; QElapsedTimer elapsedtimer;
elapsedtimer.start(); elapsedtimer.start();
QMutableListIterator<QThread*> iter(d->activethreads);
kDebug() << "currently" << d->activethreadcount << "active threads"; kDebug() << "currently" << d->activethreadcount << "active threads";
while ((timeout < 1 || elapsedtimer.elapsed() < timeout) && d->activethreadcount > 0) { while ((timeout < 1 || elapsedtimer.elapsed() < timeout) && d->activethreadcount > 0) {
iter.toFront(); QCoreApplication::processEvents(QEventLoop::AllEvents, s_waittimeout);
while (iter.hasNext()) { QThread::msleep(s_waittimeout);
QThread* thread = iter.next();
// kDebug() << "waiting for" << thread;
disconnect(thread, 0, this, 0);
thread->wait(s_waittimeout);
if (thread->isFinished()) {
kDebug() << "thread finished" << thread;
iter.remove();
d->activethreadcount--;
Q_ASSERT(d->activethreadcount >= 0);
thread->deleteLater();
}
}
} }
if (d->activethreadcount > 0) { if (d->activethreadcount > 0) {
kWarning() << "still there are active threads" << d->activethreadcount; kWarning() << "still there are active threads" << d->activethreadcount;
iter.toFront();
while (iter.hasNext()) {
QThread* thread = iter.next();
kWarning() << "terminating" << thread;
thread->terminate();
thread->wait(s_terminatetimeout);
thread->deleteLater();
}
} }
} }