[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.
- call-process should not block process filters from running,
Spencer Baugh <=