diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-04-16 17:21:37 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2015-07-18 02:24:59 +0000 |
commit | 10c529b08de7cd55b4c3e3654464119246498273 (patch) | |
tree | b2ebe0a8bc1cef7767817b20cf88cda41d6df6c2 /tests/auto/corelib/kernel | |
parent | 9d98584a835962ca7ad870bbede8f6ab7f66b6bf (diff) | |
download | qtbase-10c529b08de7cd55b4c3e3654464119246498273.tar.gz |
Add a way for auxiliary threads to handle events without CoreApp
Long-lived threads started by Qt itself can now receive events even if
QCoreApplication hasn't been created. This is required in all threads we
start that will handle events, unless we're sure that the thread will
exit before the global application object begins destruction.
Otherwise, those threads will have race conditions dealing with the
event delivery system trying to call the QCoreApplication::notify()
virtual while the object is being destroyed.
Change-Id: I27eaacb532114dd188c4ffff13d4ad2a4bb443e6
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Diffstat (limited to 'tests/auto/corelib/kernel')
3 files changed, 53 insertions, 0 deletions
diff --git a/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro b/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro index 0602b9fc38..1039f2c08d 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro +++ b/tests/auto/corelib/kernel/qcoreapplication/qcoreapplication.pro @@ -3,3 +3,4 @@ TARGET = tst_qcoreapplication QT = core testlib core-private SOURCES = tst_qcoreapplication.cpp HEADERS = tst_qcoreapplication.h +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index efecf31d66..696a1c4722 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -78,6 +78,21 @@ public: } }; +class Thread : public QDaemonThread +{ + void run() Q_DECL_OVERRIDE + { + QThreadData *data = QThreadData::current(); + QVERIFY(!data->requiresCoreApplication); // daemon thread + data->requiresCoreApplication = requiresCoreApplication; + QThread::run(); + } + +public: + Thread() : requiresCoreApplication(true) {} + bool requiresCoreApplication; +}; + void tst_QCoreApplication::sendEventsOnProcessEvents() { int argc = 1; @@ -853,6 +868,41 @@ void tst_QCoreApplication::applicationEventFilters_auxThread() QVERIFY(!spy.recordedEvents.contains(QEvent::User + 1)); } +void tst_QCoreApplication::threadedEventDelivery_data() +{ + QTest::addColumn<bool>("requiresCoreApplication"); + QTest::addColumn<bool>("createCoreApplication"); + QTest::addColumn<bool>("eventsReceived"); + + // invalid combination: + //QTest::newRow("default-without-coreapp") << true << false << false; + QTest::newRow("default") << true << true << true; + QTest::newRow("independent-without-coreapp") << false << false << true; + QTest::newRow("independent-with-coreapp") << false << true << true; +} + +// posts the event before the QCoreApplication is destroyed, starts thread after +void tst_QCoreApplication::threadedEventDelivery() +{ + QFETCH(bool, requiresCoreApplication); + QFETCH(bool, createCoreApplication); + QFETCH(bool, eventsReceived); + + int argc = 1; + char *argv[] = { const_cast<char*>(QTest::currentAppName()) }; + QScopedPointer<TestApplication> app(createCoreApplication ? new TestApplication(argc, argv) : 0); + + Thread thread; + thread.requiresCoreApplication = requiresCoreApplication; + ThreadedEventReceiver receiver; + receiver.moveToThread(&thread); + QCoreApplication::postEvent(&receiver, new QEvent(QEvent::Type(QEvent::User + 1))); + + thread.start(); + QVERIFY(thread.wait(1000)); + QCOMPARE(receiver.recordedEvents.contains(QEvent::User + 1), eventsReceived); +} + static void createQObjectOnDestruction() { // Make sure that we can create a QObject after the last QObject has been diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h index 09e15723ac..8efe374a2b 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.h @@ -61,6 +61,8 @@ private slots: void QTBUG31606_QEventDestructorDeadLock(); void applicationEventFilters_mainThread(); void applicationEventFilters_auxThread(); + void threadedEventDelivery_data(); + void threadedEventDelivery(); }; #endif // TST_QCOREAPPLICATION_H |