diff options
| author | Thiago Macieira <thiago.macieira@intel.com> | 2024-10-23 10:11:30 -0700 |
|---|---|---|
| committer | Thiago Macieira <thiago.macieira@intel.com> | 2024-10-28 21:15:06 -0700 |
| commit | 6bd271cf74d6d57816531f688c82c51d29f1be91 (patch) | |
| tree | 4465c5659651550b26379116e4bf4718c29739d9 /src/corelib/thread/qthread.cpp | |
| parent | 5b5297fe87859f59a7aaf5e86a8915c00714fefa (diff) | |
QThread: avoid unlock/lock/unlock in ~QThread if state is Finishing
This is a corner-case scenario but valid because we tell users they can
destroy the QThread object right after finished() has been emitted. But
emitting finished() does not mean the launched thread has actually
exited: it may still be in Finishing state for an arbitrarily long time.
Completely aside from what else may run from other libraries, we only
destroy QThreadStorage and the thread's event dispatcher after
finished() has been emitted.
This commit avoids the unnecessary mutex unlocking in the destructor,
then QThread::wait() locking again, only to unlock yet again so that it
can perform the necessary low-level wait calls. The same for the return
path: wait() locked again to check the state, then unlocked, only for
the destructor to lock again. Now, QThreadPrivate::wait() is responsible
for returning with a locked mutex.
Pick-to: 6.8
Change-Id: I87adffb89f275accea18fffd6b4293861ea7cf39
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/corelib/thread/qthread.cpp')
| -rw-r--r-- | src/corelib/thread/qthread.cpp | 7 |
1 files changed, 2 insertions, 5 deletions
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())); |
