Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Fixed bug in timer when the list of timers changed.

Fix contributed by Michael Bicha
  • Loading branch information
slouken committed Jan 22, 2011
1 parent 48df290 commit 09caf239c9f4c5cc3d236b027a374302eb1a4d7b
Showing with 51 additions and 40 deletions.
  1. +51 −40 src/timer/SDL_timer.c
@@ -113,56 +113,67 @@ SDL_ThreadedTimerCheck(void)
SDL_bool removed;

SDL_mutexP(SDL_timer_mutex);
list_changed = SDL_FALSE;

now = SDL_GetTicks();
for (prev = NULL, t = SDL_timers; t; t = next) {
removed = SDL_FALSE;
ms = t->interval - SDL_TIMESLICE;
next = t->next;
if ((int) (now - t->last_alarm) > (int) ms) {
struct _SDL_TimerID timer;
do {
list_changed = SDL_FALSE;
for (prev = NULL, t = SDL_timers; t; t = next) {
removed = SDL_FALSE;
ms = t->interval - SDL_TIMESLICE;
next = t->next;
if ((int) (now - t->last_alarm) > (int) ms) {
struct _SDL_TimerID timer;

if ((now - t->last_alarm) < t->interval) {
t->last_alarm += t->interval;
} else {
t->last_alarm = now;
}
#ifdef DEBUG_TIMERS
printf("Executing timer %p (thread = %lu)\n", t, SDL_ThreadID());
#endif
timer = *t;
SDL_mutexV(SDL_timer_mutex);
ms = timer.cb(timer.interval, timer.param);
SDL_mutexP(SDL_timer_mutex);
if (list_changed) {
/* Abort, list of timers modified */
/* FIXME: what if ms was changed? */
break;
}
if (ms != t->interval) {
if (ms) {
t->interval = ROUND_RESOLUTION(ms);
if ((now - t->last_alarm) < t->interval) {
t->last_alarm += t->interval;
} else {
/* Remove timer from the list */
t->last_alarm = now;
}
#ifdef DEBUG_TIMERS
printf("SDL: Removing timer %p\n", t);
printf("Executing timer %p (thread = %lu)\n",
t, SDL_ThreadID());
#endif
if (prev) {
prev->next = next;
timer = *t;
SDL_mutexV(SDL_timer_mutex);
ms = timer.cb(timer.interval, timer.param);
SDL_mutexP(SDL_timer_mutex);
if (list_changed) {
next = t->next;
for (prev = SDL_timers; prev; prev = prev->next) {
if (prev->next == t)
break;
}
}
if (ms != t->interval) {
if (ms) {
t->interval = ROUND_RESOLUTION(ms);
} else {
SDL_timers = next;
/* Remove timer from the list */
#ifdef DEBUG_TIMERS
printf("SDL: Removing timer %p\n", t);
#endif
if (prev) {
prev->next = next;
} else {
SDL_timers = next;
}
SDL_free(t);
--SDL_timer_running;
removed = SDL_TRUE;
}
SDL_free(t);
--SDL_timer_running;
removed = SDL_TRUE;
}
if (list_changed) {
/* Abort, list of timers modified */
break;
}
}
/* Don't update prev if the timer has disappeared */
if (!removed) {
prev = t;
}
}
/* Don't update prev if the timer has disappeared */
if (!removed) {
prev = t;
}
}
} while (list_changed);

SDL_mutexV(SDL_timer_mutex);
}

0 comments on commit 09caf23

Please sign in to comment.