[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Emacs-diffs] master 1392ec7 2/3: A quicker check for quit

From: Eli Zaretskii
Subject: Re: [Emacs-diffs] master 1392ec7 2/3: A quicker check for quit
Date: Sun, 29 Jan 2017 19:30:47 +0200

> From: Paul Eggert <address@hidden>
> Date: Thu, 26 Jan 2017 09:45:09 -0800
> I was under the impression that if immediate_quit is true, then a tight 
> loop in C doesn't need to call maybe_quit (the new name for QUIT), as 
> C-g will error out immediately. There is longstanding code in the 
> interpreter that assumes this, for example in the implementation of nth.
> Unfortunately my impression is incorrect. If you byte-compile this:
> (defun foo () (nth most-positive-fixnum '#1=(1 . #1#)))
> and load the resulting .elc file and then execute (foo) on a 64-bit 
> Emacs displaying X, then C-g does not interrupt Emacs and Emacs hangs 
> while counting up to 2**61. (C-g works as expected with emacs -nw.) I 
> will look into fixing this longstanding bug, as well as fixing similar 
> bugs that I recently introduced.
> This leads me to wonder: what's the point of immediate_quit? If 
> immediate_quit doesn't always cause C-g to immediately quit, why are we 
> bothering with an immediate_quit variable? Or if immediate_quit makes 
> sense, then should we arrange for a C-g under X to behave more like C-g 
> on a terminal, and do a longjmp? (Shudder.)

Once upon a time Emacs on X would read input from a SIGIO handler.  If
you look in the sources for, say, Emacs 22.3, you will see there that
the function input_available_signal, which was installed as the SIGIO
handler, called handle_async_input, which read input from the
window-system.  As part of reading input, Emacs would QUIT immediately
when it saw C-g, if immediate_quit was set and inhibit-quit was nil.
Thus, functions that wanted to be interruptible could set
immediate_quit non-zero and be sure they will be interrupted when the
user pressed C-g.

Later we decided that doing non-trivial stuff from signal handlers was
not such a good idea.  So nowadays, the SIGIO handler just sets a flag
and returns.  That flag is checked as part of QUIT (now rebranded as
maybe_quit), and if found set, we quit at that time.

This is why we started inserting QUIT in places that could potentially
hang or take a long time -- to allow the user to interrupt them sooner
rather than later.  And that is why the recent changes which removed
QUIT and added setting immediate_quit non-zero are a move in the wrong
direction -- we should be doing the exact opposite.

> > Of course, for circular lists a better solution is to use the
> > hare&tortoise, e.g. with FOR_EACH_TAIL.
> Yes, that's something that could be done in these cases too. I'd like to 
> get C-g fixed first, though.

If your plan for fixing this is anything other than restoring the
removed calls to maybe_quit, please show or describe your planned
changes before you install them.  This tricky issue is further
complicated by the concurrency features, so I think we should make
sure the design is right before applying.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]