From ed40ffb381e1f874145b70de43961298428c03af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lutz=20Sch=C3=B6nemann?= Date: Mon, 1 Dec 2014 16:12:22 +0100 Subject: Fix crash on signal after deregistration Implemented a remove method in SignalHandler that allows us to remove and disconnect an object from SignalHandler w/o decrementing the connection counter until it hits zero or deleting the object That same functionality was used to remove an object from internal lists when receiving a destroyed signal from an object. In case of deregistering an object we haven't received a destoryed signal but simulated reception of that signal and so that code was not called in that case. Change-Id: Ie20cf628a2de028375f5d29f913682e25ebf8d44 Reviewed-by: Milian Wolff --- src/webchannel/qmetaobjectpublisher.cpp | 1 + src/webchannel/signalhandler_p.h | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp index b3ae23c..b92cf51 100644 --- a/src/webchannel/qmetaobjectpublisher.cpp +++ b/src/webchannel/qmetaobjectpublisher.cpp @@ -403,6 +403,7 @@ void QMetaObjectPublisher::objectDestroyed(const QObject *object) Q_ASSERT(removed); Q_UNUSED(removed); + signalHandler.remove(object); signalToPropertyMap.remove(object); pendingPropertyUpdates.remove(object); wrappedObjects.remove(object); diff --git a/src/webchannel/signalhandler_p.h b/src/webchannel/signalhandler_p.h index 2560cdb..03fbca9 100644 --- a/src/webchannel/signalhandler_p.h +++ b/src/webchannel/signalhandler_p.h @@ -84,6 +84,11 @@ public: */ void clear(); + /** + * Fully remove and disconnect an object from handler + */ + void remove(const QObject *object); + private: /** * Exctract the arguments of a signal call and pass them to the receiver. @@ -252,15 +257,6 @@ int SignalHandler::qt_metacall(QMetaObject::Call call, int methodId, v dispatch(object, methodId, args); - if (methodId == s_destroyedSignalIndex) { - // disconnect on QObject::destroyed - ConnectionHash::iterator it = m_connectionsCounter.find(object); - Q_ASSERT(it != m_connectionsCounter.end()); - foreach (const ConnectionPair &connection, *it) { - QObject::disconnect(connection.first); - } - m_connectionsCounter.erase(it); - } return -1; } return methodId; @@ -280,6 +276,17 @@ void SignalHandler::clear() m_signalArgumentTypes[&QObject::staticMetaObject] = keep; } +template +void SignalHandler::remove(const QObject *object) +{ + Q_ASSERT(m_connectionsCounter.contains(object)); + const SignalConnectionHash &connections = m_connectionsCounter.value(object); + foreach (const ConnectionPair &connection, connections) { + QObject::disconnect(connection.first); + } + m_connectionsCounter.remove(object); +} + QT_END_NAMESPACE #endif // SIGNALHANDLER_H -- cgit v1.2.1