summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
diff options
context:
space:
mode:
authorVladimir Belyavsky <belyavskyv@gmail.com>2022-06-01 20:44:57 +0300
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2022-06-10 19:40:32 +0000
commit865212057b9f4e2809ebe42ec25c2d94d818cde7 (patch)
tree7b8e47cc643de10f50ce4a07eb4d9ffd5b4cf8e9 /src/corelib/thread
parente2f14e5be702f89e3d54153fd7511c02729e014e (diff)
Windows: fix DeferredDelete events processing on QThread::terminate()
On finishing/terminating a thread, when processing posted events, we need to consider QThread's own data instead of caller thread's data. Otherwise we can get into unexpected situations such as double destruction of an object, premature destruction, etc. Fixes: QTBUG-103922 Pick-to: 6.4 6.3 6.3.1 6.2 5.15 Change-Id: Idf77221ebbaa0b150ee2d0c296b51829ae8dc30e Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/thread')
-rw-r--r--src/corelib/thread/qthread_win.cpp13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index dc069a03c7..384d80dcb6 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -293,6 +293,17 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
return 0;
}
+/*
+ For regularly terminating threads, this will be called and executed by the thread as the
+ last code before the thread exits. In that case, \a arg is the current QThread.
+
+ However, this function will also be called by QThread::terminate (as well as wait() and
+ setTerminationEnabled) to give Qt a chance to update the terminated thread's state and
+ process pending DeleteLater events for objects that live in the terminated thread. And for
+ adopted thread, this method is called by the thread watcher.
+
+ In those cases, \a arg will not be the current thread.
+*/
void QThreadPrivate::finish(void *arg, bool lockAnyway) noexcept
{
QThread *thr = reinterpret_cast<QThread *>(arg);
@@ -305,7 +316,7 @@ void QThreadPrivate::finish(void *arg, bool lockAnyway) noexcept
if (lockAnyway)
locker.unlock();
emit thr->finished(QThread::QPrivateSignal());
- QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplicationPrivate::sendPostedEvents(nullptr, QEvent::DeferredDelete, d->data);
QThreadStorageData::finish(tls_data);
if (lockAnyway)
locker.relock();