summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobject.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2011-06-23 14:11:50 +0200
committerQt by Nokia <qt-info@nokia.com>2011-07-11 12:43:52 +0200
commitf9035587b98ac5dc9491e642b8ec84470ec03f0e (patch)
treef91962125963ee91ff6d13fa029606966b00a272 /src/corelib/kernel/qobject.cpp
parent915ec02cadcd6e3ca423968a094a97ad417783a1 (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.cpp130
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, &currentSender);
+ switched = true;
+ }
+
+ inline ~QConnectionSenderSwitcher()
+ {
+ if (switched)
+ QObjectPrivate::resetCurrentSender(receiver, &currentSender, 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, &currentSender);
-#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, &currentSender, previousSender);
- QT_RETHROW;
- }
-#endif
- QObjectPrivate::resetCurrentSender(this, &currentSender, 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, &currentSender);
+ 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, &currentSender, 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, &currentSender, 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);