Subject: Re: bug#33839: 26.1.90; Emacs occasionally fails to receive asynchronous subprocess output in batch mode

From: Philipp Stephani <[email-masked]>
Date: Tue, 25 Dec 2018 17:41:17 +0100

Am So., 23. Dez. 2018 um 17:54 Uhr schrieb Eli Zaretskii <[email-masked]>:
>
> > From: Philipp Stephani <[email-masked]>
> > Date: Sun, 23 Dec 2018 17:45:31 +0100
> > Cc: [email-masked]
> >
> > Am So., 23. Dez. 2018 um 16:22 Uhr schrieb Eli Zaretskii <[email-masked]>:
> > >
> > > > From: Philipp <[email-masked]>
> > > > Date: Sun, 23 Dec 2018 03:28:53 +0100
> > > >
> > > > (with-temp-buffer
> > > >   (let ((proc (make-process :name "test"
> > > >                             :command '("bash" "-c" "echo stdout; echo stderr >&2")
> > > >                             :buffer (current-buffer)
> > > >                             :connection-type 'pipe
> > > >                             :sentinel #'ignore
> > > >                             :noquery t
> > > >                             :coding '(utf-8-unix . utf-8-unix))))
> > > >     (when (process-live-p proc)
> > > >       (process-send-eof proc))
> > > >     (while (process-live-p proc)
> > > >       (accept-process-output proc))
> > > >     (cl-assert (equal (buffer-string) "stdout\nstderr\n") :show-args)))
> > > >
> > > > Then evaluate this form repeatedly.  Occasionally the buffer is empty
> > > > and the assertion triggers.
> > >
> > > Isn't there an inherent race condition here?
> >
> > Maybe? If so, then it should be documented, with an explanation how to
> > write this in a race-free manner.
>
> Can you tell why you used the process-live-p condition for calling
> accept-process-output?

Because it seemed logical to do so: while the process is running, wait
for process output. I don't think the manual states that output can
arrive after the process has finished, but if that's the case, then it
should do so.

> What happens if you do that unconditionally?

You mean, without a while loop? It works in this specific case, but
doesn't work in other cases, e.g. when a timer runs while the process
is still running.
To make this work reliably, a loop is required because there's no
guarantee that accept-process-output returns only when the process has
finished.