Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.0.2, 5.1.0 RC1
-
None
-
debian7 x64
-
d6d9edd7c47b183edc1acc631602ea4f4a885d84
Description
have QObject-based object (Receptor) with slot, accepted QSharedPointer of QObject-based object (Message)
if
1. Receptor.slot called through event loop (via signal emitting, via QMetaObject::invokeMethod, ...)
2. Receptor.slot argument - QSharedPointer<Message> - have just one reference, holded into QMetaCallEvent
3. Message object have undelivered posted events before call of Receptor.slot complete
then deadlock occured during Message destruction, QObject destructor try to lock thread`s posted events list (for erase own undelivered events) but list already locked by delivering system
reproduce
#include <QtCore> class Receptor : public QObject { Q_OBJECT public: Receptor() { qRegisterMetaType<QSharedPointer<QObject> >("QSharedPointer<QObject>"); } public slots: #if 1 //deadlock void onMessage(QSharedPointer<QObject> msg=QSharedPointer<QObject>()) { qDebug()<<"msg"; //case 1: post any event to msg - deadlock //if(msg) QCoreApplication::instance()->postEvent(msg.data(), new QEvent(QEvent::None)); QSharedPointer<QObject> newMsg(new QObject); QMetaObject::invokeMethod(this, "onMessage", Qt::QueuedConnection, Q_ARG(QSharedPointer<QObject>, newMsg)); //case2: post any event to newMsg - deadlock QCoreApplication::instance()->postEvent(newMsg.data(), new QEvent(QEvent::None)); } #else //workaround void onMessage(QSharedPointer<QObject> /*msg*/=QSharedPointer<QObject>()) { qDebug()<<"msg"; //QSharedPointer<QObject> newMsg(new Receptor, &QObject::deleteLater); //case3: deadlock QSharedPointer<QObject> newMsg(new Receptor, &defferedQObjectDeleter); //ok QMetaObject::invokeMethod(this, "onMessage", Qt::QueuedConnection, Q_ARG(QSharedPointer<QObject>, newMsg)); QCoreApplication::instance()->postEvent(newMsg.data(), new QEvent(QEvent::None)); } static void defferedQObjectDeleter(QObject *target) { QTimer::singleShot(1, target, SLOT(deleteLater())); } #endif };
From user side defferedQObjectDeleter fix problem. From Qt side - see patch attached