From: Stefan Monnier Date: Sun, 18 May 2014 12:58:30 +0000 (-0400) Subject: * lisp/emacs-lisp/timer.el (timer-event-handler): Don't run if canceled. X-Git-Tag: emacs-24.3.92~195 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=08a2434e2f7a60fc558e052e37409333582504cb;p=emacs.git * lisp/emacs-lisp/timer.el (timer-event-handler): Don't run if canceled. Fixes: debbugs:17392 --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 9205d3a73ea..90335fda706 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2014-05-18 Stefan Monnier + + * emacs-lisp/timer.el (timer-event-handler): Don't run if canceled + (bug#17392). + 2014-05-17 Michael Albinus * net/tramp-sh.el (tramp-find-inline-encoding): Do not match "%%t" diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el index 515bbc36a06..516ea3643d5 100644 --- a/lisp/emacs-lisp/timer.el +++ b/lisp/emacs-lisp/timer.el @@ -290,42 +290,50 @@ This function is called, by name, directly by the C code." (cell ;; Delete from queue. Record the cons cell that was used. (cancel-timer-internal timer))) - ;; Re-schedule if requested. - (if (timer--repeat-delay timer) - (if (timer--idle-delay timer) - (timer-activate-when-idle timer nil cell) - (timer-inc-time timer (timer--repeat-delay timer) 0) - ;; If real time has jumped forward, - ;; perhaps because Emacs was suspended for a long time, - ;; limit how many times things get repeated. - (if (and (numberp timer-max-repeats) - (< 0 (timer-until timer (current-time)))) - (let ((repeats (/ (timer-until timer (current-time)) - (timer--repeat-delay timer)))) - (if (> repeats timer-max-repeats) - (timer-inc-time timer (* (timer--repeat-delay timer) - repeats))))) - ;; Place it back on the timer-list before running - ;; timer--function, so it can cancel-timer itself. - (timer-activate timer t cell) - (setq retrigger t))) - ;; Run handler. - (condition-case-unless-debug err - ;; Timer functions should not change the current buffer. - ;; If they do, all kinds of nasty surprises can happen, - ;; and it can be hellish to track down their source. - (save-current-buffer - (apply (timer--function timer) (timer--args timer))) - (error (message "Error running timer%s: %S" - (if (symbolp (timer--function timer)) - (format " `%s'" (timer--function timer)) "") - err))) - (when (and retrigger - ;; If the timer's been canceled, don't "retrigger" it - ;; since it might still be in the copy of timer-list kept - ;; by keyboard.c:timer_check (bug#14156). - (memq timer timer-list)) - (setf (timer--triggered timer) nil))))) + ;; If `cell' is nil, it means the timer was already canceled, so we + ;; shouldn't be running it at all. This can happen for example with the + ;; following scenario (bug#17392): + ;; - we run timers, starting with A (and remembering the rest as (B C)). + ;; - A runs and a does a sit-for. + ;; - during sit-for we run timer D which cancels timer B. + ;; - timer A finally finishes, so we move on to timers B and C. + (unless cell + ;; Re-schedule if requested. + (if (timer--repeat-delay timer) + (if (timer--idle-delay timer) + (timer-activate-when-idle timer nil cell) + (timer-inc-time timer (timer--repeat-delay timer) 0) + ;; If real time has jumped forward, + ;; perhaps because Emacs was suspended for a long time, + ;; limit how many times things get repeated. + (if (and (numberp timer-max-repeats) + (< 0 (timer-until timer (current-time)))) + (let ((repeats (/ (timer-until timer (current-time)) + (timer--repeat-delay timer)))) + (if (> repeats timer-max-repeats) + (timer-inc-time timer (* (timer--repeat-delay timer) + repeats))))) + ;; Place it back on the timer-list before running + ;; timer--function, so it can cancel-timer itself. + (timer-activate timer t cell) + (setq retrigger t))) + ;; Run handler. + (condition-case-unless-debug err + ;; Timer functions should not change the current buffer. + ;; If they do, all kinds of nasty surprises can happen, + ;; and it can be hellish to track down their source. + (save-current-buffer + (apply (timer--function timer) (timer--args timer))) + (error (message "Error running timer%s: %S" + (if (symbolp (timer--function timer)) + (format " `%s'" (timer--function timer)) "") + err))) + (when (and retrigger + ;; If the timer's been canceled, don't "retrigger" it + ;; since it might still be in the copy of timer-list kept + ;; by keyboard.c:timer_check (bug#14156). + (memq timer timer-list)) + (setf (timer--triggered timer) nil)))))) ;; This function is incompatible with the one in levents.el. (defun timeout-event-p (event) diff --git a/lisp/frame.el b/lisp/frame.el index f081df788ec..d699d243023 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -1822,9 +1822,7 @@ terminals, cursor blinking is controlled by the terminal." :initialize 'custom-initialize-delay :group 'cursor :global t - (if blink-cursor-idle-timer (cancel-timer blink-cursor-idle-timer)) - (setq blink-cursor-idle-timer nil) - (blink-cursor-end) + (blink-cursor-suspend) (remove-hook 'focus-in-hook #'blink-cursor-check) (remove-hook 'focus-out-hook #'blink-cursor-suspend) (when blink-cursor-mode diff --git a/src/minibuf.c b/src/minibuf.c index cd108d88ecc..c3fcbeb59c7 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -396,7 +396,8 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, Lisp_Object prompt, in previous recursive minibuffer, but was not set explicitly to t for this invocation, so set it to nil in this minibuffer. Save the old value now, before we change it. */ - specbind (intern ("minibuffer-completing-file-name"), Vminibuffer_completing_file_name); + specbind (intern ("minibuffer-completing-file-name"), + Vminibuffer_completing_file_name); if (EQ (Vminibuffer_completing_file_name, Qlambda)) Vminibuffer_completing_file_name = Qnil;