summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp33
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian_p.h2
2 files changed, 30 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();
diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h
index 53f92a9..fd0350d 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian_p.h
+++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h
@@ -117,6 +117,7 @@ struct SymbianTimerInfo : public QSharedData
int timerId;
int interval;
+ int msLeft;
bool inTimerEvent;
QObject *receiver;
QTimerActiveObject *timerAO;
@@ -140,6 +141,7 @@ protected:
private:
void Run();
+ void StartTimer();
private:
SymbianTimerInfo *m_timerInfo;