Subject: bug#17392: 24.3.90; cursor blinks faster and faster

From: Eli Zaretskii <[email-masked]>
Date: Tue, 13 May 2014 20:50:44 +0300

> From: Michael Heerdegen <[email-masked]>
> Cc: [email-masked]
> Date: Tue, 13 May 2014 18:04:14 +0200
> 
> Before spending time in debugging, I studied the related lisp code in
> frame.el and timer.el.  AFAICT, you can't explain what I see exclusively
> by bugs in that code.

I don't see how this can be explained except by some race condition.
And I don't see how can a race condition happen here, since both Lisp
and C code involved in this are supposed to be run by the same
single-threaded Lisp interpreter.

> But Eli, this advice:
> 
>   (advice-add 'timer-event-handler :before
>               (lambda (timer)
>                 (unless (or (memq timer timer-list)
>                             (memq timer timer-idle-list))
>                   (message "This should not happen"))))
> 
> prints "This should not happen" for me.  I can easily reproduce this
> message in emacs -Q.  Should that really be possible?  If not, isn't it
> a clear sign that something's going wrong in keyboard.c?

I agree that the results are strange and even suspicious.  But the
evidence is indirect at best, and there's no description of how this
could happen.  All you have shown is that the invoked timer is not in
the timers list at the moment when the timer is run by the Lisp
interpreter.  How does this implicate keyboard.c?

The code in keyboard.c is very simple: it copies the timers list, and
then examines each timer in the copy in sequence, and invokes every
timer that expired.  That is all.  Can you describe a scenario where
the timer function thus invoked will not find its timer in the
original list?  What could delete or modify the timer, and how?

Perhaps instead of merely comparing timers, you could actually show
the differences between the timer whose function is being run and the
similar (but not identical) time in the list?  (Note that
copy-sequence only copies the list, but not the members, so changing a
member will be reflected in the corresponding member of the original
list.)

Also, what about GC?  Does it happen during this scenario, and if so,
can it cause some strange effects like this?