From cf2220385506fe9f94ef1dbfa43518e489e04155 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 16 Oct 2017 22:31:42 -0700 Subject: Add a comment about the weird refcount for adopted QThreadData It's perfectly benign, but I spent a lot of time debugging this and trying to figure out how to solve something that didn't need solving. So document for posterity. For an adopted thread, the TLS destructors or the adopted thread watcher on Windows will call QThreadData::deref(): - QThreadData::deref(), count drops to zero -> delete this; - ~QThreadData() deletes the QAdoptedThread -> delete t; - ~QThreadPrivate() calls deref() again -> data->deref(); - QThreadData::deref(), count drops to -1, no action taken - ~QObjectPrivate() calls deref() yet again -> threadData->deref() - QThreadData::deref(), count drops to -2, no action taken Change-Id: Icaa86fc7b54d4b368c0efffd14ee448e0796e8d7 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/corelib/thread/qthread.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/corelib/thread') diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index e92be64dfa..cad7a14017 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -78,6 +78,13 @@ QThreadData::~QThreadData() QThreadData::clearCurrentThreadData(); } + // ~QThread() sets thread to nullptr, so if it isn't null here, it's + // because we're being run before the main object itself. This can only + // happen for QAdoptedThread. Note that both ~QThreadPrivate() and + // ~QObjectPrivate() will deref this object again, but that is acceptable + // because this destructor is still running (the _ref sub-object has not + // been destroyed) and there's no reentrancy. The refcount will become + // negative, but that's acceptable. QThread *t = thread; thread = 0; delete t; -- cgit v1.2.3