PDA

View Full Version : Deleting objects in their event handler



drhex
17th March 2009, 21:15
In the Qt-4.5.0 changelog, I read this:

[203864] Don't warn when deleting objects in their event handler except on Jambi.

How is this supposed to be interpreted?


Deleting objects in their event handlers was once a Bad Thing(tm), but is now ok
It is not now - and never was - ok to kill objects in their event handler, but now Qt doesn't warn about it
It has always been ok to kill an object in its event handler, but for some reason Qt used to give warnings about it anyway. Those warnings are now gone.


Oh, and why make an exception for Jambi?

drhex
18th March 2009, 18:52
Nobody knows what the trolls mean?

I've tried clumsy indirect ways of deleting later because Qt used to complain on the console about not deleting objects in their event handler. Now that the warning is gone, I tried doing all operations immediately and it seems to work. I just want to know if that is because I was lucky or if deleting from event handler is really ok now.

The Storm
18th March 2009, 19:11
With deleteLater() you can delete the object from it's own methods or events without problem, because it shedule the object pointer for a deleteion after the object returns to the main event loop.

drhex
18th March 2009, 20:41
I was doing it by having a singleshot-timer calling a slot. But there was many other things to do besides possibly deleting an object and those "other things" required me to pass arguments, and QTimer::singleShot() won't let me call a slot with arguments, so they had to be passed by other means.
I therefore considered using QMetaObject::invokeMethod() instead which, when called with QueuedConnection can call a method delayed with arguments.
But when I saw that line in the Qt-4.5.0 changelog mentioned above I was thinking the call may not need to be delayed at all :cool:

However, simply replacing
delete foo;
with
foo->deleteLater();

as you suggest, is quite easy too. And I can skip all that awkward parameter passing :D

but it's still a mystery whether a delayed delete is really necessary...

The Storm
18th March 2009, 20:47
Depends on your project if delayed delete is needed. It is not problem to use it every time because the object will be deleted as soon as it returns to the event loop so it will happen almost as fast as regular delete operator(i.e. you will not notice a visible difference). Other good thing is that deleteLater() is a slot so it can be connected for even more nice and easy coding. :P

TemporalBeing
19th March 2009, 19:54
But what about when data feeds into the program keep the processor busy enough that the event loop can't process the deletes? Is there a way to ensure its gets some time to do so?

I'm trying to figure this out now as I have that exact problem - 4 QTcpSockets driving ~4 MBytes/sec (total) at my application. The memory goes through the roof as the processor pegs at 100% (of the core its on). While I originally did it all in a single thread, I reworked it to have each QTcpSocket in its own thread; the only thing the main app does (now) is display the data and then return it to thread that generated it for deletion when new data arrives.

Removing use of QPointer reduced some of the problem, but not entirely. (With QPointer tracking the objects, it was much more problematic and faster to run out of memory. Removing it made it more usable, but still a problem exists.)

If I drop it to 2 feeds (~2MB/sec), then everything works fine and the app peaks at ~ 41MB during this operation (up from ~6.5MB prior.) Oddly, it doesn't drop back down when the operation stops - but it doesn't grow further either.

So is there a way I can guarantee the event loop gets run?

The Storm
19th March 2009, 21:44
If the GUI is not freezed, then the event loop is running fine. :)

TemporalBeing
6th May 2009, 16:08
Remember - there is not necessarily only one event loop in a program. Each thread can have its own event loop.

So if the data gets pushed from the thread to the main loop, and then moved back to the thread that is suppose to clean it up, but that thread's event loop doesn't have time to do so?

Is there any way to guarantee that the thread's event loop will be run for sure? (Since the cross-thread data movement doesn't necessarily trigger the thread's event loop, I think...not sure about how Qt internally does it...)