[6248] in Athena Bugs
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