summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qeventdispatcher_symbian.cpp
diff options
context:
space:
mode:
authorShane Kearns <shane.kearns@sosco.com>2009-09-16 13:48:59 (GMT)
committerShane Kearns <shane.kearns@sosco.com>2009-09-16 13:48:59 (GMT)
commit504dd08854a8f6519a0529014df2233938b82728 (patch)
treec96594b5b69bcd10d61b97fd9838505208eb7610 /src/corelib/kernel/qeventdispatcher_symbian.cpp
parent314e5680c8276d539b596927874036a873966d8f (diff)
downloadQt-504dd08854a8f6519a0529014df2233938b82728.zip
Qt-504dd08854a8f6519a0529014df2233938b82728.tar.gz
Qt-504dd08854a8f6519a0529014df2233938b82728.tar.bz2
Fix QTimer overflow with interval > 35 minutes on symbian
For long intervals, restart the system timer every 2000 seconds New autotest to verify long timers don't crash or complete immediately Task-number: QT-651 Reviewed-by: axis
Diffstat (limited to 'src/corelib/kernel/qeventdispatcher_symbian.cpp')
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index b1c8734..11a0da6 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -231,15 +231,39 @@ void QTimerActiveObject::RunL()
}
}
+#define MAX_SYMBIAN_TIMEOUT_MS 2000000
+void QTimerActiveObject::StartTimer()
+{
+ if (m_timerInfo->msLeft > MAX_SYMBIAN_TIMEOUT_MS) {
+ //There is loss of accuracy anyway due to needing to restart the timer every 33 minutes,
+ //so the 1/64s res of After() is acceptable for these very long timers.
+ m_rTimer.After(iStatus, MAX_SYMBIAN_TIMEOUT_MS * 1000);
+ m_timerInfo->msLeft -= MAX_SYMBIAN_TIMEOUT_MS;
+ } else {
+ //HighRes gives the 1ms accuracy expected by Qt, the +1 is to ensure that
+ //"Timers will never time out earlier than the specified timeout value"
+ //condition is always met.
+ m_rTimer.HighRes(iStatus, (m_timerInfo->msLeft + 1) * 1000);
+ m_timerInfo->msLeft = 0;
+ }
+ SetActive();
+}
+
void QTimerActiveObject::Run()
{
+ //restart timer immediately, if the timeout has been split because it overflows max for platform.
+ if (m_timerInfo->msLeft > 0) {
+ StartTimer();
+ return;
+ }
+
if (!okToRun())
return;
if (m_timerInfo->interval > 0) {
// Start a new timer immediately so that we don't lose time.
- SetActive();
- m_rTimer.After(iStatus, m_timerInfo->interval*1000);
+ m_timerInfo->msLeft = m_timerInfo->interval;
+ StartTimer();
m_timerInfo->dispatcher->timerFired(m_timerInfo->timerId);
} else {
@@ -261,11 +285,10 @@ void QTimerActiveObject::Run()
void QTimerActiveObject::Start()
{
CActiveScheduler::Add(this);
+ m_timerInfo->msLeft = m_timerInfo->interval;
if (m_timerInfo->interval > 0) {
m_rTimer.CreateLocal();
- iStatus = KRequestPending;
- SetActive();
- m_rTimer.After(iStatus, m_timerInfo->interval*1000);
+ StartTimer();
} else {
iStatus = KRequestPending;
SetActive();