# HG changeset patch # User Gerd Moellmann # Date 950361193 0 # Node ID cf2edc15eaa9a07cd16e5b0a1e7d9288a3bcc700 # Parent 5fddc840c29cd262a9e3ca43d8ecfa3628744476 (stopped_atimers): New variable. (stop_other_atimers, run_all_atimers, unwind_stop_other_atimers): New functions. diff -r 5fddc840c29c -r cf2edc15eaa9 src/atimer.c --- a/src/atimer.c Sat Feb 12 13:12:17 2000 +0000 +++ b/src/atimer.c Sat Feb 12 13:13:13 2000 +0000 @@ -44,6 +44,11 @@ static struct atimer *free_atimers; +/* List of currently not running timers due to a call to + lock_atimer. */ + +static struct atimer *stopped_atimers; + /* List of active atimers, sorted by expiration time. The timer that will become ripe next is always at the front of this list. */ @@ -95,6 +100,10 @@ { 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 @@ -161,6 +170,10 @@ { struct atimer *t, *prev; + /* May not be called when some timers are stopped. */ + if (stopped_atimers) + abort (); + BLOCK_ATIMERS; /* See if TIMER is active. */ @@ -185,12 +198,70 @@ } +/* 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. */ + +void +stop_other_atimers (t) + struct atimer *t; +{ + BLOCK_ATIMERS; + + if (stopped_atimers) + abort (); + + if (t) + { + cancel_atimer (t); + if (free_atimers != t) + abort (); + free_atimers = free_atimers->next; + t->next = NULL; + } + + stopped_atimers = atimers; + atimers = t; + UNBLOCK_ATIMERS; +} + + +/* Run all timers again, if some have been stopped with a call to + stop_other_atimers. */ + +void +run_all_atimers () +{ + if (stopped_atimers) + { + struct atimer *t = atimers; + BLOCK_ATIMERS; + atimers = stopped_atimers; + stopped_atimers = NULL; + if (t) + schedule_atimer (t); + UNBLOCK_ATIMERS; + } +} + + +/* A version of run_all_timers suitable for a record_unwind_protect. */ + +Lisp_Object +unwind_stop_other_atimers (dummy) + Lisp_Object dummy; +{ + run_all_atimers (); + return Qnil; +} + + /* Arrange for a SIGALRM to arrive when the next timer is ripe. */ static void set_alarm () { - #if defined (USG) && !defined (POSIX_SIGNALS) /* USG systems forget handlers when they are used; must reestablish each time. */