emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

call-process should not block process filters from running


From: Spencer Baugh
Subject: call-process should not block process filters from running
Date: Tue, 27 Jun 2023 17:55:00 -0400

When Lisp code calls call-process, then while call-process is running,
all Lisp is blocked from running, including process filters and timers
created beforehand by other Lisp.  This call-process behavior is
harmful, but we can fix call-process to not behave this way.

This call-process behavior is harmful:
Many packages rely on their process filters and timers being able to
run:
- Packages which communicate over the network (such as ERC)
  rely on being able to respond to heartbeats and prevent timeouts.
- Packages which respond to requests from other programs (such as EXWM)
  rely on being able to respond to those requests.
A simple (shell-command "sleep 60") will cause most such packages to
break or behave poorly.

We can fix call-process to not behave this way:
It is straightforward to reimplement call-process in Lisp, using
accept-process-output, so that process filters and timers and other Lisp
can run while waiting on call-process.  There's been at least one
attempt at doing so:
https://github.com/tromey/emacs/tree/rewrite-call-process

My suggestion is that we should create a new helper function in Lisp,
perhaps called "process-run", which has an identical interface as
call-process, except that while it is running, other process filters and
other Lisp are still able to run.  Then we can move users of
call-process over to this new function.  Most (but perhaps not all) Lisp
using call-process should be using process-run, since most Lisp doesn't
actually want to block process filters from running.

As a bonus, process-run will be usable by Lisp code running in Lisp
threads created by make-thread, as will any functions which use
process-run, since accept-process-output supports threads.
(call-process does not)

A few clarifications in advance for things which I suspect might be
confusing:

- This is not about switching Lisp from running processes synchronously
  (call-process) to asynchronously (make-process).  process-run would
  still be a synchronous API.  It is much easier to fix this one bad
  aspect of the call-process API than to move lots of Lisp over to
  make-process.  Even if we moved all Lisp over to be run asynchronous
  processes, we would still want a fixed call-process for Lisp thread
  support.

- This does not require changing the C core of Emacs at all, nor
  changing the call-process implementation.  The existing
  accept-process-output API is sufficient for creating a synchronous
  process-running API which does not block Lisp from running in process
  filters and timers and so on.

- MS-DOS can't support an implementation of call-process which allows
  other Lisp to run.  On MS-DOS, call-process and process-run will be
  identical.  This is fine and not a problem.  Furthermore, even if it
  was a problem, MS-DOS should not hold us back from improving Emacs on
  other platforms.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]