diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 870689f4d0c..9d42c5dc02a 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -483,11 +483,8 @@ QThread::~QThread() Q_D(QThread); { QMutexLocker locker(&d->mutex); - if (d->threadState == QThreadPrivate::Finishing) { - locker.unlock(); - wait(); - locker.relock(); - } + if (d->threadState == QThreadPrivate::Finishing) + d->wait(locker, QDeadlineTimer::Forever); if (d->threadState == QThreadPrivate::Running && !d->data->isAdopted) qFatal("QThread: Destroyed while thread '%ls' is still running", qUtf16Printable(objectName())); diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 5a7b241cd04..ada010dfefe 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -204,6 +204,8 @@ public: uint stackSize = 0; std::underlying_type_t priority = QThread::InheritPriority; + bool wait(QMutexLocker &locker, QDeadlineTimer deadline); + #ifdef Q_OS_UNIX QWaitCondition thread_done; diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index a540687dcd1..90505ba51ec 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -822,6 +822,17 @@ bool QThread::wait(QDeadlineTimer deadline) if (d->threadState == QThreadPrivate::NotStarted) return true; + if (d->threadState == QThreadPrivate::Finished) + return true; + + return d->wait(locker, deadline); +} + +bool QThreadPrivate::wait(QMutexLocker &locker, QDeadlineTimer deadline) +{ + Q_ASSERT(threadState != QThreadPrivate::Finished); + Q_ASSERT(locker.isLocked()); + QThreadPrivate *d = this; while (d->threadState != QThreadPrivate::Finished) { if (!d->thread_done.wait(locker.mutex(), deadline)) diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 6d8d630f2cf..3fb07db62da 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -488,6 +488,14 @@ bool QThread::wait(QDeadlineTimer deadline) } if (d->threadState == QThreadPrivate::NotStarted || d->threadState == QThreadPrivate::Finished) return true; + return d->wait(locker, deadline); +} + +bool QThreadPrivate::wait(QMutexLocker &locker, QDeadlineTimer deadline) +{ + Q_ASSERT(threadState != QThreadPrivate::Finished); + Q_ASSERT(locker.isLocked()); + QThreadPrivate *d = this; ++d->waiters; locker.mutex()->unlock();