From 768852d010db37edeba88e7e8b2ef31d4908e862 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 24 Jan 2007 22:56:57 +0000 Subject: [PATCH] Modified version of Torbjoern's patch from bug #1640420 (fixes an overflow in the default timer manager) svn-id: r25165 --- backends/timer/default/default-timer.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/backends/timer/default/default-timer.cpp b/backends/timer/default/default-timer.cpp index 6688ce0a038..aa9d4c9fec9 100644 --- a/backends/timer/default/default-timer.cpp +++ b/backends/timer/default/default-timer.cpp @@ -29,8 +29,10 @@ struct TimerSlot { Common::TimerManager::TimerProc callback; void *refCon; - int32 interval; - int32 nextFireTime; + uint32 interval; // in microseconds + + uint32 nextFireTime; // in milliseconds + uint32 nextFireTimeMicro; // mircoseconds part of nextFire TimerSlot *next; }; @@ -39,7 +41,7 @@ void insertPrioQueue(TimerSlot *head, TimerSlot *newSlot) { // The head points to a fake anchor TimerSlot; this common // trick allows us to get rid of many special cases. - const int32 nextFireTime = newSlot->nextFireTime; + const uint32 nextFireTime = newSlot->nextFireTime; TimerSlot *slot = head; newSlot->next = 0; @@ -47,7 +49,7 @@ void insertPrioQueue(TimerSlot *head, TimerSlot *newSlot) { // timers in such a way that the list stays sorted... while (true) { assert(slot); - if (slot->next == 0 || slot->next->nextFireTime > nextFireTime) { + if (slot->next == 0 || nextFireTime < slot->next->nextFireTime) { newSlot->next = slot->next; slot->next = newSlot; return; @@ -80,7 +82,7 @@ DefaultTimerManager::~DefaultTimerManager() { void DefaultTimerManager::handler() { Common::StackLock lock(_mutex); - const int32 curTime = g_system->getMillis() * 1000; + const uint32 curTime = g_system->getMillis(); // Repeat as long as there is a TimerSlot that is scheduled to fire. TimerSlot *slot = _head->next; @@ -92,7 +94,12 @@ void DefaultTimerManager::handler() { // queue. Has to be done before the timer callback is invoked, in case // the callback wants to remove itself. assert(slot->interval > 0); - slot->nextFireTime += slot->interval; + slot->nextFireTime += (slot->interval / 1000); + slot->nextFireTimeMicro += (slot->interval % 1000); + if (slot->nextFireTimeMicro > 1000) { + slot->nextFireTime += slot->nextFireTimeMicro / 1000; + slot->nextFireTimeMicro %= 1000; + } insertPrioQueue(_head, slot); // Invoke the timer callback @@ -108,12 +115,12 @@ bool DefaultTimerManager::installTimerProc(TimerProc callback, int32 interval, v assert(interval > 0); Common::StackLock lock(_mutex); - TimerSlot *slot = new TimerSlot; slot->callback = callback; slot->refCon = refCon; slot->interval = interval; - slot->nextFireTime = g_system->getMillis() * 1000 + interval; + slot->nextFireTime = g_system->getMillis() + interval / 1000; + slot->nextFireTimeMicro = interval % 1000; slot->next = 0; insertPrioQueue(_head, slot);