PDA

View Full Version : postEvent() to a non-existing receiver



Artschi
24th May 2006, 10:18
Hi all,

when posting a custom QEvent to a receiver that has been removed I'll get a debug message "Receiver is not a valid QObject".

But, how do I identify this problem inside my application?

postEvent() doesn't have a return and the event itself has been removed in that case :(

Any suggestions?

jacek
24th May 2006, 14:06
How do you remove that receiver? Do you use deleteLater()?

Artschi
29th May 2006, 13:51
Jacek,

I implemented a generic event subscription to provide async triggering between application components. The goal of this pattern is that underlying components do not have to know the (high level) components. Of course, all receivers will unregister, when they disappear (e.g. in destructor). But sometime this will not work. My intention is to clean-up the subscription list in a generic way if the receiver object isn't alive anymore.

Thus, I can’t specify whether the receiver was destroyed by calling deleteLater() or somehow else.

Artschi

jacek
29th May 2006, 15:59
My intention is to clean-up the subscription list in a generic way if the receiver object isn't alive anymore.
You might try QPointer or QObjectCleanupHandler, but I'm not sure if they are thread-safe.


Thus, I can’t specify whether the receiver was destroyed by calling deleteLater() or somehow else.
AFAIR I read somewhere that you shouldn't delete an object if there are some events for it in the event queue, but I can't find it anywhere now. Maybe it was only about QWidgets? Anyway deleteLater() won't help you much in a multi-threaded application.

Artschi
30th May 2006, 10:19
OK, these are two aspects of my problem:

How to avoid leaked pointers to receiver objects

You might try QPointer or QObjectCleanupHandler, but I'm not sure if they are thread-safe.
QPointer would be perfect if all receiver objects are of the same type. Unfortunately, my EventDispatcher has to handle different receivers :(

QObjectCleanupHandler sounds interesting. I'll verify this.

Another approach is to use the QObject::destroyed signal that could be connected to a clean-up slot in the dispatcher.
.
How to handle receiver objects

AFAIR I read somewhere that you shouldn't delete an object if there are some events for it in the event queue, but I can't find it anywhere now. Maybe it was only about QWidgets? Anyway deleteLater() won't help you much in a multi-threaded application.
I understand from the documentation that the purpose of QObject::deleteLater() is to enable object deletion from outside the thread, irrespective if that object is executing an event at this moment.

From inside the thread I'm able to avoid this conflict. And even there are events left in the queue for that receiver, QT handles this. However, this is not documented and I don't know if it will work in any case ?!

jacek
30th May 2006, 16:05
I understand from the documentation that the purpose of QObject::deleteLater() is to enable object deletion from outside the thread, irrespective if that object is executing an event at this moment.
deleteLater() tells Qt to delete the object when program flow returns to the event loop, but it looks like it isn't thread-safe, so you should forget about it.

wysota
31st May 2006, 08:27
It's usefull if, for example, you want to delete the calling object from within a slot.

Artschi
1st June 2006, 14:44
Thanks for your support.

At the end I decided to connect the destroyed() signal of each receiver with a cleanUp() slot of my EventDispatcher during event subscription.

This works quite good.

Still left to check what happens if the receiver will be deleted before it is connected.