diff options
| author | Stefan Monnier | 2014-05-18 08:58:30 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2014-05-18 08:58:30 -0400 |
| commit | 08a2434e2f7a60fc558e052e37409333582504cb (patch) | |
| tree | 0fdc023b08f78ad8fbd3950777fdf52e389fb298 | |
| parent | 2f826609630cc1bf1d470428273711ebde9eec3c (diff) | |
| download | emacs-08a2434e2f7a60fc558e052e37409333582504cb.tar.gz emacs-08a2434e2f7a60fc558e052e37409333582504cb.zip | |
* lisp/emacs-lisp/timer.el (timer-event-handler): Don't run if canceled.
Fixes: debbugs:17392
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/emacs-lisp/timer.el | 80 | ||||
| -rw-r--r-- | lisp/frame.el | 4 | ||||
| -rw-r--r-- | src/minibuf.c | 3 |
4 files changed, 52 insertions, 40 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 9205d3a73ea..90335fda706 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2014-05-18 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * emacs-lisp/timer.el (timer-event-handler): Don't run if canceled | ||
| 4 | (bug#17392). | ||
| 5 | |||
| 1 | 2014-05-17 Michael Albinus <michael.albinus@gmx.de> | 6 | 2014-05-17 Michael Albinus <michael.albinus@gmx.de> |
| 2 | 7 | ||
| 3 | * net/tramp-sh.el (tramp-find-inline-encoding): Do not match "%%t" | 8 | * 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." | |||
| 290 | (cell | 290 | (cell |
| 291 | ;; Delete from queue. Record the cons cell that was used. | 291 | ;; Delete from queue. Record the cons cell that was used. |
| 292 | (cancel-timer-internal timer))) | 292 | (cancel-timer-internal timer))) |
| 293 | ;; Re-schedule if requested. | 293 | ;; If `cell' is nil, it means the timer was already canceled, so we |
| 294 | (if (timer--repeat-delay timer) | 294 | ;; shouldn't be running it at all. This can happen for example with the |
| 295 | (if (timer--idle-delay timer) | 295 | ;; following scenario (bug#17392): |
| 296 | (timer-activate-when-idle timer nil cell) | 296 | ;; - we run timers, starting with A (and remembering the rest as (B C)). |
| 297 | (timer-inc-time timer (timer--repeat-delay timer) 0) | 297 | ;; - A runs and a does a sit-for. |
| 298 | ;; If real time has jumped forward, | 298 | ;; - during sit-for we run timer D which cancels timer B. |
| 299 | ;; perhaps because Emacs was suspended for a long time, | 299 | ;; - timer A finally finishes, so we move on to timers B and C. |
| 300 | ;; limit how many times things get repeated. | 300 | (unless cell |
| 301 | (if (and (numberp timer-max-repeats) | 301 | ;; Re-schedule if requested. |
| 302 | (< 0 (timer-until timer (current-time)))) | 302 | (if (timer--repeat-delay timer) |
| 303 | (let ((repeats (/ (timer-until timer (current-time)) | 303 | (if (timer--idle-delay timer) |
| 304 | (timer--repeat-delay timer)))) | 304 | (timer-activate-when-idle timer nil cell) |
| 305 | (if (> repeats timer-max-repeats) | 305 | (timer-inc-time timer (timer--repeat-delay timer) 0) |
| 306 | (timer-inc-time timer (* (timer--repeat-delay timer) | 306 | ;; If real time has jumped forward, |
| 307 | repeats))))) | 307 | ;; perhaps because Emacs was suspended for a long time, |
| 308 | ;; Place it back on the timer-list before running | 308 | ;; limit how many times things get repeated. |
| 309 | ;; timer--function, so it can cancel-timer itself. | 309 | (if (and (numberp timer-max-repeats) |
| 310 | (timer-activate timer t cell) | 310 | (< 0 (timer-until timer (current-time)))) |
| 311 | (setq retrigger t))) | 311 | (let ((repeats (/ (timer-until timer (current-time)) |
| 312 | ;; Run handler. | 312 | (timer--repeat-delay timer)))) |
| 313 | (condition-case-unless-debug err | 313 | (if (> repeats timer-max-repeats) |
| 314 | ;; Timer functions should not change the current buffer. | 314 | (timer-inc-time timer (* (timer--repeat-delay timer) |
| 315 | ;; If they do, all kinds of nasty surprises can happen, | 315 | repeats))))) |
| 316 | ;; and it can be hellish to track down their source. | 316 | ;; Place it back on the timer-list before running |
| 317 | (save-current-buffer | 317 | ;; timer--function, so it can cancel-timer itself. |
| 318 | (apply (timer--function timer) (timer--args timer))) | 318 | (timer-activate timer t cell) |
| 319 | (error (message "Error running timer%s: %S" | 319 | (setq retrigger t))) |
| 320 | (if (symbolp (timer--function timer)) | 320 | ;; Run handler. |
| 321 | (format " `%s'" (timer--function timer)) "") | 321 | (condition-case-unless-debug err |
| 322 | err))) | 322 | ;; Timer functions should not change the current buffer. |
| 323 | (when (and retrigger | 323 | ;; If they do, all kinds of nasty surprises can happen, |
| 324 | ;; If the timer's been canceled, don't "retrigger" it | 324 | ;; and it can be hellish to track down their source. |
| 325 | ;; since it might still be in the copy of timer-list kept | 325 | (save-current-buffer |
| 326 | ;; by keyboard.c:timer_check (bug#14156). | 326 | (apply (timer--function timer) (timer--args timer))) |
| 327 | (memq timer timer-list)) | 327 | (error (message "Error running timer%s: %S" |
| 328 | (setf (timer--triggered timer) nil))))) | 328 | (if (symbolp (timer--function timer)) |
| 329 | (format " `%s'" (timer--function timer)) "") | ||
| 330 | err))) | ||
| 331 | (when (and retrigger | ||
| 332 | ;; If the timer's been canceled, don't "retrigger" it | ||
| 333 | ;; since it might still be in the copy of timer-list kept | ||
| 334 | ;; by keyboard.c:timer_check (bug#14156). | ||
| 335 | (memq timer timer-list)) | ||
| 336 | (setf (timer--triggered timer) nil)))))) | ||
| 329 | 337 | ||
| 330 | ;; This function is incompatible with the one in levents.el. | 338 | ;; This function is incompatible with the one in levents.el. |
| 331 | (defun timeout-event-p (event) | 339 | (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." | |||
| 1822 | :initialize 'custom-initialize-delay | 1822 | :initialize 'custom-initialize-delay |
| 1823 | :group 'cursor | 1823 | :group 'cursor |
| 1824 | :global t | 1824 | :global t |
| 1825 | (if blink-cursor-idle-timer (cancel-timer blink-cursor-idle-timer)) | 1825 | (blink-cursor-suspend) |
| 1826 | (setq blink-cursor-idle-timer nil) | ||
| 1827 | (blink-cursor-end) | ||
| 1828 | (remove-hook 'focus-in-hook #'blink-cursor-check) | 1826 | (remove-hook 'focus-in-hook #'blink-cursor-check) |
| 1829 | (remove-hook 'focus-out-hook #'blink-cursor-suspend) | 1827 | (remove-hook 'focus-out-hook #'blink-cursor-suspend) |
| 1830 | (when blink-cursor-mode | 1828 | (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, | |||
| 396 | in previous recursive minibuffer, but was not set explicitly | 396 | in previous recursive minibuffer, but was not set explicitly |
| 397 | to t for this invocation, so set it to nil in this minibuffer. | 397 | to t for this invocation, so set it to nil in this minibuffer. |
| 398 | Save the old value now, before we change it. */ | 398 | Save the old value now, before we change it. */ |
| 399 | specbind (intern ("minibuffer-completing-file-name"), Vminibuffer_completing_file_name); | 399 | specbind (intern ("minibuffer-completing-file-name"), |
| 400 | Vminibuffer_completing_file_name); | ||
| 400 | if (EQ (Vminibuffer_completing_file_name, Qlambda)) | 401 | if (EQ (Vminibuffer_completing_file_name, Qlambda)) |
| 401 | Vminibuffer_completing_file_name = Qnil; | 402 | Vminibuffer_completing_file_name = Qnil; |
| 402 | 403 | ||