Subject: Re: bug#78737: sit-for behavior changes when byte-compiled

From: Lynn Winebarger <[email-masked]>
Date: Sat, 14 Jun 2025 13:36:59 -0400

On Sat, Jun 14, 2025, 2:28 AM Pip Cet <[email-masked]> wrote:

> "Lynn Winebarger" <[email-masked]> writes:
>
> > On Fri, Jun 13, 2025 at 10:02 AM Daniel Colascione <[email-masked]>
> wrote:
> >>
> >>
> >>
> >> On June 13, 2025 6:42:58 AM PDT, Daniel Colascione <[email-masked]>
> wrote:
> >> >
> >> >We already have something like that. :-) read-event already runs
> >> > the events it reads through special-event-map, right? We don't
> >> > even need to create a separate thunk list concept: we could just
> >> > bind C-g in special event map and do what we want, right?
>
> > Would that provide the behavior Pip is looking for?
>
> It would not, because quits are currently processed out-of-order, and
> this important feature should remain in place for "serious" quits.  See
> below.
>
> >> >The only special thing about C-g is how we treat it when Lisp is
> >> > running. When it's instead reading an event, it can and be a
> >> > boring event processed the same way every other event is.
>
> > It seems to me what Pip is looking for is analogous to a "Quit" button
> > hardwired to a pin on a CPU, which is not something that can be
> > reliably implemented in the C primitives as they are now.
>
> You're suggesting I'm looking for something that cannot be implemented.
> I'm not.
>

That was not my intention.  I don't think that hard-wired behavior can be
reliably implemented one read_char has started processing an input event
off its queue.  There's just too many ways a keystroke can get consumed or
discarded that may not even be in the C primitives, as far as I can tell.
At least, that's what it looks like from a cursory reading of read_char.
It seems to me the most reliable way to guarantee C-g or any other
designated special input is treated specially is to make sure they don't
enter the queue processed by read_char at all.  And the most reliable way
to do that is probably to make the signal handler indicating keystrokes are
available, split the special keystrokes off into their own queue right from
the start.  How much actual processing might be done from the handler's
activation frame is a separate matter.  For example, the signal handler
could increment a quit count if it isn't already, then do something more
aggressive if the count exceeds some threshold, like throwing directly from
the signal handler rather than waiting for the C code to reach some point
safe for throwing.

>
> I described specific situations in which I think quit should be expanded
> to work better than it does now.  No one's expecting that quit works in
> absolutely every situation, as far as I know.  That's what gdb is for.
>

Actually, I'd love C-g to reliably interrupt Emacs when it appears locked
up and I have no idea why.  It's probably annoying to other users who don't
have a copy of Emacs built for debugging to not be able to kick Emacs out
of an infinite loop (or worse) as well.

> If you're referring to the "C-g C-g" thing, I did not describe how I'd
> implement it in detail, because there are many choices to be made; but
> the main idea would be that we should not immediately clear inhibit-quit
> for that combination, because that's a dangerous and destructive thing
> to do.  If we decide to do so (after a delay, for example), we need to
> print a clear warning to the user that their Emacs session needs
> restarting.
>
> So C-g C-g might do less than GUI C-g C-g C-g does currently.
>
> There are actions even more dangerous than clearing inhibit-quit.  I
> don't know whether we want a level-3 quit which does even more than the
> current GUI C-g C-g C-g code.
>

I don't really understand the necessity or use of inhibit-quit, as opposed
to, say, pushing a new quit handler or blocking input altogether, if the
consistency of the lisp machine state is a concern (e.g. to prevent
throwing from a signal handler).

Lynn