summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qobject.cpp')
-rw-r--r--src/corelib/kernel/qobject.cpp48
1 files changed, 32 insertions, 16 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 5298fff..761b31f 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -871,7 +871,7 @@ QObject::~QObject()
// all the signal/slots connections are still in place - if we don't
// quit now, we will crash pretty soon.
qWarning("Detected an unexpected exception in ~QObject while emitting destroyed().");
-#if defined(Q_AUTOTEST_EXPORT) && !defined(QT_NO_EXCEPTIONS)
+#if defined(Q_BUILD_INTERNAL) && !defined(QT_NO_EXCEPTIONS)
struct AutotestException : public std::exception
{
const char *what() const throw() { return "autotest swallow"; }
@@ -903,7 +903,8 @@ QObject::~QObject()
// disconnect all receivers
if (d->connectionLists) {
++d->connectionLists->inUse;
- for (int signal = -1; signal < d->connectionLists->count(); ++signal) {
+ int connectionListsCount = d->connectionLists->count();
+ for (int signal = -1; signal < connectionListsCount; ++signal) {
QObjectPrivate::ConnectionList &connectionList =
(*d->connectionLists)[signal];
@@ -940,16 +941,17 @@ QObject::~QObject()
// disconnect all senders
QObjectPrivate::Connection *node = d->senders;
while (node) {
- QMutex *m = signalSlotLock(node->sender);
+ QObject *sender = node->sender;
+ QMutex *m = signalSlotLock(sender);
node->prev = &node;
bool needToUnlock = QOrderedMutexLocker::relock(locker.mutex(), m);
//the node has maybe been removed while the mutex was unlocked in relock?
- if (!node || signalSlotLock(node->sender) != m) {
+ if (!node || node->sender != sender) {
m->unlock();
continue;
}
node->receiver = 0;
- QObjectConnectionListVector *senderLists = node->sender->d_func()->connectionLists;
+ QObjectConnectionListVector *senderLists = sender->d_func()->connectionLists;
if (senderLists)
senderLists->dirty = true;
@@ -2510,20 +2512,25 @@ bool QObject::connect(const QObject *sender, const char *signal,
const QMetaObject *smeta = sender->metaObject();
const char *signal_arg = signal;
++signal; //skip code
- int signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal);
+ int signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
if (signal_index < 0) {
// check for normalized signatures
tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
signal = tmp_signal_name.constData() + 1;
smeta = sender->metaObject();
- signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal);
+ signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
+ }
+ if (signal_index < 0) {
+ // re-use tmp_signal_name and signal from above
- if (signal_index < 0) {
- err_method_notfound(sender, signal_arg, "connect");
- err_info_about_objects("connect", sender, receiver);
- return false;
- }
+ smeta = sender->metaObject();
+ signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
+ }
+ if (signal_index < 0) {
+ err_method_notfound(sender, signal_arg, "connect");
+ err_info_about_objects("connect", sender, receiver);
+ return false;
}
signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
int signalOffset, methodOffset;
@@ -2543,16 +2550,21 @@ bool QObject::connect(const QObject *sender, const char *signal,
int method_index = -1;
switch (membcode) {
case QSLOT_CODE:
- method_index = rmeta->indexOfSlot(method);
+ method_index = QMetaObjectPrivate::indexOfSlot(rmeta, method, false);
break;
case QSIGNAL_CODE:
- method_index = rmeta->indexOfSignal(method);
+ method_index = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
+ if (method_index >= 0)
+ method_index += rmeta->methodOffset();
break;
}
if (method_index < 0) {
// check for normalized methods
tmp_method_name = QMetaObject::normalizedSignature(method);
method = tmp_method_name.constData();
+
+ // rmeta may have been modified above
+ rmeta = receiver->metaObject();
switch (membcode) {
case QSLOT_CODE:
method_index = rmeta->indexOfSlot(method);
@@ -2740,7 +2752,9 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
do {
int signal_index = -1;
if (signal) {
- signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal);
+ signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
+ if (signal_index < 0)
+ signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
if (signal_index < 0)
break;
signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
@@ -3360,7 +3374,9 @@ int QObjectPrivate::signalIndex(const char *signalName) const
{
Q_Q(const QObject);
const QMetaObject *base = q->metaObject();
- int relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName);
+ int relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName, false);
+ if (relative_index < 0)
+ relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName, true);
if (relative_index < 0)
return relative_index;
relative_index = QMetaObjectPrivate::originalClone(base, relative_index);