summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-02-12 16:28:07 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-02-12 16:28:07 +0100
commita9c88c1f39c41215eb9d7288a1fd02aa865e8a04 (patch)
treed6229a2370f202d5ff8a5f56da1f43982bc524c2 /tests/auto/corelib/kernel/qobject/tst_qobject.cpp
parentff23fb6cf723bcc52a5f037ef92500c480ce5a5c (diff)
parent8e22d71b225576ae7ccd6ed349c05219bae7689e (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/qobject/tst_qobject.cpp')
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp42
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