[Development] Allowing event delivery prior to and after QCoreApplication
Thiago Macieira
thiago.macieira at intel.com
Wed Jan 14 01:28:02 CET 2015
Regarding:
inline bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)
{ if (event) event->spont = false; return self ? self-
>notifyInternal(receiver, event) : false; }
inline bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent
*event)
{ if (event) event->spont = true; return self ? self->notifyInternal(receiver,
event) : false; }
sendEvent is used by QCoreApplicationPrivate::sendPostedEvents, which in turn
is the core of event dispatching in Qt (all event dispatchers' processEvents
call it).
As you can see from the code above, event delivery is stopped when
QCoreApplication::self is null. This means any event delivery attempted prior
to the QCoreApplication creation or after its destruction silently fails. This
includes the deleteLater() event, as well as timer events and QSocketNotifier's
event. In other words, almost everything stops.
Do we need still need that behaviour?
One reason I can think of is that events, when handled, can produce more
events. Since we're trying to stop the application, dropping events on the
floor means no more events can be generated (no live lock).
I ran into this when I was trying to ask the QtDBus manager thread to exit on
application exit. The only solution I could find was to actually override the
QThread::run() method, because fortunately QThread::quit() does interrupt
execution -- the handling of thread wakeup is done without QSocketNotifier.
The other problem is trying to use QtDBus before QCoreApplication is created
(KUniqueApplication did that, I'm not sure if it still does). Right now,
QtDBus prints a warning if you try to do that:
qWarning("QDBusConnection: %s D-Bus connection created before
QCoreApplication. Application may misbehave.",
type == SessionBus ? "session" : type == SystemBus ?
"system" : "generic");
With the changes I'm making, the application won't misbehave later. It will
just use 100% CPU in the auxiliary thread until QCoreApplication is created
(because there is an event loop which has a QSocketNotifier, but since no one
is handling the activation event, the notifier keeps firing).
Finally, note what happens if there's a thread trying to deliver events
*while* QCoreApplication is being shut down: notifyInternal() is probably
dereferencing a dangling pointer.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
More information about the Development
mailing list