Subject: bug#63078: 26.1; Sentinels are sometimes unexpectedly only invoked in script mode

From: Markus Triska <[email-masked]>
Date: Wed, 26 Apr 2023 19:58:54 +0200

Eli Zaretskii <[email-masked]> writes:

> I cannot reproduce the problem with Emacs 28.2: I get "process said:
> hello" in the echo-area, as expected.  Did you try with the -nw
> command-line switch, and if you do, does it change anything?

> It could be some timing problem: you start a program that exits almost
> immediately, so there could be some race condition between the program
> and your code.

I can reproduce the problem also with Emacs 28.8, and yes, I also
believe this may be a timing issue: I have now constructed a test case
that exhibits the issue also when the "-nw" option is used. To
reproduce, please start Emacs with:

    $ emacs -Q

or with:

    $ emacs -Q -nw

and then place the forms below in a buffer, and then evaluate the buffer
contents with M-x eval-buffer RET. The bash shell is used as external
process, the sample C program I originally included is no longer needed.
The expected output of the forms below is an endless stream of messages
of the form:

    trying to elicit race condition at (25673 25753 287220 854000)
    process status is: run [2 times]
    process said: hi
    failed
    trying to elicit race condition at (25673 25753 289270 703000)
    process status is: run [2 times]
    process said: hi
    failed

i.e., the expected case is that *no* race condition exists, and
therefore eliciting the issue *fails*, which is the desired result as
long as the program runs.

However, after I few seconds, this expected sequence of messages stops,
and only the following message is then emitted over and over:

    process status is: exit

When this occurs, it means that the sentinel was unexpectedly not
invoked when the process stops, in contrast to all preceding cases where
the sentinel was invoked as expected when the process terminates.

Running the program in script mode yields the expected result over and
over, I cannot elicit the issue with the --script option of Emacs.

I hope this helps. Can you reproduce the issue with this example?

Thank you and all the best,
Markus

(defvar p-stopped nil)

(defun my-sentinel (proc str)
  (when (string-match "^\\(?:finished\n\\|exited abnormally\\|killed\n\\)"
                      str)
    (setq p-stopped t)))

(defun wait-for-process-end (proc)
  (while (not p-stopped)
    (message "process status is: %s" (process-status proc))
    (accept-process-output proc 0.1 nil t)))

(defun elicit-issue ()
  (with-temp-buffer
    (let ((proc (start-process "p" (current-buffer) "bash" "-c" "echo -n hi")))
      (setq p-stopped nil)
      (set-process-sentinel proc 'my-sentinel)
      (wait-for-process-end proc))
    (message "process said: %s" (buffer-string))))

(while t
  (message "trying to elicit race condition at %s" (current-time))
  (elicit-issue)
  (message "failed"))