diff options
-rw-r--r-- | src/corelib/io/qprocess_symbian.cpp | 3 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_symbian.cpp | 48 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_symbian_p.h | 10 | ||||
-rw-r--r-- | tests/auto/exceptionsafety/tst_exceptionsafety.cpp | 23 |
4 files changed, 58 insertions, 26 deletions
diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index 26e7cdc..7da6a1d 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -65,6 +65,7 @@ #include "qstring.h" #include "qprocess.h" #include "qprocess_p.h" +#include "qeventdispatcher_symbian_p.h" #include <private/qthread_p.h> #include <qmutex.h> @@ -594,7 +595,7 @@ TInt processManagerThreadFunction(TAny* param) QProcessManager* manager = reinterpret_cast<QProcessManager*>(param); - CActiveScheduler* scheduler = new CActiveScheduler(); + CActiveScheduler* scheduler = new CQtActiveScheduler(); QPROCESS_ASSERT(scheduler, EProcessManagerSchedulerCreationFail, diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 423fbaa..27118be 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -246,7 +246,7 @@ void QTimerActiveObject::Run() SymbianTimerInfoPtr timerInfoPtr(m_timerInfo); m_timerInfo->dispatcher->timerFired(m_timerInfo->timerId); - + iStatus = KRequestPending; SetActive(); TRequestStatus *status = &iStatus; @@ -615,7 +615,7 @@ QEventDispatcherSymbian::~QEventDispatcherSymbian() void QEventDispatcherSymbian::startingUp() { if( !CActiveScheduler::Current() ) { - m_activeScheduler = new(ELeave)CActiveScheduler(); + m_activeScheduler = new(ELeave)CQtActiveScheduler(); CActiveScheduler::Install(m_activeScheduler); } m_wakeUpAO = new(ELeave) QWakeUpActiveObject(this); @@ -643,13 +643,13 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla QT_TRY { Q_D(QAbstractEventDispatcher); - + // It is safe if this counter overflows. The main importance is that each // iteration count is different from the last. m_iterationCount++; RThread &thread = d->threadData->symbian_thread_handle; - + bool block; if (flags & QEventLoop::WaitForMoreEvents) { block = true; @@ -657,7 +657,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla } else { block = false; } - + bool oldNoSocketEventsValue = m_noSocketEvents; if (flags & QEventLoop::ExcludeSocketNotifiers) { m_noSocketEvents = true; @@ -665,10 +665,10 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla m_noSocketEvents = false; handledAnyEvent = sendDeferredSocketEvents(); } - + bool handledSymbianEvent = false; m_interrupt = false; - + /* * This QTime variable is used to measure the time it takes to finish * the event loop. If we take too long in the loop, other processes @@ -684,9 +684,9 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla SubsequentRun, TimeStarted } timeState = FirstRun; - + TProcessPriority priority; - + while (1) { if (block) { // This is where Qt will spend most of its time. @@ -698,19 +698,19 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla // This one should return without delay. CActiveScheduler::Current()->WaitForAnyRequest(); } - + if (timeState == SubsequentRun) { time.start(); timeState = TimeStarted; } - + TInt error; handledSymbianEvent = CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle); if (error) { qWarning("CActiveScheduler::RunIfReady() returned error: %i\n", error); CActiveScheduler::Current()->Error(error); } - + if (!handledSymbianEvent) { qFatal("QEventDispatcherSymbian::processEvents(): Caught Symbian stray signal"); } @@ -732,14 +732,14 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla if (timeState == FirstRun) timeState = SubsequentRun; }; - + emit awake(); - + m_noSocketEvents = oldNoSocketEventsValue; } QT_CATCH (const std::exception& ex) { -#ifndef QT_NO_EXCEPTIONS +#ifndef QT_NO_EXCEPTIONS CActiveScheduler::Current()->Error(qt_translateExceptionToSymbianError(ex)); -#endif +#endif } return handledAnyEvent; @@ -969,5 +969,21 @@ QList<QEventDispatcherSymbian::TimerInfo> QEventDispatcherSymbian::registeredTim return list; } +/* + * This active scheduler class implements a simple report and continue policy, for Symbian OS leaves + * or exceptions from Qt that fall back to the scheduler. + * It will be used in cases where there is no existing active scheduler installed. + * Apps which link to qts60main.lib will have the UI active scheduler installed in the main thread + * instead of this one. But this would be used in other threads in the UI. + * An app could replace this behaviour by installing an alternative active scheduler. + */ +void CQtActiveScheduler::Error(TInt aError) const +{ + try { + qWarning("Error from active scheduler %d", aError); + } + catch (const std::bad_alloc&) {} // ignore alloc fails, nothing more can be done +} + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h index 3593055..c1cf7b6 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian_p.h +++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h @@ -136,7 +136,7 @@ public: protected: void DoCancel(); void RunL(); - + private: void Run(); @@ -209,6 +209,12 @@ private: bool m_quit; }; +class Q_CORE_EXPORT CQtActiveScheduler : public CActiveScheduler + { +public: // from CActiveScheduler + virtual void Error(TInt aError) const; + }; + class Q_CORE_EXPORT QEventDispatcherSymbian : public QAbstractEventDispatcher { Q_DECLARE_PRIVATE(QAbstractEventDispatcher) @@ -253,7 +259,7 @@ private: private: QSelectThread m_selectThread; - CActiveScheduler *m_activeScheduler; + CQtActiveScheduler *m_activeScheduler; QHash<int, SymbianTimerInfoPtr> m_timerList; QHash<QSocketNotifier *, QSocketActiveObject *> m_notifiers; diff --git a/tests/auto/exceptionsafety/tst_exceptionsafety.cpp b/tests/auto/exceptionsafety/tst_exceptionsafety.cpp index 8ed2913..4dce86d 100644 --- a/tests/auto/exceptionsafety/tst_exceptionsafety.cpp +++ b/tests/auto/exceptionsafety/tst_exceptionsafety.cpp @@ -617,6 +617,12 @@ public: {} }; +struct IntEx : public std::exception +{ + IntEx(int aEx) : ex(aEx) {} + int ex; +}; + class TestObject : public QObject { public: @@ -630,7 +636,7 @@ protected: bool event(QEvent *event) { if (int(event->type()) == ThrowEventId) { - throw ++throwEventCount; + throw IntEx(++throwEventCount); } else if (int(event->type()) == NoThrowEventId) { ++noThrowEventCount; } @@ -645,8 +651,8 @@ void tst_ExceptionSafety::exceptionEventLoop() ThrowEvent throwEvent; try { qApp->sendEvent(&obj, &throwEvent); - } catch (int code) { - QCOMPARE(code, 1); + } catch (IntEx code) { + QCOMPARE(code.ex, 1); } QCOMPARE(obj.throwEventCount, 1); @@ -655,8 +661,8 @@ void tst_ExceptionSafety::exceptionEventLoop() try { qApp->processEvents(); - } catch (int code) { - QCOMPARE(code, 2); + } catch (IntEx code) { + QCOMPARE(code.ex, 2); } QCOMPARE(obj.throwEventCount, 2); @@ -669,12 +675,15 @@ void tst_ExceptionSafety::exceptionEventLoop() try { qApp->processEvents(); - } catch (int code) { - QCOMPARE(code, 3); + } catch (IntEx code) { + QCOMPARE(code.ex, 3); } // here, we should have received on non-throwing event and one throwing one QCOMPARE(obj.throwEventCount, 3); +#ifndef __SYMBIAN32__ + // symbian event loops will have absorbed the exceptions QCOMPARE(obj.noThrowEventCount, 1); +#endif // spin the event loop again qApp->processEvents(); |