[Development] Allowing event delivery prior to and after QCoreApplication

Julien Cugnière julien.cugniere at gmail.com
Wed Apr 15 20:49:42 CEST 2015


2015-04-15 17:11 GMT+02:00 Thiago Macieira <thiago.macieira at intel.com>:
> Not exactly. It all depends on what you define to be "works". I don't consider
> resuming the event loop to be "works". I think that an uncaught exception
> should exit the event loop and cause the application to exit, so I consider
> your code above broken. It should rethrow after logging.
>
> But let's assume you have a good reason for continuing the event loop. You're
> now in unsupported territory because you caught an exception in the middle of
> the loop and resumed operations.

The idea is that we have threads which serve requests from other
threads through the use of slots. When an exception is thrown during
the processing of such a slot, it means the request encountered a
fatal error and was aborted. But the thread should continue executing
and serving other requests.

Same thing with a thread executing a periodic task through the use a
QTimer. A particular execution of the task could fail through an
exception, but the task can be retried the next time the timer fires.

> The code above will continue to work for the main thread, but will stop
> working for auxiliary threads. And there will be no work around. You will need
> to do the right thing and stop any exceptions from going back to the signal-
> slot mechanism and the event delivery mechanism.

But this requires wrapping every single slot in a try/catch. Apart
from the code churn (we have lots of those), this is repetitive and
error-prone, as it's all too easy to add a new slot and forget the
try/catch. The software is much more robust and maintainable if the
catching of exceptions can be centralized.

> If the problem is exceptions, we can simply add the exception protection
> elsewhere in the stack, closer to where we actually call out to the event
> handler or the slot.

Our use of QCoreApplication::notify is intended to solve the problem I
describe above by moving the try/catch one level up in the call stack
: instead of doing it in the slot itself, we want it done in the
caller of the slot.

If notify is too far up the stack, it would be fine doing it closer to
the user code. I suppose for slots you're thinking of
qt_static_metacall or QMetaObject::activate.

But ideally it would need to go through a user-supplied function, to
be able to customize the type of exception caught, and the way they
are handled (logged in our case). Wouldn't that bring the same kind of
problem as QCoreApplication::notify ?

Or if it can't go through a user supplied function, at the very least
Qt should catch std::exception, and log its message through a
user-customizable function (such as qWarning()). A simple catch(...)
wouldn't be enough, as the text of the exception would be lost.

> Do you need OpenGL or X11? Those use threads and they will probably continue
> running even after your SomeApplication class's destructor has begun, which
> means they may call your notify() during the destructor, including just after
> it finished and ~QApplication began.

It's a background service, so not really. But I suppose sooner or
later we'll run into problems if some other part of Qt starts to use
threads.

By the way, thanks for taking the time of discussing this use-case.

Julien Cugnière



More information about the Development mailing list