Fixed bug in timer when the list of timers changed.
Fix contributed by Michael Bicha
This commit is contained in:
parent
c4bf458e47
commit
dcd48df016
1 changed files with 53 additions and 42 deletions
|
@ -113,56 +113,67 @@ SDL_ThreadedTimerCheck(void)
|
||||||
SDL_bool removed;
|
SDL_bool removed;
|
||||||
|
|
||||||
SDL_mutexP(SDL_timer_mutex);
|
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;
|
|
||||||
|
|
||||||
if ((now - t->last_alarm) < t->interval) {
|
now = SDL_GetTicks();
|
||||||
t->last_alarm += t->interval;
|
do {
|
||||||
} else {
|
list_changed = SDL_FALSE;
|
||||||
t->last_alarm = now;
|
for (prev = NULL, t = SDL_timers; t; t = next) {
|
||||||
}
|
removed = SDL_FALSE;
|
||||||
#ifdef DEBUG_TIMERS
|
ms = t->interval - SDL_TIMESLICE;
|
||||||
printf("Executing timer %p (thread = %lu)\n", t, SDL_ThreadID());
|
next = t->next;
|
||||||
#endif
|
if ((int) (now - t->last_alarm) > (int) ms) {
|
||||||
timer = *t;
|
struct _SDL_TimerID timer;
|
||||||
SDL_mutexV(SDL_timer_mutex);
|
|
||||||
ms = timer.cb(timer.interval, timer.param);
|
if ((now - t->last_alarm) < t->interval) {
|
||||||
SDL_mutexP(SDL_timer_mutex);
|
t->last_alarm += t->interval;
|
||||||
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);
|
|
||||||
} else {
|
} else {
|
||||||
/* Remove timer from the list */
|
t->last_alarm = now;
|
||||||
|
}
|
||||||
#ifdef DEBUG_TIMERS
|
#ifdef DEBUG_TIMERS
|
||||||
printf("SDL: Removing timer %p\n", t);
|
printf("Executing timer %p (thread = %lu)\n",
|
||||||
|
t, SDL_ThreadID());
|
||||||
#endif
|
#endif
|
||||||
if (prev) {
|
timer = *t;
|
||||||
prev->next = next;
|
SDL_mutexV(SDL_timer_mutex);
|
||||||
} else {
|
ms = timer.cb(timer.interval, timer.param);
|
||||||
SDL_timers = next;
|
SDL_mutexP(SDL_timer_mutex);
|
||||||
|
if (list_changed) {
|
||||||
|
next = t->next;
|
||||||
|
for (prev = SDL_timers; prev; prev = prev->next) {
|
||||||
|
if (prev->next == t)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
SDL_free(t);
|
}
|
||||||
--SDL_timer_running;
|
if (ms != t->interval) {
|
||||||
removed = SDL_TRUE;
|
if (ms) {
|
||||||
|
t->interval = ROUND_RESOLUTION(ms);
|
||||||
|
} else {
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 */
|
} while (list_changed);
|
||||||
if (!removed) {
|
|
||||||
prev = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SDL_mutexV(SDL_timer_mutex);
|
SDL_mutexV(SDL_timer_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue