# HG changeset patch # User Gerd Moellmann # Date 951832142 0 # Node ID 81d5641c8b048af3c2cc67faac97c7f85cd48b3e # Parent ed26ed5b0afc3bdd2d4be971ab8f36a6a87bfc62 (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. diff -r ed26ed5b0afc -r 81d5641c8b04 src/atimer.c --- a/src/atimer.c Tue Feb 29 11:32:52 2000 +0000 +++ b/src/atimer.c Tue Feb 29 13:49:02 2000 +0000 @@ -71,6 +71,8 @@ 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 @@ { 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 @@ 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) + for (i = 0; i < 2; ++i) { - timer->next = free_atimers; - free_atimers = timer; - atimers = NULL; - } - else - { + 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 @@ } -/* 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 @@ { BLOCK_ATIMERS; - if (stopped_atimers) - abort (); - if (t) { struct atimer *p, *prev; @@ -242,7 +250,7 @@ t = NULL; } - stopped_atimers = atimers; + stopped_atimers = append_atimer_lists (atimers, stopped_atimers); atimers = t; UNBLOCK_ATIMERS; } @@ -257,11 +265,19 @@ 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; } }