GNU bug report logs - #80140
30.1.90; jsonrpc-shutdown does not wait its full timeout if the process has output

Previous Next

Package: emacs;

Reported by: Aaron Zeng <azeng <at> janestreet.com>

Date: Tue, 6 Jan 2026 17:20:02 UTC

Severity: normal

Found in version 30.1.90

To reply to this bug, email your comments to 80140 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#80140; Package emacs. (Tue, 06 Jan 2026 17:20:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Aaron Zeng <azeng <at> janestreet.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 06 Jan 2026 17:20:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Aaron Zeng <azeng <at> janestreet.com>
To: bug-gnu-emacs <at> gnu.org
Cc: app-emacs-dev <at> janestreet.com, azeng <at> janestreet.com
Subject: 30.1.90; jsonrpc-shutdown does not wait its full timeout if the
 process has output
Date: Tue, 06 Jan 2026 12:18:56 -0500
Hello,

I have noticed that jsonrpc-shutdown (called by eglot-shutdown)
sometimes does not wait the full 100ms timeout for the process to exit
and instead calls delete-process (sending SIGKILL) very quickly after
being called.  For example, here is some output from attempting to shut
down ocaml-lsp using M-x eglot-shutdown:

    [jsonrpc] e[17:11:23.652] --> shutdown[4] {"jsonrpc":"2.0","id":4,"method":"shutdown","params":{}}
    [stderr]  2025-12-19 17:11:23.652551-05:00 Info ("request:shutdown                 (azeng:11)"(category request)(event_index 11)(action shutdown)(feature())(file())(lines())(hash())(position())(info())) -- [program: ocaml-lsp-server]
    [jsonrpc] e[17:11:23.653]   <-- shutdown[4] {"id":4,"jsonrpc":"2.0","result":null}
    [jsonrpc] e[17:11:23.653] --> exit {"jsonrpc":"2.0","method":"exit","params":{}}
    [stderr]  2025-12-19 17:11:23.653406-05:00 Info ("Priority_lsp_executor queue stats"(action"just after dequeue: Eof")(realtime_size 0)(background_size 0)(total_size 0)) -- [program: ocaml-lsp-server]
    [jsonrpc] D[17:11:23.664] Connection state change: `killed

From the timestamps, you can see that the connection was killed a mere
11ms after the exit request notification was sent, rather than the
expected 100ms.  I believe this is due to the fact that jsonrpc-shutdown
will only call accept-process-output once, but that function may return
sooner than 100ms if the process produces some stdout/stderr output and
runs a process filter:

      (cl-loop
       with proc = (jsonrpc--process conn) for i from 0
       while (not (process-get proc 'jsonrpc-sentinel-cleanup-started))
       unless (zerop i) do
       (jsonrpc--warn "Sentinel for %s still hasn't run, deleting it!" proc)
       (delete-process proc)
       do
       ;; Let sentinel have a chance to run
       (accept-process-output nil 0.1))

In order to allow a full 100ms for the process to exit, I think this
instead needs to loop and call accept-process-output multiple times,
perhaps using with-timeout like so:

    do
    ;; Let sentinel have a chance to run
    (with-timeout (0.1)
      (while (not (process-get proc 'jsonrpc-sentinel-cleanup-started))
        (accept-process-output)))

With the above code installed locally, I see that eglot-shutdown waits
the full 100ms on a nonresponsive language server before SIGKILLing it.
Please feel free to reimplement to taste :)

Thanks,
Aaron


In GNU Emacs 30.1.90 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.15.12, Xaw scroll bars) of 2025-12-17 built on
 igm-qws-u12685a
Repository revision: b16b92282c83c51818a55c9f7a241596e876ad4e
Windowing system distributor 'The X.Org Foundation', version 11.0.12011000
System Description: Rocky Linux 8.10 (Green Obsidian)

Configured using:
 'configure --with-x-toolkit=lucid --without-gpm --without-gconf
 --without-selinux --without-imagemagick --with-modules --with-gif=no
 --with-cairo --with-rsvg --without-compress-install --with-tree-sitter
 --with-native-compilation=aot
 --prefix=/usr/local/home/garnish/raw-emacs/30-20251217_145705'

Configured features:
CAIRO DBUS FREETYPE GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG LIBSYSTEMD
LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP
SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER X11 XDBE XIM
XINPUT2 XPM LUCID ZLIB

Important settings:
  value of $EMACSLOADPATH: /usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+share+/app/emacs/elisp:/usr/local/home/azeng/workspaces/24833141-bffb-3c99-a9d6-c366d37c4f5e/+share+/app/emacs/site-lisp:
  value of $LANG: en_US.utf8
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-regexp-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message mailcap yank-media puny dired
dired-loaddefs rfc822 mml mml-sec password-cache epa derived epg rfc6068
epg-config gnus-util text-property-search time-date subr-x mm-decode
mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader
sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils
help-mode cl-loaddefs cl-lib rmc iso-transl tooltip cconv eldoc paren
electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/x-win x-win term/common-win x-dnd touch-screen tool-bar dnd fontset
image fringe tabulated-list replace newcomment text-mode lisp-mode
prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu
timer select scroll-bar mouse jit-lock font-lock syntax font-core
term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
theme-loaddefs regexp-opt faces cus-face macroexp files window
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget keymap hashtable-print-readable backquote threads dbusbind
inotify dynamic-setting system-font-setting font-render-setting cairo
x-toolkit xinput2 x multi-tty move-toolbar make-network-process
native-compile emacs)

Memory information:
((conses 16 58500 9886) (symbols 48 5519 3) (strings 32 22158 1681)
 (string-bytes 1 579161) (vectors 16 9202)
 (vector-slots 8 128678 7990) (floats 8 25 2) (intervals 56 276 0)
 (buffers 992 11))




This bug report was last modified 5 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.