Subject: bug#30182: Update

From: Eli Zaretskii <[email-masked]>
Date: Sun, 04 Feb 2018 20:21:10 +0200

> Date: Sun, 04 Feb 2018 11:01:03 +0100
> From: martin rudalics <[email-masked]>
> CC: [email-masked], [email-masked]
> 
>  > That commentary was outdated.  I updated it now.
> 
> Thanks.
> 
>  > Please take a look
>  > and tell if anything there needs clarification or any other change.
> 
> One question I'd ask myself is how we avoid that redisplay is
> reentered during maybe_quit.

I thought I explained just that in the commentary:

   It is therefore very important that C functions which might cause
   such "asynchronous" redisplay, but cannot tolerate the results, use
   block_input/unblock_input around code fragments which assume that
   global Lisp state doesn't change.

The "asynchronous" redisplay is triggered by certain X events, so the
way to prevent that is to disallow reading X events in
process_pending_signals (which might be called from maybe_quit), and
the call to block_input achieves that.

> And I would like to know which settings
> can disrupt redisplay and whether and which, if any, parts of
> redisplay (mode lines and echo area) may get through after such a
> disruption, probably to avoid garbling the display.

Once again: redisplay itself is not the problem here.  The problem is
calling Lisp as part of redisplay.  This is currently only possible if
note_mouse_highlight is called, which can happen either directly
(because we read a mouse-motion event), or from expose_frame under
certain conditions.  I see no other code in both of these cases that
could invoke Lisp, except that safe_call1 you added lately in
note_mode_line_or_margin_highlight.

>  > I believe that what I wrote in the message to which you were replying
>  > was based on incorrect interpretation of what actually happens.  With
>  > the correct interpretation, there's no asynchronous entry into
>  > redisplay, if "asynchronous" is interpreted literally.  So the
>  > measures I described above are unnecessary, but there is a need to
>  > block input around C fragments that cannot tolerate changes in global
>  > state.
> 
> I must admit that I never thought of maybe_quit being able to process
> input when a function like 'copy-sequence' executes "normally".  Maybe
> this should be emphasized in the Elisp manual's section on Quitting.

Let's first decide what to do about this particular issue, and only
after that see if anything needs to be documented.

> I don't even understand what it's good for to process input just after
> a few conses or calculating the length of some short list.

I'm not sure.  I guess leaving too many unprocessed X events is not
what good X citizens are expected to do?  And reacting to mouse
movements and expose-frame events in a timely manner improves the UX?

>  > This now raises the question: should we block input around the 2 calls
>  > to Fcopy_sequence in timer_check, on the emacs-26 branch?  I tend to
>  > think we should, because letting arbitrary Lisp change the timer lists
>  > while Fcopy_sequence runs could cause hard-to-debug bugs.  WDYT?
> 
> It cannot possibly harm so I think we should.
> 
>  >> And one thing that is obviously needed is some guidance on what should
>  >> be allowed in the mode line and what should be avoided.  For example,
>  >> having `mode-line-buffer-identification' install a timer is something
>  >> that should be avoided IMO.
>  >
>  > If we protect Fcopy_sequence as indicated above, I think such a
>  > limitation would no longer be necessary.
> 
> If the :eval form in 'mode-line-format' changes an arbitrary list
> which is about to be copied, a similar crash could be provoked.  Or am
> I missing something?

Hmm... you are right.  So maybe we need to revert that change which
allows help-echo to be a function, after all.  It seems to open a can
of worms that is too large, so we might as well avoid that before we
get too far.  WDYT?