summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@woboq.com>2014-07-05 16:24:17 +0200
committerOlivier Goffart <ogoffart@woboq.com>2014-07-07 08:45:56 +0200
commitd49f7168aba2770cc39d463adeeffc4e9635f4dc (patch)
treed0c00b3ebfd5241535de6cf6cc86b465919c971d /tests/auto
parent7e488626ab484ef8f62be6f80791a0b3adae80ab (diff)
QObject: don't hold mutex when copying arguments in a QueuedConnection
QMetaType::create can call user code and we should not keep mutex held as this may cause dead lock. Make sure the tst_qobjectrace actually emit some signal so the test check there is no race if the receiver object is destroyed while the mutex is unlocked. Task-number: QTBUG-39990 Change-Id: I56ca1ae7a11cd7b33c1a68727370972862e11c2f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp33
-rw-r--r--tests/auto/other/qobjectrace/tst_qobjectrace.cpp25
2 files changed, 37 insertions, 21 deletions
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index 1c0a495116..0308e870be 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -270,6 +270,21 @@ public slots:
int ReceiverObject::sequence = 0;
+static void playWithObjects()
+{
+ // 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 tst_QObject::initTestCase()
{
const QString testDataDir = QFileInfo(QFINDTESTDATA("signalbug")).absolutePath();
@@ -1368,10 +1383,10 @@ struct CheckInstanceCount
struct CustomType
{
CustomType(int l1 = 0, int l2 = 0, int l3 = 0): i1(l1), i2(l2), i3(l3)
- { ++instanceCount; }
+ { ++instanceCount; playWithObjects(); }
CustomType(const CustomType &other): i1(other.i1), i2(other.i2), i3(other.i3)
- { ++instanceCount; }
- ~CustomType() { --instanceCount; }
+ { ++instanceCount; playWithObjects(); }
+ ~CustomType() { --instanceCount; playWithObjects(); }
int i1, i2, i3;
int value() { return i1 + i2 + i3; }
@@ -5749,17 +5764,7 @@ public:
{}
~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);
- }
+ playWithObjects();
}
void operator()() {
diff --git a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp
index 71a90e83f7..775156e728 100644
--- a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp
+++ b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp
@@ -172,14 +172,18 @@ void tst_QObjectRace::moveToThreadRace()
class MyObject : public QObject
{ Q_OBJECT
+ bool ok;
+ public:
+ MyObject() : ok(true) {}
+ ~MyObject() { Q_ASSERT(ok); ok = false; }
public slots:
- void slot1() { emit signal1(); }
- void slot2() { emit signal2(); }
- void slot3() { emit signal3(); }
- void slot4() { emit signal4(); }
- void slot5() { emit signal5(); }
- void slot6() { emit signal6(); }
- void slot7() { emit signal7(); }
+ void slot1() { Q_ASSERT(ok); }
+ void slot2() { Q_ASSERT(ok); }
+ void slot3() { Q_ASSERT(ok); }
+ void slot4() { Q_ASSERT(ok); }
+ void slot5() { Q_ASSERT(ok); }
+ void slot6() { Q_ASSERT(ok); }
+ void slot7() { Q_ASSERT(ok); }
signals:
void signal1();
void signal2();
@@ -237,6 +241,10 @@ public:
disconnect(objects[((i+4)*41) % nAlive], _signalsPMF[(18*i)%7], objects[((i+5)*43) % nAlive], _slotsPMF[(19*i+2)%7] );
QMetaObject::Connection c = connect(objects[((i+5)*43) % nAlive], _signalsPMF[(9*i+1)%7], Functor());
+
+ for (int f = 0; f < 7; ++f)
+ emit (objects[i]->*_signalsPMF[f])();
+
disconnect(c);
disconnect(objects[i], _signalsPMF[(10*i+5)%7], 0, 0);
@@ -249,6 +257,9 @@ public:
delete objects[i];
}
+
+ //run the possible queued slots
+ qApp->processEvents();
}
};