Document how to process deferred deletes in a plugin-scenario

When Qt is not driving the event dispatching, the event loop level
of the thread will stay 0. As a result, we will not automatically
bump the deferred delete event's scope level to 1 when the deferred
delete happens from a code path that doesn't raise the scope level
via QScopedScopeLevelCounter, leaving the event with loop and scope
level 0.

As we only process these 0+0 deferred delete events automatically from
QCoreApplicationPrivate::execCleanup(), which is not going to be called
when the app doesn't call QCoreAppliction::exec(), we were failing to
process the deferred deletes both during the application's runtime,
as well as on shutdown.

Task-number: QTBUG-120124
Fixes: QTBUG-117975
Pick-to: 6.5
Change-Id: I2b8accb432517a48370923ee2d760f8e2e4a8055
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit 7fac2fac9a512cef2d5cdefd9837d76f8be7de05)
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Tor Arne Vestbø 2023-12-14 15:16:40 +01:00
parent 4601674da6
commit d909a8ed67

View File

@ -2394,6 +2394,21 @@ void QObject::removeEventFilter(QObject *obj)
event loop was still running: the Qt event loop will delete those objects event loop was still running: the Qt event loop will delete those objects
as soon as the new nested event loop starts. as soon as the new nested event loop starts.
In situations where Qt is not driving the event dispatcher via e.g.
QCoreApplication::exec() or QEventLoop::exec(), deferred deletes
will not be processed automatically. To ensure deferred deletion in
this scenario, the following workaround can be used:
\code
const auto *eventDispatcher = QThread::currentThread()->eventDispatcher();
QObject::connect(eventDispatcher, &QAbstractEventDispatcher::aboutToBlock,
QThread::currentThread(), []{
if (QThread::currentThread()->loopLevel() == 0)
QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete);
}
);
\endcode
\note It is safe to call this function more than once; when the \note It is safe to call this function more than once; when the
first deferred deletion event is delivered, any pending events for the first deferred deletion event is delivered, any pending events for the
object are removed from the event queue. object are removed from the event queue.