Subject: bug#50166: 28.0.50; ECM for possible process-status/sentinel bug

From: Adam Porter <[email-masked]>
Date: Sun, 22 Aug 2021 15:08:01 -0500

[As originally posted at
https://lists.gnu.org/archive/html/emacs-devel/2021-08/msg00654.html]

Hi,

The attached file provides an ECM for a possible bug in Emacs's process
handling.  The rub is whether a process sentinel may be called with a
STATUS string of "finished\n" while the process's `process-status' is
`open': If that is expected, then this may not indicate a bug (but
perhaps an issue that needs to be more prominently documented).  But if
it's not supposed to happen, then this may provide a means to reproduce
the behavior and troubleshoot the bug.

This ECM works by making 10 (by default) curl `pipe' processes that send
requests to httpbin.org.  When each process is finished, the process
sentinel should conclude by killing the process's buffer.

This appears to work most of the time, especially with low numbers of
processes (like 1-3).  But as the number of processes is increased,
sometimes one or more of the attempts to kill a process's buffer result
in the user's being prompted to kill the buffer due to the process still
running (an obvious problem when happening in library code that the user
should not be concerned with).  As the number of processes increases,
the number of process buffers that prompt seems to increase (e.g. with
15 processes, 1-2 prompts seems common).

A possible workaround would be to check the process's status before
attempting to kill the buffer, however that would seem to raise a
problem: according to the Elisp manual, calls to the sentinel may be
coalesced when a process's status changes quickly, so if the sentinel
simply did not kill the buffer if the process were still alive, it's
unclear whether the sentinel will be called a final time, after the
process's status is `closed'; if not, the buffer would never be killed.
Alternatively, the sentinel could loop while checking `process-status',
but that would obviously be undesirable, and would seem like working
around a bug (and it might be the wrong thing to do in general,
depending on the process's and sentinel's purposes).

To test this ECM:

1.  Evaluate this file (with lexical-binding).

2.  Eval (argh).

3.  The messages buffer should show the first line of the HTTP response
body for requests 1-10, as well as a "killing buffer..."  line for each
curl process's buffer.  There should be NO "Buffer has a running
process; kill it?" prompts.

4.  But, usually, there will be one or two of those prompts.  When there
are, you can see that the buffer's process has a (process-status) value
of "open" rather than "closed", even though the process's sentinel was
called with "finished\n" as the status argument.

So far, this has been reproduced on Emacs 26.3, 27.2 (with Eric
Abrahamsen's help), and 28.0.50 (built on 2021-07-05), on GNU/Linux.

Alternatively, if this simply demonstrates a lack of understanding on my
part of how to properly use sentinels, I'd be grateful to be corrected.

[This file has also been posted at
https://gist.github.com/alphapapa/daa36dc3388dec694602e06fe6d114b7, and
may be updated there if necessary.]

Thanks,
Adam