diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2011-06-23 14:11:50 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-07-11 12:43:52 +0200 |
commit | f9035587b98ac5dc9491e642b8ec84470ec03f0e (patch) | |
tree | f91962125963ee91ff6d13fa029606966b00a272 /src/corelib/kernel/qobject.cpp | |
parent | 915ec02cadcd6e3ca423968a094a97ad417783a1 (diff) |
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 <qt_sanity_bot@ovi.com>
Reviewed-by: Olivier Goffart <olivier.goffart@nokia.com>
Diffstat (limited to 'src/corelib/kernel/qobject.cpp')
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 130 |
1 files changed, 68 insertions, 62 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 192e0accaa..c1ac70d8da 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -125,6 +125,39 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *) } } +struct QConnectionSenderSwitcher { + QObject *receiver; + QObjectPrivate::Sender *previousSender; + QObjectPrivate::Sender currentSender; + bool switched; + + inline QConnectionSenderSwitcher() : switched(false) {} + + inline QConnectionSenderSwitcher(QObject *receiver, QObject *sender, int signal_absolute_id) + { + switchSender(receiver, sender, signal_absolute_id); + } + + inline void switchSender(QObject *receiver, QObject *sender, int signal_absolute_id) + { + this->receiver = receiver; + currentSender.sender = sender; + currentSender.signal = signal_absolute_id; + currentSender.ref = 1; + previousSender = QObjectPrivate::setCurrentSender(receiver, ¤tSender); + switched = true; + } + + inline ~QConnectionSenderSwitcher() + { + if (switched) + QObjectPrivate::resetCurrentSender(receiver, ¤tSender, previousSender); + } +private: + Q_DISABLE_COPY(QConnectionSenderSwitcher) +}; + + void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0; void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0; void (*QAbstractDeclarativeData::objectNameChanged)(QAbstractDeclarativeData *, QObject *) = 0; @@ -1083,23 +1116,10 @@ bool QObject::event(QEvent *e) d_func()->inEventHandler = false; #endif QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e); - QObjectPrivate::Sender currentSender; - currentSender.sender = const_cast<QObject*>(mce->sender()); - currentSender.signal = mce->signalId(); - currentSender.ref = 1; - QObjectPrivate::Sender * const previousSender = - QObjectPrivate::setCurrentSender(this, ¤tSender); -#if defined(QT_NO_EXCEPTIONS) + + QConnectionSenderSwitcher sw(this, const_cast<QObject*>(mce->sender()), mce->signalId()); + mce->placeMetaCall(this); -#else - QT_TRY { - mce->placeMetaCall(this); - } QT_CATCH(...) { - QObjectPrivate::resetCurrentSender(this, ¤tSender, previousSender); - QT_RETHROW; - } -#endif - QObjectPrivate::resetCurrentSender(this, ¤tSender, previousSender); break; } @@ -2976,7 +2996,7 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index, type &= Qt::UniqueConnection - 1; } - QObjectPrivate::Connection *c = new QObjectPrivate::Connection; + QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection); c->sender = s; c->receiver = r; c->method_relative = method_index; @@ -2986,16 +3006,11 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index, c->nextConnectionList = 0; c->callFunction = callFunction; - QT_TRY { - QObjectPrivate::get(s)->addConnection(signal_index, c); - } QT_CATCH(...) { - delete c; - QT_RETHROW; - } + QObjectPrivate::get(s)->addConnection(signal_index, c.data()); c->prev = &(QObjectPrivate::get(r)->senders); c->next = *c->prev; - *c->prev = c; + *c->prev = c.data(); if (c->next) c->next->prev = &c->next; @@ -3006,6 +3021,7 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index, sender_d->connectedSignals[signal_index >> 5] |= (1 << (signal_index & 0x1f)); } + c.take(); // stop tracking return true; } @@ -3264,16 +3280,37 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign Qt::HANDLE currentThreadId = QThread::currentThreadId(); + { QMutexLocker locker(signalSlotLock(sender)); - QObjectConnectionListVector *connectionLists = sender->d_func()->connectionLists; - if (!connectionLists) { + struct ConnectionListsRef { + QObjectConnectionListVector *connectionLists; + ConnectionListsRef(QObjectConnectionListVector *connectionLists) : connectionLists(connectionLists) + { + if (connectionLists) + ++connectionLists->inUse; + } + ~ConnectionListsRef() + { + if (!connectionLists) + return; + + --connectionLists->inUse; + Q_ASSERT(connectionLists->inUse >= 0); + if (connectionLists->orphaned) { + if (!connectionLists->inUse) + delete connectionLists; + } + } + + QObjectConnectionListVector *operator->() const { return connectionLists; } + }; + ConnectionListsRef connectionLists = sender->d_func()->connectionLists; + if (!connectionLists.connectionLists) { locker.unlock(); if (qt_signal_spy_callback_set.signal_end_callback != 0) qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index); return; } - ++connectionLists->inUse; - const QObjectPrivate::ConnectionList *list; if (signal_index < connectionLists->count()) @@ -3323,13 +3360,10 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign #endif } - QObjectPrivate::Sender currentSender; - QObjectPrivate::Sender *previousSender = 0; + QConnectionSenderSwitcher sw; + if (receiverInSameThread) { - currentSender.sender = sender; - currentSender.signal = signal_absolute_index; - currentSender.ref = 1; - previousSender = QObjectPrivate::setCurrentSender(receiver, ¤tSender); + sw.switchSender(receiver, sender, signal_absolute_index); } const QObjectPrivate::StaticMetaCallFunction callFunction = c->callFunction; const int method_relative = c->method_relative; @@ -3354,23 +3388,7 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign argv ? argv : empty_argv); } -#if defined(QT_NO_EXCEPTIONS) metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv); -#else - QT_TRY { - metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv); - } QT_CATCH(...) { - locker.relock(); - if (receiverInSameThread) - QObjectPrivate::resetCurrentSender(receiver, ¤tSender, previousSender); - - --connectionLists->inUse; - Q_ASSERT(connectionLists->inUse >= 0); - if (connectionLists->orphaned && !connectionLists->inUse) - delete connectionLists; - QT_RETHROW; - } -#endif if (qt_signal_spy_callback_set.slot_end_callback != 0) qt_signal_spy_callback_set.slot_end_callback(receiver, method); @@ -3378,9 +3396,6 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign locker.relock(); } - if (receiverInSameThread) - QObjectPrivate::resetCurrentSender(receiver, ¤tSender, previousSender); - if (connectionLists->orphaned) break; } while (c != last && (c = c->nextConnectionList) != 0); @@ -3391,17 +3406,8 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign //start over for all signals; ((list = &connectionLists->allsignals), true)); - --connectionLists->inUse; - Q_ASSERT(connectionLists->inUse >= 0); - if (connectionLists->orphaned) { - if (!connectionLists->inUse) - delete connectionLists; - } else if (connectionLists->dirty) { - sender->d_func()->cleanConnectionLists(); } - locker.unlock(); - if (qt_signal_spy_callback_set.signal_end_callback != 0) qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index); |