summaryrefslogtreecommitdiffstats
path: root/tests/auto/qeventloop/tst_qeventloop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qeventloop/tst_qeventloop.cpp')
-rw-r--r--tests/auto/qeventloop/tst_qeventloop.cpp937
1 files changed, 0 insertions, 937 deletions
diff --git a/tests/auto/qeventloop/tst_qeventloop.cpp b/tests/auto/qeventloop/tst_qeventloop.cpp
deleted file mode 100644
index a702908549..0000000000
--- a/tests/auto/qeventloop/tst_qeventloop.cpp
+++ /dev/null
@@ -1,937 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include <QtTest/QtTest>
-
-
-#include <qabstracteventdispatcher.h>
-#include <qcoreapplication.h>
-#include <qcoreevent.h>
-#include <qeventloop.h>
-#include <qmutex.h>
-#include <qthread.h>
-#include <qtimer.h>
-#include <qwaitcondition.h>
-#include <QTcpServer>
-#include <QTcpSocket>
-
-#ifdef Q_OS_SYMBIAN
-#include <e32base.h>
-#include <unistd.h>
-#endif
-
-#include "../../shared/util.h"
-
-//TESTED_CLASS=
-//TESTED_FILES=
-
-class EventLoopExiter : public QObject
-{
- Q_OBJECT
- QEventLoop *eventLoop;
-public:
- inline EventLoopExiter(QEventLoop *el)
- : eventLoop(el)
- { }
-public slots:
- void exit();
- void exit1();
- void exit2();
-};
-
-void EventLoopExiter::exit()
-{ eventLoop->exit(); }
-
-void EventLoopExiter::exit1()
-{ eventLoop->exit(1); }
-
-void EventLoopExiter::exit2()
-{ eventLoop->exit(2); }
-
-class EventLoopThread : public QThread
-{
- Q_OBJECT
-signals:
- void checkPoint();
-public:
- QEventLoop *eventLoop;
- void run();
-};
-
-void EventLoopThread::run()
-{
- eventLoop = new QEventLoop;
- emit checkPoint();
- (void) eventLoop->exec();
- delete eventLoop;
- eventLoop = 0;
-}
-
-class MultipleExecThread : public QThread
-{
- Q_OBJECT
-signals:
- void checkPoint();
-public:
- QMutex mutex;
- QWaitCondition cond;
- volatile int result1;
- volatile int result2;
- MultipleExecThread() : result1(0xdead), result2(0xbeef) {}
-
- void run()
- {
- QMutexLocker locker(&mutex);
- // this exec should work
-
- cond.wakeOne();
- cond.wait(&mutex);
-
- QTimer timer;
- connect(&timer, SIGNAL(timeout()), SLOT(quit()), Qt::DirectConnection);
- timer.setInterval(1000);
- timer.start();
- result1 = exec();
-
- // this should return immediately, since exit() has been called
- cond.wakeOne();
- cond.wait(&mutex);
- QEventLoop eventLoop;
- result2 = eventLoop.exec();
- }
-};
-
-class StartStopEvent: public QEvent
-{
-public:
- StartStopEvent(int type, QEventLoop *loop = 0)
- : QEvent(Type(type)), el(loop)
- { }
-
- QEventLoop *el;
-};
-
-class EventLoopExecutor : public QObject
-{
- Q_OBJECT
- QEventLoop *eventLoop;
-public:
- int returnCode;
- EventLoopExecutor(QEventLoop *eventLoop)
- : QObject(), eventLoop(eventLoop), returnCode(-42)
- {
- }
-public slots:
- void exec()
- {
- QTimer::singleShot(100, eventLoop, SLOT(quit()));
- // this should return immediately, and the timer event should be delivered to
- // tst_QEventLoop::exec() test, letting the test complete
- returnCode = eventLoop->exec();
- }
-};
-
-#ifndef QT_NO_EXCEPTIONS
-class QEventLoopTestException { };
-
-class ExceptionThrower : public QObject
-{
- Q_OBJECT
-public:
- ExceptionThrower() : QObject() { }
-public slots:
- void throwException()
- {
- QEventLoopTestException e;
- throw e;
- }
-};
-#endif
-
-class tst_QEventLoop : public QObject
-{
- Q_OBJECT
-public:
- tst_QEventLoop();
- ~tst_QEventLoop();
-public slots:
- void init();
- void cleanup();
-private slots:
- // This test *must* run first. See the definition for why.
- void onlySymbianActiveScheduler();
- void symbianNestedActiveSchedulerLoop_data();
- void symbianNestedActiveSchedulerLoop();
- void processEvents();
- void exec();
- void throwInExec();
- void reexec();
- void exit();
- void execAfterExit();
- void wakeUp();
- void quit();
- void processEventsExcludeSocket();
- void processEventsExcludeTimers();
- void deliverInDefinedOrder_QTBUG19637();
-
- // keep this test last:
- void nestedLoops();
-
-protected:
- void customEvent(QEvent *e);
-};
-
-tst_QEventLoop::tst_QEventLoop()
-{ }
-
-tst_QEventLoop::~tst_QEventLoop()
-{ }
-
-void tst_QEventLoop::init()
-{ }
-
-void tst_QEventLoop::cleanup()
-{ }
-
-#ifdef Q_OS_SYMBIAN
-class OnlySymbianActiveScheduler_helper : public QObject
-{
- Q_OBJECT
-
-public:
- OnlySymbianActiveScheduler_helper(int fd, QTimer *zeroTimer)
- : fd(fd),
- timerCount(0),
- zeroTimer(zeroTimer),
- zeroTimerCount(0),
- notifierCount(0)
- {
- }
- ~OnlySymbianActiveScheduler_helper() {}
-
-public slots:
- void timerSlot()
- {
- // Let all the events occur twice so we know they reactivated after
- // each occurrence.
- if (++timerCount >= 2) {
- // This will hopefully run last, so stop the active scheduler.
- CActiveScheduler::Stop();
- }
- }
- void zeroTimerSlot()
- {
- if (++zeroTimerCount >= 2) {
- zeroTimer->stop();
- }
- }
- void notifierSlot()
- {
- if (++notifierCount >= 2) {
- char dummy;
- ::read(fd, &dummy, 1);
- }
- }
-
-private:
- int fd;
- int timerCount;
- QTimer *zeroTimer;
- int zeroTimerCount;
- int notifierCount;
-};
-#endif
-
-void tst_QEventLoop::onlySymbianActiveScheduler() {
-#ifndef Q_OS_SYMBIAN
- QSKIP("This is a Symbian-only test.", SkipAll);
-#else
- // In here we try to use timers and sockets exclusively using the Symbian
- // active scheduler and no processEvents().
- // This test should therefore be run first, so that we can verify that
- // the first occurrence of processEvents does not do any initialization that
- // we depend on.
-
- // Open up a pipe so we can test socket notifiers.
- int pipeEnds[2];
- if (::pipe(pipeEnds) != 0) {
- QFAIL("Could not open pipe");
- }
- QSocketNotifier notifier(pipeEnds[0], QSocketNotifier::Read);
- QSignalSpy notifierSpy(&notifier, SIGNAL(activated(int)));
- char dummy = 1;
- ::write(pipeEnds[1], &dummy, 1);
-
- QTimer zeroTimer;
- QSignalSpy zeroTimerSpy(&zeroTimer, SIGNAL(timeout()));
- zeroTimer.setInterval(0);
- zeroTimer.start();
-
- QTimer timer;
- QSignalSpy timerSpy(&timer, SIGNAL(timeout()));
- timer.setInterval(2000); // Generous timeout or this test will fail if there is high load
- timer.start();
-
- OnlySymbianActiveScheduler_helper helper(pipeEnds[0], &zeroTimer);
- connect(&notifier, SIGNAL(activated(int)), &helper, SLOT(notifierSlot()));
- connect(&zeroTimer, SIGNAL(timeout()), &helper, SLOT(zeroTimerSlot()));
- connect(&timer, SIGNAL(timeout()), &helper, SLOT(timerSlot()));
-
- CActiveScheduler::Start();
-
- ::close(pipeEnds[1]);
- ::close(pipeEnds[0]);
-
- QCOMPARE(notifierSpy.count(), 2);
- QCOMPARE(zeroTimerSpy.count(), 2);
- QCOMPARE(timerSpy.count(), 2);
-#endif
-}
-
-void tst_QEventLoop::processEvents()
-{
- QSignalSpy spy1(QAbstractEventDispatcher::instance(), SIGNAL(aboutToBlock()));
- QSignalSpy spy2(QAbstractEventDispatcher::instance(), SIGNAL(awake()));
-
- QEventLoop eventLoop;
-
- QCoreApplication::postEvent(&eventLoop, new QEvent(QEvent::User));
-
- // process posted events, QEventLoop::processEvents() should return
- // true
- QVERIFY(eventLoop.processEvents());
- QCOMPARE(spy1.count(), 0);
- QCOMPARE(spy2.count(), 1);
-
- // allow any session manager to complete its handshake, so that
- // there are no pending events left.
- while (eventLoop.processEvents())
- ;
-
- // On mac we get application started events at this point,
- // so process events one more time just to be sure.
- eventLoop.processEvents();
-
- // no events to process, QEventLoop::processEvents() should return
- // false
- spy1.clear();
- spy2.clear();
- QVERIFY(!eventLoop.processEvents());
- QCOMPARE(spy1.count(), 0);
- QCOMPARE(spy2.count(), 1);
-
- // make sure the test doesn't block forever
- int timerId = startTimer(100);
-
- // wait for more events to process, QEventLoop::processEvents()
- // should return true
- spy1.clear();
- spy2.clear();
- QVERIFY(eventLoop.processEvents(QEventLoop::WaitForMoreEvents));
-
- // Verify that the eventloop has blocked and woken up. Some eventloops
- // may block and wake up multiple times.
- QVERIFY(spy1.count() > 0);
- QVERIFY(spy2.count() > 0);
- // We should get one awake for each aboutToBlock, plus one awake when
- // processEvents is entered.
- QVERIFY(spy2.count() >= spy1.count());
-
- killTimer(timerId);
-}
-
-#if defined(Q_OS_SYMBIAN) && defined(Q_CC_NOKIAX86)
-// Symbian needs bit longer timeout for emulator, as emulator startup causes additional delay
-# define EXEC_TIMEOUT 1000
-#else
-# define EXEC_TIMEOUT 100
-#endif
-
-
-void tst_QEventLoop::exec()
-{
- {
- QEventLoop eventLoop;
- EventLoopExiter exiter(&eventLoop);
- int returnCode;
-
- QTimer::singleShot(EXEC_TIMEOUT, &exiter, SLOT(exit()));
- returnCode = eventLoop.exec();
- QCOMPARE(returnCode, 0);
-
- QTimer::singleShot(EXEC_TIMEOUT, &exiter, SLOT(exit1()));
- returnCode = eventLoop.exec();
- QCOMPARE(returnCode, 1);
-
- QTimer::singleShot(EXEC_TIMEOUT, &exiter, SLOT(exit2()));
- returnCode = eventLoop.exec();
- QCOMPARE(returnCode, 2);
- }
-
- {
- // calling QEventLoop::exec() after a thread loop has exit()ed should return immediately
- // Note: this behaviour differs from QCoreApplication and QEventLoop
- // see tst_QCoreApplication::eventLoopExecAfterExit, tst_QEventLoop::reexec
- MultipleExecThread thread;
-
- // start thread and wait for checkpoint
- thread.mutex.lock();
- thread.start();
- thread.cond.wait(&thread.mutex);
-
- // make sure the eventloop runs
- QSignalSpy spy(QAbstractEventDispatcher::instance(&thread), SIGNAL(awake()));
- thread.cond.wakeOne();
- thread.cond.wait(&thread.mutex);
- QVERIFY(spy.count() > 0);
- int v = thread.result1;
- QCOMPARE(v, 0);
-
- // exec should return immediately
- spy.clear();
- thread.cond.wakeOne();
- thread.mutex.unlock();
- thread.wait();
- QCOMPARE(spy.count(), 0);
- v = thread.result2;
- QCOMPARE(v, -1);
- }
-
- {
- // a single instance of QEventLoop should not be allowed to recurse into exec()
- QEventLoop eventLoop;
- EventLoopExecutor executor(&eventLoop);
-
- QTimer::singleShot(EXEC_TIMEOUT, &executor, SLOT(exec()));
- int returnCode = eventLoop.exec();
- QCOMPARE(returnCode, 0);
- QCOMPARE(executor.returnCode, -1);
- }
-}
-
-void tst_QEventLoop::throwInExec()
-{
-#if defined(QT_NO_EXCEPTIONS) || defined(NO_EVENTLOOP_EXCEPTIONS)
- QSKIP("Exceptions are disabled", SkipAll);
-#elif defined(Q_OS_WINCE_WM) || defined(Q_OS_SYMBIAN)
- // Windows Mobile cannot handle cross library exceptions
- // qobject.cpp will try to rethrow the exception after handling
- // which causes gwes.exe to crash
-
- // Symbian doesn't propagate exceptions from eventloop, but converts them to
- // CActiveScheduler errors instead -> this test will hang.
- QSKIP("This platform doesn't support propagating exceptions through the event loop", SkipAll);
-#elif defined(Q_OS_LINUX)
- // C++ exceptions can't be passed through glib callbacks. Skip the test if
- // we're using the glib event loop.
- QByteArray dispatcher = QAbstractEventDispatcher::instance()->metaObject()->className();
- if (dispatcher.contains("Glib")) {
- QSKIP(
- qPrintable(QString(
- "Throwing exceptions in exec() won't work if %1 event dispatcher is used.\n"
- "Try running with QT_NO_GLIB=1 in environment."
- ).arg(QString::fromLatin1(dispatcher))),
- SkipAll
- );
- }
-#endif
-
- {
- // QEventLoop::exec() is exception safe
- QEventLoop eventLoop;
- int caughtExceptions = 0;
-
- try {
- ExceptionThrower exceptionThrower;
- QTimer::singleShot(EXEC_TIMEOUT, &exceptionThrower, SLOT(throwException()));
- (void) eventLoop.exec();
- } catch (...) {
- ++caughtExceptions;
- }
- try {
- ExceptionThrower exceptionThrower;
- QTimer::singleShot(EXEC_TIMEOUT, &exceptionThrower, SLOT(throwException()));
- (void) eventLoop.exec();
- } catch (...) {
- ++caughtExceptions;
- }
- QCOMPARE(caughtExceptions, 2);
- }
-}
-
-void tst_QEventLoop::reexec()
-{
- QEventLoop loop;
-
- // exec once
- QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection);
- QCOMPARE(loop.exec(), 0);
-
- // and again
- QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection);
- QCOMPARE(loop.exec(), 0);
-}
-
-void tst_QEventLoop::exit()
-{ DEPENDS_ON(exec()); }
-
-void tst_QEventLoop::execAfterExit()
-{
- QEventLoop loop;
- EventLoopExiter obj(&loop);
-
- QMetaObject::invokeMethod(&obj, "exit", Qt::QueuedConnection);
- loop.exit(1);
- QCOMPARE(loop.exec(), 0);
-}
-
-void tst_QEventLoop::wakeUp()
-{
- EventLoopThread thread;
- QEventLoop eventLoop;
- connect(&thread, SIGNAL(checkPoint()), &eventLoop, SLOT(quit()));
- connect(&thread, SIGNAL(finished()), &eventLoop, SLOT(quit()));
-
- thread.start();
- (void) eventLoop.exec();
-
- QSignalSpy spy(QAbstractEventDispatcher::instance(&thread), SIGNAL(awake()));
- thread.eventLoop->wakeUp();
-
- // give the thread time to wake up
- QTimer::singleShot(1000, &eventLoop, SLOT(quit()));
- (void) eventLoop.exec();
-
- QVERIFY(spy.count() > 0);
-
- thread.quit();
- (void) eventLoop.exec();
-}
-
-void tst_QEventLoop::quit()
-{
- QEventLoop eventLoop;
- int returnCode;
-
- QTimer::singleShot(100, &eventLoop, SLOT(quit()));
- returnCode = eventLoop.exec();
- QCOMPARE(returnCode, 0);
-}
-
-
-void tst_QEventLoop::nestedLoops()
-{
- QCoreApplication::postEvent(this, new StartStopEvent(QEvent::User));
- QCoreApplication::postEvent(this, new StartStopEvent(QEvent::User));
- QCoreApplication::postEvent(this, new StartStopEvent(QEvent::User));
-
- // without the fix, this will *wedge* and never return
- QTest::qWait(1000);
-}
-
-void tst_QEventLoop::customEvent(QEvent *e)
-{
- if (e->type() == QEvent::User) {
- QEventLoop loop;
- QCoreApplication::postEvent(this, new StartStopEvent(int(QEvent::User) + 1, &loop));
- loop.exec();
- } else {
- static_cast<StartStopEvent *>(e)->el->exit();
- }
-}
-
-class SocketEventsTester: public QObject
-{
- Q_OBJECT
-public:
- SocketEventsTester()
- {
- socket = 0;
- server = 0;
- dataArrived = false;
- testResult = false;
- }
- ~SocketEventsTester()
- {
- delete socket;
- delete server;
- }
- bool init()
- {
- bool ret = false;
- server = new QTcpServer();
- socket = new QTcpSocket();
- connect(server, SIGNAL(newConnection()), this, SLOT(sendHello()));
- connect(socket, SIGNAL(readyRead()), this, SLOT(sendAck()), Qt::DirectConnection);
- if((ret = server->listen(QHostAddress::LocalHost, 0))) {
- socket->connectToHost(server->serverAddress(), server->serverPort());
- socket->waitForConnected();
- }
- return ret;
- }
-
- QTcpSocket *socket;
- QTcpServer *server;
- bool dataArrived;
- bool testResult;
-public slots:
- void sendAck()
- {
- dataArrived = true;
- }
- void sendHello()
- {
- char data[10] ="HELLO";
- qint64 size = sizeof(data);
-
- QTcpSocket *serverSocket = server->nextPendingConnection();
- serverSocket->write(data, size);
- serverSocket->flush();
- QTest::qSleep(200); //allow the TCP/IP stack time to loopback the data, so our socket is ready to read
- QCoreApplication::processEvents(QEventLoop::ExcludeSocketNotifiers);
- testResult = dataArrived;
- QCoreApplication::processEvents(); //check the deferred event is processed
- serverSocket->close();
- QThread::currentThread()->exit(0);
- }
-};
-
-class SocketTestThread : public QThread
-{
- Q_OBJECT
-public:
- SocketTestThread():QThread(0),testResult(false){};
- void run()
- {
- SocketEventsTester *tester = new SocketEventsTester();
- if (tester->init())
- exec();
- testResult = tester->testResult;
- dataArrived = tester->dataArrived;
- delete tester;
- }
- bool testResult;
- bool dataArrived;
-};
-
-void tst_QEventLoop::processEventsExcludeSocket()
-{
- SocketTestThread thread;
- thread.start();
- QVERIFY(thread.wait());
- QVERIFY(!thread.testResult);
- QVERIFY(thread.dataArrived);
-}
-
-class TimerReceiver : public QObject
-{
-public:
- int gotTimerEvent;
-
- TimerReceiver()
- : QObject(), gotTimerEvent(-1)
- { }
-
- void timerEvent(QTimerEvent *event)
- {
- gotTimerEvent = event->timerId();
- }
-};
-
-void tst_QEventLoop::processEventsExcludeTimers()
-{
- TimerReceiver timerReceiver;
- int timerId = timerReceiver.startTimer(0);
-
- QEventLoop eventLoop;
-
- // normal process events will send timers
- eventLoop.processEvents();
- QCOMPARE(timerReceiver.gotTimerEvent, timerId);
- timerReceiver.gotTimerEvent = -1;
-
- // normal process events will send timers
- eventLoop.processEvents(QEventLoop::X11ExcludeTimers);
-#if !defined(Q_OS_UNIX) || defined(Q_OS_SYMBIAN)
- QEXPECT_FAIL("", "X11ExcludeTimers only works on UN*X", Continue);
-#endif
- QCOMPARE(timerReceiver.gotTimerEvent, -1);
- timerReceiver.gotTimerEvent = -1;
-
- // resume timer processing
- eventLoop.processEvents();
- QCOMPARE(timerReceiver.gotTimerEvent, timerId);
- timerReceiver.gotTimerEvent = -1;
-}
-
-#ifdef Q_OS_SYMBIAN
-class DummyActiveObject : public CActive
-{
-public:
- DummyActiveObject(int levels);
- ~DummyActiveObject();
-
- void Start();
-
-protected:
- void DoCancel();
- void RunL();
-
-public:
- bool succeeded;
-
-private:
- RTimer m_rTimer;
- int remainingLevels;
-};
-
-class ActiveSchedulerLoop : public QObject
-{
-public:
- ActiveSchedulerLoop(int levels) : succeeded(false), timerId(-1), remainingLevels(levels) {}
- ~ActiveSchedulerLoop() {}
-
- void timerEvent(QTimerEvent *e);
-
-public:
- bool succeeded;
- int timerId;
- int remainingLevels;
-};
-
-DummyActiveObject::DummyActiveObject(int levels)
- : CActive(CActive::EPriorityStandard),
- succeeded(false),
- remainingLevels(levels)
-{
- m_rTimer.CreateLocal();
-}
-
-DummyActiveObject::~DummyActiveObject()
-{
- Cancel();
- m_rTimer.Close();
-}
-
-void DummyActiveObject::DoCancel()
-{
- m_rTimer.Cancel();
-}
-
-void DummyActiveObject::RunL()
-{
- if (remainingLevels - 1 <= 0) {
- ActiveSchedulerLoop loop(remainingLevels - 1);
- loop.timerId = loop.startTimer(0);
- QCoreApplication::processEvents();
-
- succeeded = loop.succeeded;
- } else {
- succeeded = true;
- }
- CActiveScheduler::Stop();
-}
-
-void DummyActiveObject::Start()
-{
- m_rTimer.After(iStatus, 100000); // 100 ms
- SetActive();
-}
-
-void ActiveSchedulerLoop::timerEvent(QTimerEvent *e)
-{
- Q_UNUSED(e);
- DummyActiveObject *dummy = new(ELeave) DummyActiveObject(remainingLevels);
- CActiveScheduler::Add(dummy);
-
- dummy->Start();
-
- CActiveScheduler::Start();
-
- succeeded = dummy->succeeded;
-
- delete dummy;
-
- killTimer(timerId);
-}
-
-// We cannot trap panics when the test case fails, so run it in a different thread instead.
-class ActiveSchedulerThread : public QThread
-{
-public:
- ActiveSchedulerThread(QEventLoop::ProcessEventsFlag flags);
- ~ActiveSchedulerThread();
-
-protected:
- void run();
-
-public:
- volatile bool succeeded;
-
-private:
- QEventLoop::ProcessEventsFlag m_flags;
-};
-
-ActiveSchedulerThread::ActiveSchedulerThread(QEventLoop::ProcessEventsFlag flags)
- : succeeded(false),
- m_flags(flags)
-{
-}
-
-ActiveSchedulerThread::~ActiveSchedulerThread()
-{
-}
-
-void ActiveSchedulerThread::run()
-{
- ActiveSchedulerLoop loop(2);
- loop.timerId = loop.startTimer(0);
- // It may panic in here if the active scheduler and the Qt loop don't go together.
- QCoreApplication::processEvents(m_flags);
-
- succeeded = loop.succeeded;
-}
-#endif // ifdef Q_OS_SYMBIAN
-
-void tst_QEventLoop::symbianNestedActiveSchedulerLoop_data()
-{
- QTest::addColumn<int>("processEventFlags");
-
- QTest::newRow("AllEvents") << (int)QEventLoop::AllEvents;
- QTest::newRow("WaitForMoreEvents") << (int)QEventLoop::WaitForMoreEvents;
-}
-
-/*
- Before you start fiddling with this test, you should have a good understanding of how
- Symbian active objects work. What the test does is to try to screw up the semaphore count
- in the active scheduler to cause stray signals, by running the Qt event loop and the
- active scheduler inside each other. Naturally, its attempts to do this should be futile!
-*/
-void tst_QEventLoop::symbianNestedActiveSchedulerLoop()
-{
-#ifndef Q_OS_SYMBIAN
- QSKIP("This is a Symbian only test.", SkipAll);
-#else
- QFETCH(int, processEventFlags);
-
- ActiveSchedulerThread thread((QEventLoop::ProcessEventsFlag)processEventFlags);
- thread.start();
- thread.wait(2000);
-
- QVERIFY(thread.succeeded);
-#endif
-}
-
-Q_DECLARE_METATYPE(QThread*)
-
-namespace DeliverInDefinedOrder_QTBUG19637 {
- enum { NbThread = 3, NbObject = 500, NbEventQueue = 5, NbEvent = 50 };
-
- struct CustomEvent : public QEvent {
- CustomEvent(int q, int v) : QEvent(Type(User + q)), value(v) {}
- int value;
- };
-
- struct Object : public QObject {
- Q_OBJECT
- public:
- Object() : count(0) {
- for (int i = 0; i < NbEventQueue; i++)
- lastReceived[i] = -1;
- }
- int lastReceived[NbEventQueue];
- int count;
- virtual void customEvent(QEvent* e) {
- QVERIFY(e->type() >= QEvent::User);
- QVERIFY(e->type() < QEvent::User + 5);
- uint idx = e->type() - QEvent::User;
- int value = static_cast<CustomEvent *>(e)->value;
- QVERIFY(lastReceived[idx] < value);
- lastReceived[idx] = value;
- count++;
- }
-
- public slots:
- void moveToThread(QThread *t) {
- QObject::moveToThread(t);
- }
- };
-
-}
-
-void tst_QEventLoop::deliverInDefinedOrder_QTBUG19637()
-{
- using namespace DeliverInDefinedOrder_QTBUG19637;
- qMetaTypeId<QThread*>();
- QThread threads[NbThread];
- Object objects[NbObject];
- for (int t = 0; t < NbThread; t++) {
- threads[t].start();
- }
-
- int event = 0;
-
- for (int o = 0; o < NbObject; o++) {
- objects[o].moveToThread(&threads[o % NbThread]);
- for (int e = 0; e < NbEvent; e++) {
- int q = e % NbEventQueue;
- QCoreApplication::postEvent(&objects[o], new CustomEvent(q, ++event) , q);
- if (e % 7)
- QMetaObject::invokeMethod(&objects[o], "moveToThread", Qt::QueuedConnection, Q_ARG(QThread*, &threads[(e+o)%NbThread]));
- }
- }
-
- QTest::qWait(30);
- for (int o = 0; o < NbObject; o++) {
- QTRY_COMPARE(objects[o].count, int(NbEvent));
- }
-
- for (int t = 0; t < NbThread; t++) {
- threads[t].quit();
- threads[t].wait();
- }
-
-}
-
-
-QTEST_MAIN(tst_QEventLoop)
-#include "tst_qeventloop.moc"