[6248] in Athena Bugs

home help back first fref pref prev next nref lref last post

emacs process false close (all machines, 18.54 and up)

daemon@ATHENA.MIT.EDU (Mark W. Eichin)
Fri Oct 19 23:12:00 1990

Date: Fri, 19 Oct 90 23:11:41 -0400
From: Mark W. Eichin <eichin@ATHENA.MIT.EDU>
To: bugs@ATHENA.MIT.EDU

BACKGROUND:
In process.c, wait_reading_process_input is structured
  while (1) {
    select(32,&Available,0,&Exception,&timeout);
    for(channel = 3; Available && channel < 32; channel++) 
      {
        m = ChannelMask(channel);
        if (m & Available) {
           Available &= ~m;
           if(read_process_output(proc[channel], channel) > 0)
               /* got some data, deal with it */
               do display;
           else
               /* select woke up, but read didn't get data, so 
                  the connection must have closed on us... */
              deactivate_process(proc);
         }
      }
   }

read_process_output is essentially
   nchars = read(channel, chars, 1024);
   if(nchars <=0) return 0;
   call2(proc->filter, proc, make_string(chars));

THE PROBLEM:
 read_process_output can call wait_reading_process_input recursively.

THE SCENARIO:
 Two channels provide output "simultaneously". The one with the lower channel
number has a "filter" which does an (accept-process-output), which calls
wait_reading_process_input. wait_reading_process_input does another select,
and sees the input for the higher channel, and calls read_process_output on
it.
 Eventually, wait_reading_process_input and (accept-process-output) return,
so the proc->filter finishes. Then the wait_reading_process_input loop
continues, sees the higher bit in Available still set, so calls
read_process_output again. This time, there isn't any output, so read gets an
EWOULDBLOCK and returns, causing wait_reading_process_input to *incorrectly*
deactivate the process.

THE FIX:
 A surprisingly simple fix is to make Available static, so that the recursive
call to wait_reading_process_input changes it... after all, the channels are
global, the mask representing them should be too.

WHY I CARE:
 Doing a reply in emacs discuss mode will sometimes deactivate the process
for emacs zwgc mode (of course, zwgc itself doesn't die...)

					_Mark_ <eichin@athena.mit.edu>
					MIT SIPB

ps. Please forward to whatever the new emacs bug list is, hopefully this can
get included in 18.5[67]. The line numbers for the patch below is for 18.54,
but the line numbers are only slightly different for 18.55.

% diff -c process.c /mit/emacs/src/process.c
*** process.c   Fri Oct 19 22:36:16 1990
--- /mit/emacs/src/process.c    Fri May 26 22:11:19 1989
***************
*** 1274,1281 ****
       int time_limit, read_kbd, do_display;
  {
    register int channel, nfds, m;
!   static int Available = 0;
!   static int Exception;
    int xerrno;
    Lisp_Object proc;
  #ifdef HAVE_TIMEVAL
--- 1274,1281 ----
       int time_limit, read_kbd, do_display;
  {
    register int channel, nfds, m;
!   int Available = 0;
!   int Exception;
    int xerrno;
    Lisp_Object proc;
  #ifdef HAVE_TIMEVAL

home help back first fref pref prev next nref lref last post