[Development] Allowing event delivery prior to and after QCoreApplication

Thiago Macieira thiago.macieira at intel.com
Tue Apr 14 20:39:33 CEST 2015


On Tuesday 14 April 2015 19:55:47 Julien Cugnière wrote:
> 2015-04-14 16:36 GMT+02:00 Thiago Macieira <thiago.macieira at intel.com>:
> > 2) fix it by not passing through notify() outside the main thread. That's
> > the solution I implemented in I27eaacb532114dd188c4ffff13d4ad2a4bb443e6.
>
> People rely on QCoreApplication::notify to provide a try/catch when
> working with Qt and exceptions. 

That solution has been disproven. It is neither sufficient nor necessary for 
proper exception unwinding of the event loop. It hasn't been for a long time, 
since at least around Qt 4.4, probably more.

> That allows dealing with them in a
> single place, rather than in every single function called by a Qt
> event. If it stops working in threads, some applications will
> definitely see the difference. They won't necessarily break, as I seem
> to remember Qt has a generic try/catch around notify, but they will
> loose any information from the exception.

We removed the try/catch and replaced with stack objects that will unwind 
properly. If you're lucky, an exception will simply unwind QCoreApplication 
out of exec(), so a try/catch around exec() may work.

But this is untested and unsupported. DO NOT throw through the event loop and 
DO NOT throw back to the signal-slot delivery mechanism. We will not deal with 
bug reports that this does not work. I may accept patches that fix this, 
provided they don't introduce performance issues.

So I am not considering this a valid use-case for the problem at hand.

> Is it that common to destroy the application object will threads are
> still delivering events ? It feels weird to me... It would be a shame
> to fix a uncommon case by breaking a common one.

Yes, it happens and that is what's happening with the QtDBus changes I'm 
making: the thread continues running after QCoreApplication exits.

The previous QProcessManager solution tried to exit the thread during 
QCoreApplication shutdown, but note that it was already too late! The routines 
added with qAddPostRoutine are run from the QCoreApplication destructor, so 
the vtables have already changed and we've already run into undefined 
behaviour.

The lastWindowClosed() and aboutToQuit() signals are also too early: they are 
emitted shortly before exec() returns, but the application may continue 
running after that.

> Just thinking out loud, but assuming it isn't that common, would it
> make sense to provide a setting to choose between the two behaviors ?

Not an applicaation-wide setting because you don't know *which* threads are 
running in the background.

But I could make it a per-thread choice.

> Or a Qt function/slot one need to explicitly call from the most
> derived application destructor when needing to continue processing
> events ?

Source-compatible, but requires changes to all applications, so we can't rely 
on applications having been corrected to deal with this. So it's useless: we 
can't rely on the feature.

> Or provide a different way of creating/destroying the
> application object when this behavior is required ?

Same thing: providing a different way without breaking source compatibility 
means we can't rely on it being used.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Development mailing list