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.cpp54
1 files changed, 46 insertions, 8 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index e588808ee8..2c53ed8f17 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -63,6 +63,7 @@
#include <qsharedpointer.h>
#include <private/qorderedmutexlocker_p.h>
+#include <private/qhooks_p.h>
#include <new>
@@ -138,6 +139,7 @@ static inline QMutex *signalSlotLock(const QObject *o)
uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)]);
}
+// ### Qt >= 5.6, remove qt_add/removeObject
extern "C" Q_CORE_EXPORT void qt_addObject(QObject *)
{}
@@ -820,6 +822,8 @@ QObject::QObject(QObject *parent)
}
}
qt_addObject(this);
+ if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
+ reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
}
/*!
@@ -851,6 +855,8 @@ QObject::QObject(QObjectPrivate &dd, QObject *parent)
}
}
qt_addObject(this);
+ if (Q_UNLIKELY(qtHookData[QHooks::AddQObject]))
+ reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this);
}
/*!
@@ -1028,6 +1034,8 @@ QObject::~QObject()
d->deleteChildren();
qt_removeObject(this);
+ if (Q_UNLIKELY(qtHookData[QHooks::RemoveQObject]))
+ reinterpret_cast<QHooks::RemoveQObjectCallback>(qtHookData[QHooks::RemoveQObject])(this);
if (d->parent) // remove it from parent object
d->setParent_helper(0);
@@ -3302,7 +3310,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
while (c) {
if (c->receiver
&& (receiver == 0 || (c->receiver == receiver
- && (method_index < 0 || c->method() == method_index)
+ && (method_index < 0 || (!c->isSlotObject && c->method() == method_index))
&& (slot == 0 || (c->isSlotObject && c->slotObj->compare(slot)))))) {
bool needToUnlock = false;
QMutex *receiverMutex = 0;
@@ -3505,7 +3513,8 @@ void QMetaObject::connectSlotsByName(QObject *o)
\a signal must be in the signal index range (see QObjectPrivate::signalIndex()).
*/
-static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv)
+static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv,
+ QMutexLocker &locker)
{
const int *argumentTypes = c->argumentTypes.load();
if (!argumentTypes && argumentTypes != &DIRECT_CONNECTION_ONLY) {
@@ -3530,8 +3539,28 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
Q_CHECK_PTR(args);
types[0] = 0; // return type
args[0] = 0; // return value
- for (int n = 1; n < nargs; ++n)
- args[n] = QMetaType::create((types[n] = argumentTypes[n-1]), argv[n]);
+
+ if (nargs > 1) {
+ for (int n = 1; n < nargs; ++n)
+ types[n] = argumentTypes[n-1];
+
+ locker.unlock();
+ for (int n = 1; n < nargs; ++n)
+ args[n] = QMetaType::create(types[n], argv[n]);
+ locker.relock();
+
+ if (!c->receiver) {
+ locker.unlock();
+ // we have been disconnected while the mutex was unlocked
+ for (int n = 1; n < nargs; ++n)
+ QMetaType::destroy(types[n], args[n]);
+ free(types);
+ free(args);
+ locker.relock();
+ return;
+ }
+ }
+
QMetaCallEvent *ev = c->isSlotObject ?
new QMetaCallEvent(c->slotObj, sender, signal, nargs, types, args) :
new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal, nargs, types, args);
@@ -3631,7 +3660,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
// put into the event queue
if ((c->connectionType == Qt::AutoConnection && !receiverInSameThread)
|| (c->connectionType == Qt::QueuedConnection)) {
- queued_activate(sender, signal_index, c, argv ? argv : empty_argv);
+ queued_activate(sender, signal_index, c, argv ? argv : empty_argv, locker);
continue;
#ifndef QT_NO_THREAD
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
@@ -3971,6 +4000,11 @@ void QObject::dumpObjectInfo()
c = c->nextConnectionList;
continue;
}
+ if (c->isSlotObject) {
+ qDebug(" <functor or function pointer>");
+ c = c->nextConnectionList;
+ continue;
+ }
const QMetaObject *receiverMetaObject = c->receiver->metaObject();
const QMetaMethod method = receiverMetaObject->method(c->method());
qDebug(" --> %s::%s %s",
@@ -3989,11 +4023,15 @@ void QObject::dumpObjectInfo()
if (d->senders) {
for (QObjectPrivate::Connection *s = d->senders; s; s = s->next) {
- const QMetaMethod slot = metaObject()->method(s->method());
- qDebug(" <-- %s::%s %s",
+ QByteArray slotName = QByteArrayLiteral("<unknown>");
+ if (!s->isSlotObject) {
+ const QMetaMethod slot = metaObject()->method(s->method());
+ slotName = slot.methodSignature();
+ }
+ qDebug(" <-- %s::%s %s",
s->sender->metaObject()->className(),
s->sender->objectName().isEmpty() ? "unnamed" : qPrintable(s->sender->objectName()),
- slot.methodSignature().constData());
+ slotName.constData());
}
} else {
qDebug(" <None>");