From xemacs-m  Wed Dec 18 15:27:00 1996
Received: from UCSD.EDU (mailbox1.ucsd.edu [132.239.1.53])
          by xemacs.cs.uiuc.edu (8.8.4/8.8.4) with ESMTP
	  id PAA05727 for <xemacs-beta@xemacs.org>; Wed, 18 Dec 1996 15:26:59 -0600 (CST)
Received: from sdnp5.ucsd.edu (sdnp5.ucsd.edu [132.239.79.10]) by UCSD.EDU (8.8.3/8.6.9) with SMTP id NAA05234; Wed, 18 Dec 1996 13:26:20 -0800 (PST)
Received: by sdnp5.ucsd.edu (SMI-8.6/SMI-SVR4)
	id NAA17510; Wed, 18 Dec 1996 13:24:34 -0800
Sender: dmoore@sdnp5.ucsd.edu
To: XEmacs Beta Mailing List <xemacs-beta@xemacs.org>
Cc: Ben Wing <ben@666.com>, "Steven L. Baur" <steve@miranova.com>
Subject: Re: sit-for bug & patch
References: <199612181012.CAA26321@shellx.best.com>
X-Face: "oX;zS#-JU$-,WKSzG.1gGE]x^cIg!hW.dq>.f6pzS^A+(k!T|M:}5{_%>Io<>L&{hO7W4cicOQ|>/lZ1G(m%7iaCf,6Qgk0%%Bz7b2-W3jd0m_UG\Y;?]}4s0O-U)uox>P3JN)9cm]O\@,vy2e{`3pb!"pqmRy3peB90*2L
From: David Moore <dmoore@UCSD.EDU>
Date: 18 Dec 1996 13:24:31 -0800
In-Reply-To: Ben Wing's message of Wed, 18 Dec 1996 02:12:43 -0800 (PST)
Message-ID: <rv4thj7dgw.fsf@sdnp5.ucsd.edu>
Lines: 199
X-Mailer: Red Gnus v0.76/XEmacs 19.15

Ben Wing <ben@666.com> writes:

> You need to use record_unwind_protect() to decrement already_in_sit_for.
> In any case though your solution is not correct.  You need to write a
> function that scans pending_timeout_list for a specified id, and use it in
> place of this code:

	New version which uses Ben's approach to fix sit-for, sleep-for
and accept-process-output.  Patch against 19.15-b4.

*** event-stream.c.orig	Tue Dec 17 10:18:59 1996
--- event-stream.c	Wed Dec 18 13:07:17 1996
***************
*** 1196,1201 ****
--- 1196,1229 ----
      }
  }
  
+ int
+ event_stream_wakeup_pending_p (int id, int async_p)
+ {
+   struct timeout *timeout;
+   Lisp_Object rest = Qnil;
+   Lisp_Object timeout_list;
+   int found = 0;
+ 
+ 
+   if (async_p)
+     timeout_list = pending_async_timeout_list;
+   else
+     timeout_list = pending_timeout_list;
+ 
+   /* Find the element on the list of pending ones, if it's still there. */
+   LIST_LOOP (rest, timeout_list)
+     {
+       timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest));
+       if (timeout->id == id)
+ 	{
+ 	  found = 1;
+ 	  break;
+ 	}
+     }
+ 
+   return found;
+ }
+ 
  
  /**** Asynch. timeout functions (see also signal.c) ****/
  
