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

From: Eli Zaretskii <[email-masked]>
Date: Fri, 14 Mar 2025 09:26:03 +0200

> Date: Thu, 13 Mar 2025 23:21:59 +0200
> Cc: [email-masked], [email-masked]
> From: Dmitry Gutov <[email-masked]>
> 
> On 13/03/2025 22:29, Eli Zaretskii wrote:
> 
> >> If the direct kill-buffer call swaps the buffer under you, it's somewhat
> >> odd, but at least it's predictable and can be debugged. Having a
> >> different thread do that do your execution flow at a random time is
> >> quite another thing.
> > 
> > Suppose a process filter or sentinel, or a timer does that -- is that
> > any different? should we forbid that?
> 
> Yeah, I think a timer or a sentinel killing a non-"private" buffer would 
> be a programmer error. Still, in that case the caller can compare the 
> kill-buffer argument to current-buffer and see that they're equal - so 
> print-debugging would still work (or edebug, etc).

If it's important, we could provide a thread-buffer function to return
the current buffer of a thread.  Should be easy to implement.

> >>>> And/or if the killing does not happen, showing a warning or an error
> >>>> would be an improvement.
> >>>
> >>> We could signal an error, yes.  But it sounds too drastic to me.
> >>
> >> Or a warning, or an entry in *Messages*, at least. Anything's better
> >> than silent noop. And you can't examine the thread's current buffer in
> >> Lisp, to find the conflicting thread another way from Lisp (e.g. for
> >> print-debugging).
> > 
> > I'd still prefer to kill the buffer, just more safely.  I mean, how is
> > this different from killing a buffer that is displayed in one or more
> > windows?  We do handle that.
> 
> Okay, how about Spencer's suggestion (maybe modulo the 
> kill-buffer-query-functions part)? When we try to kill a buffer that is 
> current to a thread, we first send a signal to that thread (to be 
> handled async), then switch that thread's buffer to another (*). Do that 
> check in all threads, then kill the buffer.

If you signal a thread that wasn't prepared to catch the signal, the
thread will terminate.  How many thread functions out there are
prepared to catch signals?  This would require every thread function
to be wrapped in condition-case with a non-trivial handler.  And what
do we expect the handler to do? probably what the loop in kill-buffer
that replaces the current buffer will do anyway, or perhaps just quit
in a more orderly fashion?

Maybe this could be an optional feature, though.  That is, the
make-thread call could accept an additional optional argument to
indicate that this thread would like to be signaled if its current
buffer is ever killed.

Patches welcome.