Details
-
Bug
-
Resolution: Invalid
-
Not Evaluated
-
None
-
4.8.0
-
None
-
i686-pc-linux-gnu; linux-3.1.6, binutils-2.21.1a, gcc-4.6.2, glib-2.14.1, Qt-4.7.4 or Qt-4.8.0, KDE-4.7.4
Description
I have a question regarding deleteLater() usage:
Suppose I have an app which overrides X11EventFilter(), and on reception of some XEvent, does some processing which ends with issuing object_A.deleteLater(). Suppose further that I connect object_A's destroyed() signal to a slot in object_B where I then issue object_B's deleteLater(), or I connect object_A's destroyed() signal to object_B's deleteLater() method/slot directly. What happens then is that if the connection is of type Qt::QueuedConnection, the deferred deletion of object_B is done reasonably quickly when control returns to the event loop, while if the connection is of type Qt::DirectConnection (or simply the default because we've only one thread here), the deferred deletion of object_B is not done until the app is terminated.
What I'd like to see is for object_B to be deleted from the (main) event loop, reasonably soon after it calls deleteLater() on itself for the default connection type (ie, for either Qt::DirectConnection or Qt::QueuedConnection)
What I think is happening is that on entry to QApplication::x11ProcessEvent() the (event loop) loopLevel is incremented, lets say to 2, object_A.deleteLater() is issued,
QApplication::x11ProcessEvent() returns (thus decrementing loopLevel back to 1), and
then, sometime later from the (main) event loop (just before the deferred deletion of
object_A is done) object_A emits the destroyed() signal and the connected object_B slot
is then called under loopLevel 1 (the connection here being direct), thus preventing the deferred object_B deletion until loopLevel 0 is reached, ie, when the app exits.
My question is if this is intended behaviour, or a bug?
ADDITIONAL INFO/DISCUSSION:
Adjust loopLevel for deleteLater() calls triggered by QObject destroyed() signal:
There exist cases where one connects the destroyed() signal to a slot in which deleteLater() calls are made or triggered. In such cases, as deleteLater() calls are not processed until the (event) loopLevel drops below the current level (which is often (always?) 1 here), the
deferred deletions may not be done until the application exits. This issue is now occurring in KDE-4.7.X.
The attached patch addresses this issue by incrementing loopLevel specifically for the 'emit destroyed()' signal in src/corelib/kernel/qobject.cpp.
I realize this is a bit of a hack, and may not be the proper way to handle this, but hopefully it will spur discussion and resolution of the issue.
Attachments
Issue Links
- relates to
-
QTBUG-23390 Adjust loopLevel for deleteLater() calls issued in QEventDispatcher filterEvent()
- Closed
-
QTBUG-21928 QObject::deleteLater() does not work properly from CActive::RunL method(in Symbian)
- Closed