From 50b1039fa7de644b62a1ebe38929bf16ec8e3b93 Mon Sep 17 00:00:00 2001 From: Gerd Moellmann Date: Tue, 29 Feb 2000 13:50:23 +0000 Subject: [PATCH] (start_atimer): Don't abort when timers are stopped. (append_atimer_lists): New function. (cancel_atimer, stop_other_atimers, run_all_atimers): Handle arbitrary lists of stopped and running atimers. --- src/ChangeLog | 5 ++++ src/atimer.c | 72 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 8146d49b2b..6bc8abc3a4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,10 @@ 2000-02-29 Gerd Moellmann + * atimer.c (start_atimer): Don't abort when timers are stopped. + (append_atimer_lists): New function. + (cancel_atimer, stop_other_atimers, run_all_atimers): Handle + arbitrary lists of stopped and running atimers. + * atimer.c (cancel_atimer): Handle canceling an atimer when some timers are stopped. diff --git a/src/atimer.c b/src/atimer.c index 82f4180088..eafe0f5ebf 100644 --- a/src/atimer.c +++ b/src/atimer.c @@ -71,6 +71,8 @@ int pending_atimers; static void set_alarm P_ ((void)); static void schedule_atimer P_ ((struct atimer *)); +static struct atimer *append_atimer_lists P_ ((struct atimer *, + struct atimer *)); /* Start a new atimer of type TYPE. TIME specifies when the timer is @@ -100,10 +102,6 @@ start_atimer (type, time, fn, client_data) { struct atimer *t; - /* May not be called when some timers are stopped. */ - if (stopped_atimers) - abort (); - /* Round TIME up to the next full second if we don't have itimers. */ #ifndef HAVE_SETITIMER @@ -168,27 +166,20 @@ void cancel_atimer (timer) struct atimer *timer; { - struct atimer *t, *prev; - struct atimer **list; - + int i; + BLOCK_ATIMERS; - /* If we've stopped all other timers except TIMER, we can - just reset the list of active atimers to null. */ - if (stopped_atimers && timer == atimers) - { - timer->next = free_atimers; - free_atimers = timer; - atimers = NULL; - } - else + for (i = 0; i < 2; ++i) { + struct atimer *t, *prev; + struct atimer **list = i ? &stopped_atimers : &atimers; + /* See if TIMER is active or stopped. */ - list = stopped_atimers ? &stopped_atimers : &atimers; for (t = *list, prev = 0; t && t != timer; t = t->next) ; - /* If it is, take it off the list of its list, and put in on the + /* If it is, take it off the its list, and put in on the free-list. We don't bother to arrange for setting a different alarm time, since a too early one doesn't hurt. */ if (t) @@ -207,10 +198,30 @@ cancel_atimer (timer) } -/* Stop all timers except timer T. T null means stop all timers. - This function may only be called when all timers are running. Two - calls of this function in a row will lead to an abort. You may not - call cancel_atimer or start_atimer while timers are stopped. */ +/* Append two lists of atimers LIST1 and LIST2 and return the + result list. */ + +static struct atimer * +append_atimer_lists (list1, list2) + struct atimer *list1, *list2; +{ + if (list1 == NULL) + return list2; + else if (list2 == NULL) + return list1; + else + { + struct atimer *p; + + for (p = list1; p->next; p = p->next) + ; + p->next = list2; + return list1; + } +} + + +/* Stop all timers except timer T. T null means stop all timers. */ void stop_other_atimers (t) @@ -218,9 +229,6 @@ stop_other_atimers (t) { BLOCK_ATIMERS; - if (stopped_atimers) - abort (); - if (t) { struct atimer *p, *prev; @@ -242,7 +250,7 @@ stop_other_atimers (t) t = NULL; } - stopped_atimers = atimers; + stopped_atimers = append_atimer_lists (atimers, stopped_atimers); atimers = t; UNBLOCK_ATIMERS; } @@ -257,11 +265,19 @@ run_all_atimers () if (stopped_atimers) { struct atimer *t = atimers; + struct atimer *next; + BLOCK_ATIMERS; atimers = stopped_atimers; stopped_atimers = NULL; - if (t) - schedule_atimer (t); + + while (t) + { + next = t->next; + schedule_atimer (t); + t = next; + } + UNBLOCK_ATIMERS; } } -- 2.20.1