PDA

View Full Version : deleteLater called from different thread (std::thread)



ustulation
24th November 2013, 11:12
I have a tree structure (say tree-A) the nodes of which are derived from QObject and std::enable_shared_from_this and std::shared_ptr is used to manage the lifetimes instead of QObject-parent-child. This is because there is a similar tree structure (tree-B) in an API which is non-qt and nodes in that tree give async updates to the corresponding connected nodes of tree-A. API is running in a separate thread (actually a threadpool). Nodes in tree-A have call back member functions connected to tree-B nodes using the shared_from_this() idiom (ie weak_ptr to shared_ptr conversions) to manage life-times. These callback functions further emit signals to finally bring the control to the slots in GUI thread. So it is quite possible in this shared ownership that API thread ends up deleting a tree-A node which would lead to undefined behaviour if the node was executing some slot. So to salvage this I’m using a custom deleter which would call deleteLater on the owned QObject derivative. However I am confused reading a few answers on the Net whether deleteLater() can be called from a different thread for a QObject created in another thread.
So if API thread is the one that is going to destroy the QObject of some node of tree-A, is it to be expected that the call to deleteLater() on the QObject from the API thread will actually post the deletion request to the GUI thread (where the QObject was created)? Or do I have to invoke deleteLater() as a Qt::QueuedConnection slot to realize that?

{Qt5.1.0, c++11}

anda_skoa
24th November 2013, 12:11
deleteLater() post an event into the object thread's event loop using QCoreApplication::postEvent(). That method is thread safe.

Cheers,
_

ustulation
24th November 2013, 13:25
oh, has anything changed or am i interpreting the documentation wrong? It says:

...for the object to be deleted, the control must return to the event loop from which deleteLater() was called.

the thread from which deleteLater() was called (API thread) is not the same as thread in which QObject was created (GUI thread). So will deleteLater still post to the GUI thread?

anda_skoa
24th November 2013, 13:38
Maybe that is just an unfortunate phrasing, wanting to say that the thread executing the object's event processing must return to event processing before anything happens.

I am pretty sure that QCoreApplication::postEvent() puts the event in the target object's event loop, anything else wouldn't make sense.
A quick check of the code confirms that :-)

Cheers,
_