(alarm_signal_handler): Add forward declaration.
[bpt/emacs.git] / src / atimer.c
index 279c5f9..54a038f 100644 (file)
@@ -71,6 +71,9 @@ 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 *));
+SIGTYPE alarm_signal_handler ();
 
 
 /* Start a new atimer of type TYPE.  TIME specifies when the timer is
@@ -100,10 +103,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,40 +167,63 @@ void
 cancel_atimer (timer)
      struct atimer *timer;
 {
-  struct atimer *t, *prev;
-
-  /* May not be called when some timers are stopped.  */
-  if (stopped_atimers)
-    abort ();
-
+  int i;
+  
   BLOCK_ATIMERS;
 
-  /* See if TIMER is active.  */
-  for (t = atimers, prev = 0; t && t != timer; t = t->next)
-    ;
-
-  /* If it is, take it off the list of active timers, 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)
+  for (i = 0; i < 2; ++i)
     {
-      if (prev)
-       prev->next = t->next;
-      else
-       atimers = t->next;
+      struct atimer *t, *prev;
+      struct atimer **list = i ? &stopped_atimers : &atimers;
+      
+      /* See if TIMER is active or stopped.  */
+      for (t = *list, prev = NULL; t && t != timer; prev = t, t = t->next)
+       ;
 
-      t->next = free_atimers;
-      free_atimers = t;
+      /* 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)
+       {
+         if (prev)
+           prev->next = t->next;
+         else
+           *list = t->next;
+         
+         t->next = free_atimers;
+         free_atimers = t;
+         break;
+       }
     }
 
   UNBLOCK_ATIMERS;
 }
 
 
-/* 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)
@@ -209,9 +231,6 @@ stop_other_atimers (t)
 {
   BLOCK_ATIMERS;
   
-  if (stopped_atimers)
-    abort ();
-
   if (t)
     {
       struct atimer *p, *prev;
@@ -233,7 +252,7 @@ stop_other_atimers (t)
        t = NULL;
     }
   
-  stopped_atimers = atimers;
+  stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
   atimers = t;
   UNBLOCK_ATIMERS;
 }
@@ -248,11 +267,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;
     }
 }