8

I'm looking for a solution to schedule the deletion of an object across threads. The docs about how deleteLater behave are not entirely clear. Can I call this function in a thread which is not the object's owner?

For example, Object X is owned by Thread A, and in Thread B I would like to have Object X deleted. As the object may be inside event processing at the moment (in Thread A) I can't safely delete it until it gets back to the message loop. If I call deleteLater from Thread B however the docs seem to indicate it will delete as soon as Thread B gets back to the message loop.

Currently I take the approach of having a signal emitted in Thread A which is attached to a slot which calls deleteLater. I'm wondering if there is perhaps an easier way to do this -- if indeed I can just call deleteLater from any thread.

edA-qa mort-ora-y
  • 30,295
  • 39
  • 137
  • 267

3 Answers3

10

Looking at the Qt 4 code and Qt 5 code, deleteLater() just invokes QCoreApplication::postEvent() which is explicitly declared thread-safe. So, it should be fine to just call it directly. As the event queue is processed in the object's owner thread, deletion will happen in thread A.

Only Qt 5 QObject documentation explicitly lists deleteLater() as thread safe. If you want to completely rely on documented behaviour in Qt 4, use postEvent().

hyde
  • 60,639
  • 21
  • 115
  • 176
Tilman Vogel
  • 9,337
  • 4
  • 33
  • 32
7

While deleteLater() is not safe itself, you can invoke it in object's threadA with meta call:

metaObject()->invokeMethod(object, "deleteLater", Qt::QueuedConnection);

Then, it will be safe.

Lol4t0
  • 12,444
  • 4
  • 29
  • 65
  • I'm worried that the docs say only "main event loop" for the queued connection here (quite different from how a queuedconnection usually works). IS this just a doc error, will this actually be like a normal signal pushed into the other thread? – edA-qa mort-ora-y Mar 09 '12 at 12:01
  • @edA-qamort-ora-y, Well, it seems to be documentation bug, and I did deleted objects with such code, but while studding Qt source code just now I found that direct call to `deleteLater` as safe as meta-call, so in current realization direct call work and future versions behavior may be surprising in both cases. – Lol4t0 Mar 09 '12 at 12:30
  • I tracked the source code now as well and it deleteLater does just post an event, and tracking that the posted events will always be sent to the receiver's thread owner. Argh! Why couldn't the docs just say the same thing so I wouldn't have worry about this... :( – edA-qa mort-ora-y Mar 09 '12 at 12:50
  • @edA-qamort-ora-y, as well as doc does not say anything, we can found that qt4.9, for example, does not send event but does smth not safe, so be careful. – Lol4t0 Mar 09 '12 at 13:03
  • I've asked over in qtforums, perhaps there's a resident expert there. For now I'll stick with an approach guaranteed to work, though convuluted. – edA-qa mort-ora-y Mar 09 '12 at 13:06
  • As for my experience and as for what the doc says here: http://qt-project.org/doc/qt-5/threads-qobject.html "Queued Connection: The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread", this is the right answer. Making sure Thread A "owns" Object X, you should be safe enough scheduling the object deletion this way. – alediaferia Dec 01 '14 at 10:07
0

deleteLater() only means that the object will be deleted after all signal/slots int the current event loop (i.e. ThreadB) have been treated.

So, if no other slots need ObjectX in ThreadB, it is equivalent to a plain delete.

Whether you can delete the object or not and how it will be handled in ThreadA is up to your app logic.

If ObjectX is the main object of the thread, sending the quit() signal to ThreadA is the way to go.

Chris Browet
  • 4,156
  • 20
  • 17
  • There will be lots of such objects, the thread is a distinct object. You're confirming though that deleteLater does indeed happen in the current thread only (thus not safe for my use). – edA-qa mort-ora-y Mar 09 '12 at 11:33
  • @edA-qamort-ora-y This depends on the Qt version you're using. See `Lol4t0`'s comment below your question. – Martin Hennings Oct 10 '14 at 12:26