(waiting_for_input): Remove unnecessary prototype.
[bpt/emacs.git] / src / atimer.c
index 9dc4f50..492aa4e 100644 (file)
@@ -35,11 +35,6 @@ Boston, MA 02111-1307, USA.  */
 #include <sys/time.h>
 #endif
 
-/* The ubiquitous min/max macros.  */
-
-#define max(X, Y) ((X) > (Y) ? (X) : (Y))
-#define min(X, Y) ((X) < (Y) ? (X) : (Y))
-
 /* Free-list of atimer structures.  */
 
 static struct atimer *free_atimers;
@@ -62,7 +57,7 @@ static struct atimer *atimers;
 
 int pending_atimers;
 
-/* Block/unblock SIGALRM.. */
+/* Block/unblock SIGALRM.  */
 
 #define BLOCK_ATIMERS   sigblock (sigmask (SIGALRM))
 #define UNBLOCK_ATIMERS sigunblock (sigmask (SIGALRM))
@@ -71,6 +66,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 +98,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 +162,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,19 +226,28 @@ stop_other_atimers (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;
+      struct atimer *p, *prev;
+      
+      /* See if T is active.  */
+      for (p = atimers, prev = 0; p && p != t; p = p->next)
+       ;
+
+      if (p == t)
+       {
+         if (prev)
+           prev->next = t->next;
+         else
+           atimers = t->next;
+         t->next = NULL;
+       }
+      else
+       /* T is not active.  Let's handle this like T == 0.  */
+       t = NULL;
     }
   
-  stopped_atimers = atimers;
+  stopped_atimers = append_atimer_lists (atimers, stopped_atimers);
   atimers = t;
   UNBLOCK_ATIMERS;
 }
@@ -236,11 +262,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;
     }
 }
@@ -357,12 +391,6 @@ alarm_signal_handler (signo)
       EMACS_GET_TIME (now);
     }
   
-#if defined (USG) && !defined (POSIX_SIGNALS)
-  /* USG systems forget handlers when they are used;
-     must reestablish each time.  */
-  signal (SIGALRM, alarm_signal_handler);
-#endif /* USG */
-  
   set_alarm ();
 }