summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-11-22 22:09:43 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-11-22 22:09:43 (GMT)
commit774a8ff7444001917287524ac57d370c6995dea0 (patch)
tree9adc84541d1fbe9226e08871979874422c253918 /tests/auto
parent3fa2a510aae1e0c5e18f3b6962c54fae92f3d176 (diff)
parent360f596183969a4c690c77df08d94101428c97c0 (diff)
downloadQt-774a8ff7444001917287524ac57d370c6995dea0.zip
Qt-774a8ff7444001917287524ac57d370c6995dea0.tar.gz
Qt-774a8ff7444001917287524ac57d370c6995dea0.tar.bz2
Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2: optimize ligatureHelper by using qBinaryFind instead of the for loop QFileSystemWatcher: Do not require QApplication in the destructor. Do not define METHOD if QT_NO_KEYWORD is defined. QThreadPrivate::finish should not keep mutex locked when calling signals Make QThreadStorage supports value type and not only pointers. QThreadStorage: fix memory leak if thread storage are added while destroying Compile fix. Fix some warnings on Mac
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp20
-rw-r--r--tests/auto/qthread/tst_qthread.cpp77
-rw-r--r--tests/auto/qthreadstorage/tst_qthreadstorage.cpp146
3 files changed, 243 insertions, 0 deletions
diff --git a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
index a26e34d..fd898ee 100644
--- a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
+++ b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp
@@ -82,6 +82,8 @@ private slots:
void removeFileAndUnWatch();
void cleanup();
+
+ void QTBUG15255_deadlock();
private:
QStringList do_force_engines;
bool do_force_native;
@@ -557,5 +559,23 @@ void tst_QFileSystemWatcher::removeFileAndUnWatch()
watcher.addPath(filename);
}
+class SomeSingleton : public QObject
+{
+public:
+ SomeSingleton() : mFsWatcher(new QFileSystemWatcher(this)) { mFsWatcher->addPath(QLatin1String("/usr/lib"));}
+ void bla() const {}
+ QFileSystemWatcher* mFsWatcher;
+};
+
+Q_GLOBAL_STATIC(SomeSingleton, someSingleton)
+
+void tst_QFileSystemWatcher::QTBUG15255_deadlock()
+{
+ someSingleton()->bla();
+ //the test must still finish
+ QTest::qWait(30);
+}
+
+
QTEST_MAIN(tst_QFileSystemWatcher)
#include "tst_qfilesystemwatcher.moc"
diff --git a/tests/auto/qthread/tst_qthread.cpp b/tests/auto/qthread/tst_qthread.cpp
index f290a2b..49c3576 100644
--- a/tests/auto/qthread/tst_qthread.cpp
+++ b/tests/auto/qthread/tst_qthread.cpp
@@ -107,6 +107,8 @@ private slots:
void QTBUG13810_exitAndStart();
void connectThreadFinishedSignalToObjectDeleteLaterSlot();
+ void wait2();
+ void wait3_slowDestructor();
void stressTest();
};
@@ -976,6 +978,7 @@ void tst_QThread::QTBUG13810_exitAndStart()
QCOMPARE(sync1.m_prop, 89);
}
+
void tst_QThread::connectThreadFinishedSignalToObjectDeleteLaterSlot()
{
QThread thread;
@@ -990,5 +993,79 @@ void tst_QThread::connectThreadFinishedSignalToObjectDeleteLaterSlot()
QVERIFY(p.isNull());
}
+class Waiting_Thread : public QThread
+{
+public:
+ enum { WaitTime = 800 };
+ QMutex mutex;
+ QWaitCondition cond1;
+ QWaitCondition cond2;
+
+ void run()
+ {
+ QMutexLocker locker(&mutex);
+ cond1.wait(&mutex);
+ cond2.wait(&mutex, WaitTime);
+ }
+};
+
+void tst_QThread::wait2()
+{
+ QElapsedTimer timer;
+ Waiting_Thread thread;
+ thread.start();
+ timer.start();
+ QVERIFY(!thread.wait(Waiting_Thread::WaitTime));
+ qint64 elapsed = timer.elapsed();
+
+ QVERIFY(elapsed >= Waiting_Thread::WaitTime);
+ //QVERIFY(elapsed < Waiting_Thread::WaitTime * 1.4);
+
+ timer.start();
+ thread.cond1.wakeOne();
+ QVERIFY(thread.wait(/*Waiting_Thread::WaitTime * 1.4*/));
+ elapsed = timer.elapsed();
+ QVERIFY(elapsed >= Waiting_Thread::WaitTime);
+ //QVERIFY(elapsed < Waiting_Thread::WaitTime * 1.4);
+}
+
+
+class SlowSlotObject : public QObject {
+ Q_OBJECT
+public:
+ QMutex mutex;
+ QWaitCondition cond;
+public slots:
+ void slowSlot() {
+ QMutexLocker locker(&mutex);
+ cond.wait(&mutex);
+ }
+};
+
+void tst_QThread::wait3_slowDestructor()
+{
+ SlowSlotObject slow;
+ QThread thread;
+ QObject::connect(&thread, SIGNAL(finished()), &slow, SLOT(slowSlot()), Qt::DirectConnection);
+
+ enum { WaitTime = 1800 };
+ QElapsedTimer timer;
+
+ thread.start();
+ thread.quit();
+ //the quit function will cause the thread to finish and enter the slowSlot that is blocking
+
+ timer.start();
+ QVERIFY(!thread.wait(Waiting_Thread::WaitTime));
+ qint64 elapsed = timer.elapsed();
+
+ QVERIFY(elapsed >= Waiting_Thread::WaitTime);
+ //QVERIFY(elapsed < Waiting_Thread::WaitTime * 1.4);
+
+ slow.cond.wakeOne();
+ //now the thread shoud finish quickly
+ QVERIFY(thread.wait(one_minute));
+}
+
QTEST_MAIN(tst_QThread)
#include "tst_qthread.moc"
diff --git a/tests/auto/qthreadstorage/tst_qthreadstorage.cpp b/tests/auto/qthreadstorage/tst_qthreadstorage.cpp
index ed86165..90e0311 100644
--- a/tests/auto/qthreadstorage/tst_qthreadstorage.cpp
+++ b/tests/auto/qthreadstorage/tst_qthreadstorage.cpp
@@ -77,6 +77,8 @@ private slots:
void adoptedThreads();
void ensureCleanupOrder();
void QTBUG13877_crashOnExit();
+ void QTBUG14579_leakInDestructor();
+ void valueBased();
};
class Pointer
@@ -310,5 +312,149 @@ void tst_QThreadStorage::QTBUG13877_crashOnExit()
QVERIFY(process.exitStatus() != QProcess::CrashExit);
}
+// S stands for thread Safe.
+class SPointer
+{
+public:
+ static QBasicAtomicInt count;
+ inline SPointer() { count.ref(); }
+ inline ~SPointer() { count.deref(); }
+ inline SPointer(const SPointer &other) { count.ref(); }
+};
+QBasicAtomicInt SPointer::count = Q_BASIC_ATOMIC_INITIALIZER(0);
+
+Q_GLOBAL_STATIC(QThreadStorage<SPointer *>, QTBUG14579_pointers1)
+Q_GLOBAL_STATIC(QThreadStorage<SPointer *>, QTBUG14579_pointers2)
+
+class QTBUG14579_class
+{
+public:
+ SPointer member;
+ inline ~QTBUG14579_class() {
+ QVERIFY(!QTBUG14579_pointers1()->hasLocalData());
+ QVERIFY(!QTBUG14579_pointers2()->hasLocalData());
+ QTBUG14579_pointers2()->setLocalData(new SPointer);
+ QTBUG14579_pointers1()->setLocalData(new SPointer);
+ QVERIFY(QTBUG14579_pointers1()->hasLocalData());
+ QVERIFY(QTBUG14579_pointers2()->hasLocalData());
+ }
+};
+
+
+void tst_QThreadStorage::QTBUG14579_leakInDestructor()
+{
+ class Thread : public QThread
+ {
+ public:
+ QThreadStorage<QTBUG14579_class *> &tls;
+
+ Thread(QThreadStorage<QTBUG14579_class *> &t) : tls(t) { }
+
+ void run()
+ {
+ QVERIFY(!tls.hasLocalData());
+ tls.setLocalData(new QTBUG14579_class);
+ QVERIFY(tls.hasLocalData());
+ }
+ };
+ int c = SPointer::count;
+
+ QThreadStorage<QTBUG14579_class *> tls;
+
+ QVERIFY(!QTBUG14579_pointers1()->hasLocalData());
+ QThreadStorage<int *> tls2; //add some more tls to make sure ids are not following each other too much
+ QThreadStorage<int *> tls3;
+ QVERIFY(!tls2.hasLocalData());
+ QVERIFY(!tls3.hasLocalData());
+ QVERIFY(!tls.hasLocalData());
+
+ Thread t1(tls);
+ Thread t2(tls);
+ Thread t3(tls);
+
+ t1.start();
+ t2.start();
+ t3.start();
+
+ QVERIFY(t1.wait());
+ QVERIFY(t2.wait());
+ QVERIFY(t3.wait());
+
+ //check all the constructed things have been destructed
+ QCOMPARE(int(SPointer::count), c);
+}
+
+void tst_QThreadStorage::valueBased()
+{
+ struct Thread : QThread {
+ QThreadStorage<SPointer> &tlsSPointer;
+ QThreadStorage<QString> &tlsString;
+ QThreadStorage<int> &tlsInt;
+
+ int someNumber;
+ QString someString;
+ Thread(QThreadStorage<SPointer> &t1, QThreadStorage<QString> &t2, QThreadStorage<int> &t3)
+ : tlsSPointer(t1), tlsString(t2), tlsInt(t3) { }
+
+ void run() {
+ /*QVERIFY(!tlsSPointer.hasLocalData());
+ QVERIFY(!tlsString.hasLocalData());
+ QVERIFY(!tlsInt.hasLocalData());*/
+ SPointer pointercopy = tlsSPointer.localData();
+
+ //Default constructed values
+ QVERIFY(tlsString.localData().isNull());
+ QCOMPARE(tlsInt.localData(), 0);
+
+ //setting
+ tlsString.setLocalData(someString);
+ tlsInt.setLocalData(someNumber);
+
+ QCOMPARE(tlsString.localData(), someString);
+ QCOMPARE(tlsInt.localData(), someNumber);
+
+ //changing
+ tlsSPointer.setLocalData(SPointer());
+ tlsInt.localData() += 42;
+ tlsString.localData().append(QLatin1String(" world"));
+
+ QCOMPARE(tlsString.localData(), (someString + QLatin1String(" world")));
+ QCOMPARE(tlsInt.localData(), (someNumber + 42));
+
+ // operator=
+ tlsString.localData() = QString::number(someNumber);
+ QCOMPARE(tlsString.localData().toInt(), someNumber);
+ }
+ };
+
+ QThreadStorage<SPointer> tlsSPointer;
+ QThreadStorage<QString> tlsString;
+ QThreadStorage<int> tlsInt;
+
+ int c = SPointer::count;
+
+ Thread t1(tlsSPointer, tlsString, tlsInt);
+ Thread t2(tlsSPointer, tlsString, tlsInt);
+ Thread t3(tlsSPointer, tlsString, tlsInt);
+ t1.someNumber = 42;
+ t2.someNumber = -128;
+ t3.someNumber = 78;
+ t1.someString = "hello";
+ t2.someString = "trolltech";
+ t3.someString = "nokia";
+
+ t1.start();
+ t2.start();
+ t3.start();
+
+ QVERIFY(t1.wait());
+ QVERIFY(t2.wait());
+ QVERIFY(t3.wait());
+
+ QCOMPARE(c, int(SPointer::count));
+
+}
+
+
QTEST_MAIN(tst_QThreadStorage)
#include "tst_qthreadstorage.moc"