(start_atimer): Don't abort when timers are stopped.
authorGerd Moellmann <gerd@gnu.org>
Tue, 29 Feb 2000 13:50:23 +0000 (13:50 +0000)
committerGerd Moellmann <gerd@gnu.org>
Tue, 29 Feb 2000 13:50:23 +0000 (13:50 +0000)
(append_atimer_lists): New function.
(cancel_atimer, stop_other_atimers, run_all_atimers): Handle
arbitrary lists of stopped and running atimers.

src/ChangeLog
src/atimer.c

index 8146d49..6bc8abc 100644 (file)
@@ -1,5 +1,10 @@
 2000-02-29  Gerd Moellmann  <gerd@gnu.org>
 
+       * 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.
 
index 82f4180..eafe0f5 100644 (file)
@@ -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;
     }
 }