[comp.emacs] ACCEPT-PROCESS-OUTPUT problem

ram-ashwin@YALE.ARPA (Ashwin Ram) (11/24/87)

I'm trying to use start-process, process filters and accept-process-output in
the following way:

1. Start-process some process foo.

2. Set its process-filter to foo-filter.
   One of the things the filter does is to check if a termination condition
   has been reached (say, foo has produced some predetermined output, or a
   predetermined amount of output, etc.  E.g., in ispell, check to see if
   there is output corresponding to the last word in the buffer being
   checked.  In gnews, check to see if a "." has been receieved all by itself
   on a line.)  If the termination condition is reached, setq foo-done to t.

       ...
       (if ...
           (setq foo-done t))
       ...

3. Now I do the following (I want to wait until foo has produced all its
   output before going on):

        (while (not foo-done)
           (accept-process-output foo))

Here's the problem I run into:  Suppose foo-done is nil to start with.  It
does a accept-process-output.  Suppose foo produces the desired final output.
The accept-process-output returns, and so we go around the while.  But
foo-filter is still processing the last piece of output, and foo-done hasn't
been setq'd to t by the time the while checks (not foo-done), so it goes
around into the accept-process-output again.  Now it hangs forever since foo
has already produced its last piece of output.  By this time foo-done is t,
but it's too late.

This bug is hard to reproduce since it depends on timing.  It depends on how
fast you go around the while vs. how fast the filter executes (often, it
depends on the length of the output that the filter is processing, since that
determines how soon it can setq foo-done to t.

Does anyone know what I'm talking about, and what the best way to get around
this is?  I tried putting a (sit-for 0) after the accept-process-output; this
usually works (but is a little annoying).  I can put a (sit-for 2) or
something, but this is even more annoying.  Perhaps a function that won't
return until the accept-process-output is done *and* the filter has processed
the output?

Thanks in advance.  In case it's relevant, I'm running GNU Emacs 18.48 on an
Apollo DN3000 running DOMAIN/IX (Aegis SR9.5 + Unix BSD 4.2).

-- Ashwin Ram --

ARPA:    Ram-Ashwin@cs.yale.edu
UUCP:    {decvax,linus,seismo}!yale!Ram-Ashwin
BITNET:  Ram@yalecs

drw@culdev1.UUCP (Dale Worley) (11/30/87)

I'm not sure, but in Gnu Emacs, I suspect that subprocess output
filtering is done only when Emacs is waiting for keyboard input, or
when the code executes accept-process-output, and that all queued
output is processed before any more keyboard input is processed, or
before accept-process-output returns.  That is, I don't think
filtering is done concurrently with execution of any other code.

If I am right, the problems discussed in the original article never
happen.

Does anyone know for sure?

Dale

-- 
Dale Worley    Cullinet Software      ARPA: culdev1!drw@eddie.mit.edu
UUCP: ...!seismo!harvard!mit-eddie!culdev1!drw
If you get fed twice a day, how bad can life be?

markl@PTT.LCS.MIT.EDU (12/01/87)

In-Reply-To: drw@culdev1.UUCP's message of 30 Nov 87 19:20:01 GMT

Repository: PTT

Originating-Client: thyme



   From: drw@culdev1.UUCP (Dale Worley)
   Date: 30 Nov 87 19:20:01 GMT

   I'm not sure, but in Gnu Emacs, I suspect that subprocess output
   filtering is done only when Emacs is waiting for keyboard input, or
   when the code executes accept-process-output, and that all queued
   output is processed before any more keyboard input is processed, or
   before accept-process-output returns.  That is, I don't think
   filtering is done concurrently with execution of any other code.

All emacs subprocess output is polled-style using
accept-process-output.  I believe you are also correct in saying that
all output is processed before accept-process-output returns.  It is a
fairly simple interface, once you get past the ifdefs...

markl

Internet: markl@ptt.lcs.mit.edu

Mark L. Lambert
MIT Laboratory for Computer Science
Distributed Systems Group

----------

jr@LF-SERVER-2.BBN.COM (John Robinson) (12/01/87)

> If I am right, the problems discussed in the original article never
> happen.
> 
> Does anyone know for sure?

I reached a similar conclusion for Gnu Emacs.  Moreover, I have found
that the following is a reasonable synchronization workaround:

  (if latch
      (progn
	(message "Awaiting latch...")
	(sit-for 0)
	(while latch
	   (sleep-for 1))
	(message "Awaiting latch...done")))

The (sleep-for) allows other sentinels to do their work without
monopolizing the CPU (I tested this using the display-time sentinel
for the modeline).  (sleep-for) apparently has the effect of a
(accept-process-output), which seems reasonable.  Warning: I don't
know how this might work on non-bsd systems; this was checked under
SunOS 3.2 (4.2bsd).

/jr
jr@bbn.com or jr@bbn.uucp