aboutsummaryrefslogtreecommitdiff
path: root/backends/timer
diff options
context:
space:
mode:
authorMax Horn2007-01-24 22:56:57 +0000
committerMax Horn2007-01-24 22:56:57 +0000
commit768852d010db37edeba88e7e8b2ef31d4908e862 (patch)
tree42fa18fdf632e40fe4b43ecd8d5cd67115f93646 /backends/timer
parent318210ad962ec294b5d74f8f1d81a9e845e2696f (diff)
downloadscummvm-rg350-768852d010db37edeba88e7e8b2ef31d4908e862.tar.gz
scummvm-rg350-768852d010db37edeba88e7e8b2ef31d4908e862.tar.bz2
scummvm-rg350-768852d010db37edeba88e7e8b2ef31d4908e862.zip
Modified version of Torbjoern's patch from bug #1640420 (fixes an overflow in the default timer manager)
svn-id: r25165
Diffstat (limited to 'backends/timer')
-rw-r--r--backends/timer/default/default-timer.cpp23
1 files changed, 15 insertions, 8 deletions
diff --git a/backends/timer/default/default-timer.cpp b/backends/timer/default/default-timer.cpp
index 6688ce0a03..aa9d4c9fec 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);