***************
*** 2403,2408 ****
--- 2431,2443 ----
  	    and really need the processes to be handled. */
  	 || (!EQ (result, Qt) && event_stream_event_pending_p (0)))
      {
+       /* If our timeout has arrived, we move along. */
+       if (!event_stream_wakeup_pending_p (timeout_id, 0))
+ 	{
+ 	  timeout_enabled = 0;
+ 	  process = Qnil;	/* We're  done. */
+ 	}
+ 
        QUIT;	/* next_event_internal() does not QUIT, so check for ^G
  		   before reading output from the process - this makes it
  		   less likely that the filter will actually be aborted.
***************
*** 2429,2449 ****
  	    break;
  	  }
  	case timeout_event:
! 	  {
! 	    if (timeout_enabled &&
!                 XEVENT (event)->event.timeout.id_number == timeout_id)
! 	      {
!                 timeout_enabled = 0;
! 		process = Qnil; /* we're done */
! 	      }
! 	    else	/* a timeout that's not the one we're waiting for */
!               goto EXECUTE_INTERNAL;
! 	    break;
! 	  }
  	case pointer_motion_event:
  	case magic_event:
            {
-           EXECUTE_INTERNAL:
              execute_internal_event (event);
              break;
            }
--- 2464,2474 ----
  	    break;
  	  }
  	case timeout_event:
! 	  /* We execute the event even if it's ours, and notice that it's
! 	     happened above. */
  	case pointer_motion_event:
  	case magic_event:
            {
              execute_internal_event (event);
              break;
            }
***************
*** 2484,2489 ****
--- 2509,2518 ----
    event = Fmake_event ();
    while (1)
      {
+       /* If our timeout has arrived, we move along. */
+       if (!event_stream_wakeup_pending_p (id, 0))
+ 	goto DONE_LABEL;
+ 
        QUIT;	/* next_event_internal() does not QUIT, so check for ^G
  		   before reading output from the process - this makes it
  		   less likely that the filter will actually be aborted.
***************
*** 2497,2508 ****
        switch (XEVENT_TYPE (event))
  	{
  	case timeout_event:
! 	  {
! 	    if (XEVENT (event)->event.timeout.id_number == id)
! 	      goto DONE_LABEL;
!             else
!               goto EXECUTE_INTERNAL;
! 	  }
  	case pointer_motion_event:
  	case process_event:
  	case magic_event:
--- 2526,2533 ----
        switch (XEVENT_TYPE (event))
  	{
  	case timeout_event:
! 	  /* We execute the event even if it's ours, and notice that it's
! 	     happened above. */
  	case pointer_motion_event:
  	case process_event:
  	case magic_event:
***************
*** 2587,2594 ****
  	  redisplay ();
  	}
  
!       /* If we're no longer waiting for a timeout, bug out. */
!       if (! id)
  	{
  	  result = Qt;
  	  goto DONE_LABEL;
--- 2612,2619 ----
  	  redisplay ();
  	}
  
!       /* If our timeout has arrived, we move along. */
!       if (!event_stream_wakeup_pending_p (id, 0))
  	{
  	  result = Qt;
  	  goto DONE_LABEL;
***************
*** 2619,2633 ****
  	    break;
  	  }
  	case timeout_event:
! 	  {
! 	    if (XEVENT (event)->event.timeout.id_number != id)
! 	      /* a timeout that wasn't the one we're waiting for */
! 	      goto EXECUTE_INTERNAL;
! 	    id = 0;	/* assert that we are no longer waiting for it. */
! 	    result = Qt;
! 	    goto DONE_LABEL;
! 	  }
!       default:
  	  {
  	  EXECUTE_INTERNAL:
  	    execute_internal_event (event);
--- 2644,2652 ----
  	    break;
  	  }
  	case timeout_event:
! 	  /* We execute the event even if it's ours, and notice that it's
! 	     happened above. */
! 	default:
  	  {
  	  EXECUTE_INTERNAL:
  	    execute_internal_event (event);
***************
*** 2638,2644 ****
  
   DONE_LABEL:
    /* If our timeout has not been signalled yet, disable it. */
!   if (id)
      event_stream_disable_wakeup (id, 0);
  
    /* Put back the event (if any) that made Fsit_for() exit before the
--- 2657,2663 ----
  
   DONE_LABEL:
    /* If our timeout has not been signalled yet, disable it. */
!   if (NILP (result))
      event_stream_disable_wakeup (id, 0);
  
    /* Put back the event (if any) that made Fsit_for() exit before the

