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

From: Eli Zaretskii <[email-masked]>
Date: Sun, 16 Mar 2025 08:07:18 +0200

> Date: Sun, 16 Mar 2025 01:29:00 +0200
> Cc: [email-masked], [email-masked]
> From: Dmitry Gutov <[email-masked]>
> 
> On 15/03/2025 16:06, Eli Zaretskii wrote:
> 
> >> My view is that there would be a bunch of threads running concurrently,
> >> most of them "harmless" - but there would be some that modify buffer
> >> contents. Having the buffer switched under them could lead to data loss
> >> in another buffer which happened to be next in the list, with the
> >> changes quite possibly saved to disk.
> > 
> > Yes.  My point is that terminating each such thread because its
> > current buffer was killed might be overkill for threads which don't
> > care about their current-buffer.
> 
> I wonder if the set of functions which behave safely under such 
> conditions is large enough for this to be the default.

If someone would like to make a survey of use patterns of Lisp
threads, I think it will be useful in more than one way.

> >> We can't really distinguish between these kinds of threads from the
> >> outside, so the general model would need to err on the side of safety.
> > 
> > The side of safety in my book is not to kill the buffer.  You
> > suggested instead to signal the thread, which would terminate it, and
> > I consider that not erring on the side of safety.
> 
> Okay... then by default we will not kill the buffer, but allow threads 
> to opt into allowing the buffer to be killed, preceded by a signal?
> 
> That sounds safe enough.

I actually thought the other way around: kill the buffer and deliver
the signal, unless a special buffer-local variable is non-nil.

> But the downside is we retain the current issue, right? As described in 
> the original report.

With your default, yes.  OTOH, the original report didn't explain why
not killing the buffer is a problem.  In general, any Lisp program
that calls kill-buffer should be prepared to deal with the fact that
the buffer might not be killed, due to any of the possible reasons
which prevent that already, even if other threads are no involved.

> 
> If only some threads opt into a different behavior, in general things 
> stay the same.
> 
> >>>> More importantly, having a thread die seems safer than forcing an
> >>>> unexpected buffer change on it - this can lead to visual effects being
> >>>> applied to a wrong buffer, or more importantly, to data loss.
> >>>
> >>> You again are thinking about only a specific class of thread
> >>> functions.  Compare this with killing a buffer shown in the selected
> >>> window and in some other windows, and draw your conclusions from the
> >>> similarity of these two situations.
> >>
> >> Not sure what thread function you're thinking of in this case.
> > 
> > In this analogy, showing buffers is that "thread function".
> 
> Okay. So take just a function that is going to display a buffer. If the 
> buffer is killed, wouldn't it be better for the

This sentence seems to be unfinished.

> I was unclear if you think it's better to always kill the buffer, or to 
> have that behavior opt-in.

That's because I don't yet have a firm opinion.  And to some extent
that depends on the optional features we will implement:

 . is signal always delivered or only to threads which said they want it?
 . do we add a buffer-local dont-ever-kill-my-buffer variable?

> If the buffer is killed, though, I believe it is better to signal its 
> threads. Having the buffer substituted can easily get unnoticed, and 
> would be hard to debug.

And I tend to prefer leaving this to the Lisp program which starts the
thread, via an additional argument to make-thread.