From f9035587b98ac5dc9491e642b8ec84470ec03f0e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Jun 2011 14:11:50 +0200 Subject: Replace try/catch blocks in favour of destructors in the event loop. This has two direct benefits: 1) compiles regardless of -fno-exceptions: no need for #ifndef QT_NO_EXCEPTIONS or QT_TRY/QT_CATCH 2) no QT_RETHROW either, which means the backtrace of an application crashing due to an uncaught exception will include the actual throw point. Change-Id: I18e5500e121bfa81431ef16699df96d962794f0e Reviewed-on: http://codereview.qt.nokia.com/663 Reviewed-by: Qt Sanity Bot Reviewed-by: Olivier Goffart --- src/corelib/kernel/qeventloop.cpp | 66 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 34 deletions(-) (limited to 'src/corelib/kernel/qeventloop.cpp') diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index 5a4ce973bc..37c06a2093 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -184,49 +184,47 @@ int QEventLoop::exec(ProcessEventsFlags flags) qWarning("QEventLoop::exec: instance %p has already called exec()", this); return -1; } - d->inExec = true; - d->exit = false; - ++d->threadData->loopLevel; - d->threadData->eventLoops.push(this); - locker.unlock(); + + struct LoopReference { + QEventLoopPrivate *d; + QMutexLocker &locker; + + bool exceptionCaught; + LoopReference(QEventLoopPrivate *d, QMutexLocker &locker) : d(d), locker(locker), exceptionCaught(true) + { + d->inExec = true; + d->exit = false; + ++d->threadData->loopLevel; + d->threadData->eventLoops.push(d->q_func()); + locker.unlock(); + } + + ~LoopReference() + { + if (exceptionCaught) { + qWarning("Qt has caught an exception thrown from an event handler. Throwing\n" + "exceptions from an event handler is not supported in Qt. You must\n" + "reimplement QApplication::notify() and catch all exceptions there.\n"); + } + locker.relock(); + QEventLoop *eventLoop = d->threadData->eventLoops.pop(); + Q_ASSERT_X(eventLoop == d->q_func(), "QEventLoop::exec()", "internal error"); + Q_UNUSED(eventLoop); // --release warning + d->inExec = false; + --d->threadData->loopLevel; + } + }; + LoopReference ref(d, locker); // remove posted quit events when entering a new event loop QCoreApplication *app = QCoreApplication::instance(); if (app && app->thread() == thread()) QCoreApplication::removePostedEvents(app, QEvent::Quit); -#if defined(QT_NO_EXCEPTIONS) while (!d->exit) processEvents(flags | WaitForMoreEvents | EventLoopExec); -#else - try { - while (!d->exit) - processEvents(flags | WaitForMoreEvents | EventLoopExec); - } catch (...) { - qWarning("Qt has caught an exception thrown from an event handler. Throwing\n" - "exceptions from an event handler is not supported in Qt. You must\n" - "reimplement QApplication::notify() and catch all exceptions there.\n"); - - // copied from below - locker.relock(); - QEventLoop *eventLoop = d->threadData->eventLoops.pop(); - Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error"); - Q_UNUSED(eventLoop); // --release warning - d->inExec = false; - --d->threadData->loopLevel; - - throw; - } -#endif - - // copied above - locker.relock(); - QEventLoop *eventLoop = d->threadData->eventLoops.pop(); - Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error"); - Q_UNUSED(eventLoop); // --release warning - d->inExec = false; - --d->threadData->loopLevel; + ref.exceptionCaught = false; return d->returnCode; } -- cgit v1.2.3