Subject: bug#76969: closed (Re: bug#76969: kill-buffer fails silently when a thread exists where it's current)

From: [email-masked] (GNU bug Tracking System)
Date: Sat, 09 Aug 2025 20:13:02 +0000

Your bug report

#76969: kill-buffer fails silently when a thread exists where it's current

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
76969: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=76969
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#76969: kill-buffer fails silently when a thread exists where it's current
From: Dmitry Gutov <[email-masked]>
To: Eli Zaretskii <[email-masked]>
Cc: [email-masked], [email-masked]
Date: Sat, 9 Aug 2025 23:11:51 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

On 09/08/2025 15:20, Eli Zaretskii wrote:
>> Date: Fri, 1 Aug 2025 03:01:11 +0300
>> Cc:[email-masked],[email-masked]
>> From: Dmitry Gutov<[email-masked]>
>>
>> +@var{buffer-disposition} indicates what happens if the thread's current
>> +buffer is about to be killed.  If the value is @code{t}, it's not
>> +allowed.
> I'd say "killing the buffer is not allowed", because "it" might be
> ambiguous.
> 
>>             Any other value, including nil (which is the default), means
>                                          ^^^
> @code{nil}
> 
>> --- a/src/thread.h
>> +++ b/src/thread.h
>> @@ -143,6 +143,9 @@ #define lisp_eval_depth (current_thread->m_lisp_eval_depth)
>>     struct buffer *m_current_buffer;
>>   #define current_buffer (current_thread->m_current_buffer)
>>   
>> +  /* Decides whether the thread's current buffer can be killed.  */
>> +  Lisp_Object buffer_disposition;
> I think this change means ABI_VERSION in comp.c should be bumped.
> 
> Also, please move this member to before event_object, because the
> comment there says:
> 
>    /* event_object must be the last Lisp field.  */
> 
> which is consistent with how we allocate thread objects:
> 
>    struct thread_state *new_thread
>      = ALLOCATE_ZEROED_PSEUDOVECTOR (struct thread_state, event_object,
> 				    PVEC_THREAD);
> 
> Finally, this needs a NEWS entry.
> 
> With the above nits fixed, please feel free to install, and thanks.

Thanks! Done all that and pushed to master:

https://cgit.git.savannah.gnu.org/cgit/emacs.git/commit/?id=07eb39f1132ceb15e80e7912445890faa8f5b78c

Now closing, and let's be on lookout for user feedback.

Subject: kill-buffer fails silently when a thread exists where it's current
From: Dmitry Gutov <[email-masked]>
To: [email-masked]
Date: Wed, 12 Mar 2025 03:16:08 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

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.

Alternative repro:

If you don't have diff-hl installed, you could replace 1 and 2 with:

   (defun foo ()
     (make-thread (lambda () (sleep-for 0.1))))

   (add-hook 'after-save-hook #'foo)