diff options
Diffstat (limited to 'src/corelib/kernel/qobject.cpp')
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 54 |
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>"); |