[Interest] moveToThread used in constructor to move "this"

Lorenz Haas lykurg at gmail.com
Sat Feb 27 11:58:09 CET 2016


2016-02-24 18:23 GMT+01:00 Thiago Macieira <thiago.macieira at intel.com>:
> On quarta-feira, 24 de fevereiro de 2016 10:22:18 PST Lorenz Haas wrote:
>>    Foo() : QObject(nullptr) {
>>       moveToThread(&m_thread);
>>       m_thread.start();
>>    }
>>
>>    ~Foo() {
>>       m_thread.quit();
>>       m_thread.wait();
>>    }
>
> This destructor is either never run or deadlocks.
>
> A QObject can only be destroyed in its thread of affinity. So the above is
> running in that m_thread thread, which means it hasn't exited. Waiting for it
> to exit will wait forever.

A follow up question of _pure academic_ nature:

Using deleteLater() on an instance of Foo is not working since the
thread deadlocks - just as you said. But how about using "delete foo;"
in main (regarding your comment "A QObject can only be destroyed in
its thread of affinity.")?

Using delete
a) the destructor would run in the GUI thread and therefor should be
fine to quit() and wait() the thread
b) after wait() the event loop of Foo is done and, suppose there is no
other concurrent access, it should be fine to delete Foo and its
QObject base class. The documentation states
http://doc.qt.io/qt-5/threads-qobject.html: "Calling delete on a
QObject from a thread other than the one that owns the object (or
accessing the object in other ways) is unsafe, unless you guarantee
that the object isn't processing events at that moment."

So it's all about the "unless..." part. Technically at the moment one
is calling delete it's not guaranteed that there are no events. Inside
the destructor, however, it is. So, assumed the documentation is
right, would this special "delete foo;" use case in main() be safe?

Once again, it's not for practical use, it's just out of technical
curiosity a colleague of mine came up with.


Thanks
Lorenz



More information about the Interest mailing list