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.cpp49
1 files changed, 19 insertions, 30 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 0bc0916b39..fc5e6abf00 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -3660,33 +3660,17 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
return;
}
- // contains the non-empty connection lists
- const QObjectPrivate::ConnectionList *lists[2];
- int numLists = 0;
- if (signal_index < connectionLists->count()) {
- const auto *list = &connectionLists->at(signal_index);
- if (list->first) // only add if non-empty
- lists[numLists++] = list;
- }
- if (connectionLists->allsignals.first) // only add if non-empty
- lists[numLists++] = &connectionLists->allsignals;
+ const QObjectPrivate::ConnectionList *list;
+ if (signal_index < connectionLists->count())
+ list = &connectionLists->at(signal_index);
+ else
+ list = &connectionLists->allsignals;
Qt::HANDLE currentThreadId = QThread::currentThreadId();
- for (int i = 0; i < numLists; ++i) {
- const auto *list = lists[i];
- if (i == 0) {
- // on the first iteration, the mutex must be locked already
- Q_ASSERT(!locker.mutex()->tryLock());
- } else {
- // otherwise the mutex is unlocked and must be relocked
- locker.relock();
- if (connectionLists->orphaned)
- break;
- }
-
+ do {
QObjectPrivate::Connection *c = list->first;
- Q_ASSERT(c);
+ if (!c) continue;
// We need to check against last here to ensure that signals added
// during the signal emission are not emitted in this emission.
QObjectPrivate::Connection *last = list->last;
@@ -3739,6 +3723,8 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
// destructor of the slot object might also lock a mutex from the signalSlotLock() mutex pool,
// and that would deadlock if the pool happens to return the same mutex.
obj.reset();
+
+ locker.relock();
} else if (c->callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
//we compare the vtable to make sure we are not in the destructor of the object.
const int methodIndex = c->method();
@@ -3752,6 +3738,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
if (qt_signal_spy_callback_set.slot_end_callback != 0)
qt_signal_spy_callback_set.slot_end_callback(receiver, methodIndex);
+ locker.relock();
} else {
const int method = c->method_relative + c->method_offset;
locker.unlock();
@@ -3766,17 +3753,19 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
if (qt_signal_spy_callback_set.slot_end_callback != 0)
qt_signal_spy_callback_set.slot_end_callback(receiver, method);
- }
- if (c == last) // early break without relock for the last signal
- break;
-
- locker.relock();
+ locker.relock();
+ }
if (connectionLists->orphaned)
break;
- } while ((c = c->nextConnectionList) != 0);
- }
+ } while (c != last && (c = c->nextConnectionList) != 0);
+
+ if (connectionLists->orphaned)
+ break;
+ } while (list != &connectionLists->allsignals &&
+ //start over for all signals;
+ ((list = &connectionLists->allsignals), true));
}