[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