diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-02-12 16:28:07 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-02-12 16:28:07 +0100 |
commit | a9c88c1f39c41215eb9d7288a1fd02aa865e8a04 (patch) | |
tree | d6229a2370f202d5ff8a5f56da1f43982bc524c2 /tests/auto/corelib/kernel | |
parent | ff23fb6cf723bcc52a5f037ef92500c480ce5a5c (diff) | |
parent | 8e22d71b225576ae7ccd6ed349c05219bae7689e (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
src/gui/image/qimage.cpp
src/gui/text/qtextengine.cpp
src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
src/printsupport/kernel/qprintengine_win.cpp
Change-Id: I09ce991a57f39bc7b1ad6978d0e0d858df0cd444
Diffstat (limited to 'tests/auto/corelib/kernel')
-rw-r--r-- | tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index ac8aae8d3a..1c0a495116 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -147,6 +147,7 @@ private slots: void connectFunctorOverloads(); void connectFunctorQueued(); void connectFunctorWithContext(); + void connectFunctorDeadlock(); void connectStaticSlotWithObject(); void disconnectDoesNotLeakFunctor(); void contextDoesNotLeakFunctor(); @@ -5740,6 +5741,47 @@ void tst_QObject::connectFunctorWithContext() context->deleteLater(); } +class MyFunctor +{ +public: + explicit MyFunctor(QObject *objectToDisconnect) + : m_objectToDisconnect(objectToDisconnect) + {} + + ~MyFunctor() { + // Do operations that will lock the internal signalSlotLock mutex on many QObjects. + // The more QObjects, the higher the chance that the signalSlotLock mutex used + // is already in use. If the number of objects is higher than the number of mutexes in + // the pool (currently 131), the deadlock should always trigger. Use an even higher number + // to be on the safe side. + const int objectCount = 1024; + SenderObject lotsOfObjects[objectCount]; + for (int i = 0; i < objectCount; ++i) { + QObject::connect(&lotsOfObjects[i], &SenderObject::signal1, + &lotsOfObjects[i], &SenderObject::aPublicSlot); + } + } + + void operator()() { + // This will cause the slot object associated with this functor to be destroyed after + // this function returns. That in turn will destroy this functor. + // If our dtor runs with the signalSlotLock held, the bunch of connect() + // performed there will deadlock trying to lock that lock again. + m_objectToDisconnect->disconnect(); + } + +private: + QObject *m_objectToDisconnect; +}; + +void tst_QObject::connectFunctorDeadlock() +{ + SenderObject sender; + MyFunctor functor(&sender); + QObject::connect(&sender, &SenderObject::signal1, functor); + sender.emitSignal1(); +} + static int s_static_slot_checker = 1; class StaticSlotChecker : public QObject |