Is it safe for a QObject's thread affinity to be a deleted QThread?
-
Consider the following code:
QThread *thread = nullptr; QObject *object = nullptr; void setup() { QThread *thread = new QThread; QObject *object = new QObject; object->moveToThread(thread); thread->start(); } void cleanup() { thread->exit(0); thread->wait(1000); if (!thread->isFinished()) { // handle error condition } delete thread; } void postEventToThread() { if (!object) { return; } QEvent *event = new QEvent(QEvent::User); qApp->postEvent(object, event); }If
postEventToThread()is called aftersetup()and beforecleanup(), then everything should work properly and an event will get posted toobject's event queue and processed inthread.However, what happens if
cleanup()is called beforepostEventToThread()?In that case
objectstill exists and is a valid object, but its thread has been deleted. Doesobjectautomatically start behaving as though it has no thread affinity? Or is this an error?I tested it out and it doesn't seem to print any warnings, cause any crashes, or otherwise behave badly. But I want to check and make sure that deleting an object's thread (but not the object itself) and posting an event to it is allowed in Qt before I commit to it.
-
From the QThread docs, "Deleting a running QThread (i.e. isFinished() returns false) will result in a program crash. Wait for the finished() signal before deleting the QThread." Dependent on your error handling, your code runs this risk if the thread does not stop inside your timeout.
Also, "Note that deleting a QThread object will not stop the execution of the thread it manages."
Calling QThread::exit() should stop Qt event processing in that thread. At a quick look, I would not expect Qt posted events to continue being processed after this point, regardless of whether the OS still schedules the thread related to the deleted QThread.
-
From the QThread docs, "Deleting a running QThread (i.e. isFinished() returns false) will result in a program crash. Wait for the finished() signal before deleting the QThread." Dependent on your error handling, your code runs this risk if the thread does not stop inside your timeout.
Also, "Note that deleting a QThread object will not stop the execution of the thread it manages."
Calling QThread::exit() should stop Qt event processing in that thread. At a quick look, I would not expect Qt posted events to continue being processed after this point, regardless of whether the OS still schedules the thread related to the deleted QThread.
@ChrisW67 said in Is it safe for a QObject's thread affinity to be a deleted QThread?:
From the QThread docs, "Deleting a running QThread (i.e. isFinished() returns false) will result in a program crash. Wait for the finished() signal before deleting the QThread." Dependent on your error handling, your code runs this risk if the thread does not stop inside your timeout.
Also, "Note that deleting a QThread object will not stop the execution of the thread it manages."
Calling QThread::exit() should stop Qt event processing in that thread. At a quick look, I would not expect Qt posted events to continue being processed after this point, regardless of whether the OS still schedules the thread related to the deleted QThread.
Don't worry, my code makes sure that the thread has stopped before deleting it.
The question is simply about what happens if an object's thread affinity is set to a deleted QThread. I just wanted to make sure that its thread being a pointer to a deleted object was not going to cause any crashes, particularly if a function running in another thread tries to post an event to it.