From c1503316685438a312d9184f798e593fc6c8ce45 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Sat, 2 Dec 2006 20:53:42 +0200 Subject: [PATCH] Bug 868: check_timers: Don't keep pointers to other timers past timer->func. --- src/main/timer.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/timer.c b/src/main/timer.c index 6aa91220..1a362cd2 100644 --- a/src/main/timer.c +++ b/src/main/timer.c @@ -22,6 +22,8 @@ struct timer { void *data; }; +/* @timers.next points to the timer with the smallest interval, + * @timers.next->next to the second smallest, and so on. */ static INIT_LIST_HEAD(timers); int @@ -36,7 +38,7 @@ check_timers(timeval_T *last_time) { timeval_T now; timeval_T interval; - struct timer *timer, *next; + struct timer *timer; timeval_now(&now); timeval_sub(&interval, last_time, &now); @@ -45,11 +47,19 @@ check_timers(timeval_T *last_time) timeval_sub_interval(&timer->interval, &interval); } - foreachsafe (timer, next, timers) { + while (!list_empty(timers)) { + timer = timers.next; + if (timeval_is_positive(&timer->interval)) break; del_from_list(timer); + /* At this point, *@timer is to be considered invalid + * outside timers.c; if anything e.g. passes it to + * @kill_timer, that's a bug. However, @timer->func + * and @check_bottom_halves can still call @kill_timer + * on other timers, so this loop must be careful not to + * keep pointers to them. (bug 868) */ timer->func(timer->data); mem_free(timer); check_bottom_halves();