GNU bug report logs - #76969
kill-buffer fails silently when a thread exists where it's current

Previous Next

Package: emacs;

Reported by: Dmitry Gutov <dmitry <at> gutov.dev>

Date: Wed, 12 Mar 2025 01:17:01 UTC

Severity: normal

Full log


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

From: Eli Zaretskii <eliz <at> gnu.org>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: 76969 <at> debbugs.gnu.org
Subject: Re: bug#76969: kill-buffer fails silently when a thread exists where
 it's current
Date: Thu, 13 Mar 2025 11:47:44 +0200
> Date: Wed, 12 Mar 2025 03:16:08 +0200
> From: Dmitry Gutov <dmitry <at> gutov.dev>
> 
> This stems from a private bug report about diff-hl when it uses a thread 
> to update the fringe highlights.
> 
> To reproduce:
> 
>    1. Install, enable diff-hl-mode.
>    2. (setq diff-hl-update-async t)
>    3. Visit a code buffer in a (e.g.) Git repo, save it.
>    4. Make an edit, don't save.
>    5. Evaluate this:
> 
>    (progn
>      (save-buffer)
>      (kill-buffer))
> 
> Current:
> 
> The result is that the buffer is not killed. And that happens silently, 
> no errors or anything. Only further examination and reading the sources 
> led to understanding the reason.
> 
> Expected:
> 
> It probably should be killed. After the thread is signaled some error 
> (perhaps) and is aborted. And if the buffer can't be killed, 
> 'kill-buffer' itself should exit with an error.
> 
> As I understand the behavior is old (2013) and comes from the 
> 'thread_check_current_buffer' call in Fkill_buffer. But it's not 
> mentioned in kill-buffer's docstring or the manual.

There are other reasons which preclude killing a buffer that aren't
mentioned in the doc string.  For example, this:

  /* Don't kill the minibuffer now current.  */
  if (BASE_EQ (buffer, XWINDOW (minibuf_window)->contents))
    return Qnil;

or this:

  /* Make this buffer not be current.  Exit if it is the sole visible
     buffer.  */
  if (b == current_buffer)
    {
      tem = Fother_buffer (buffer, Qnil, Qnil);
      Fset_buffer (tem);
      if (b == current_buffer)
	return Qnil;

or this:

  /* If the buffer now current is shown in the minibuffer and our buffer
     is the sole other buffer give up.  */
  XSETBUFFER (tem, current_buffer);
  if (EQ (tem, XWINDOW (minibuf_window)->contents)
      && BASE_EQ (buffer, Fother_buffer (buffer, Qnil, Qnil)))
    return Qnil;

So if this is a request to spell out these conditions in the
documentation, I'm okay with doing so.  But is this the only request
here?  If not, please elaborate.




This bug report was last modified 93 days ago.

Previous Next


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