Commit bad41229 authored by Stefan Monnier's avatar Stefan Monnier
Browse files

* lisp/emacs-lisp/timer.el (with-timeout): Make sure we cancel the timer

even in case of error; add debug spec; simplify data flow.
(with-timeout-handler): Remove.
parent 2be4956d
2011-10-13 Stefan Monnier <monnier@iro.umontreal.ca>
* emacs-lisp/timer.el (with-timeout): Make sure we cancel the timer
even in case of error; add debug spec; simplify data flow.
(with-timeout-handler): Remove.
2011-10-12 Michael Albinus <michael.albinus@gmx.de> 2011-10-12 Michael Albinus <michael.albinus@gmx.de>
Fix Bug#6019, Bug#9315. Fix Bug#6019, Bug#9315.
......
...@@ -402,10 +402,6 @@ This function returns a timer object which you can use in `cancel-timer'." ...@@ -402,10 +402,6 @@ This function returns a timer object which you can use in `cancel-timer'."
(timer-activate-when-idle timer t) (timer-activate-when-idle timer t)
timer)) timer))
(defun with-timeout-handler (tag)
"This is the timer function used for the timer made by `with-timeout'."
(throw tag 'timeout))
(defvar with-timeout-timers nil (defvar with-timeout-timers nil
"List of all timers used by currently pending `with-timeout' calls.") "List of all timers used by currently pending `with-timeout' calls.")
...@@ -417,24 +413,27 @@ event (such as keyboard input, input from subprocesses, or a certain time); ...@@ -417,24 +413,27 @@ event (such as keyboard input, input from subprocesses, or a certain time);
if the program loops without waiting in any way, the timeout will not if the program loops without waiting in any way, the timeout will not
be detected. be detected.
\n(fn (SECONDS TIMEOUT-FORMS...) BODY)" \n(fn (SECONDS TIMEOUT-FORMS...) BODY)"
(declare (indent 1)) (declare (indent 1) (debug ((form body) body)))
(let ((seconds (car list)) (let ((seconds (car list))
(timeout-forms (cdr list))) (timeout-forms (cdr list))
`(let ((with-timeout-tag (cons nil nil)) (timeout (make-symbol "timeout")))
with-timeout-value with-timeout-timer `(let ((-with-timeout-value-
(with-timeout-timers with-timeout-timers)) (catch ',timeout
(if (catch with-timeout-tag (let* ((-with-timeout-timer-
(progn (run-with-timer ,seconds nil
(setq with-timeout-timer (lambda () (throw ',timeout ',timeout))))
(run-with-timer ,seconds nil (with-timeout-timers
'with-timeout-handler (cons -with-timeout-timer- with-timeout-timers)))
with-timeout-tag)) (unwind-protect
(push with-timeout-timer with-timeout-timers) ,@body
(setq with-timeout-value (progn . ,body)) (cancel-timer -with-timeout-timer-))))))
nil)) ;; It is tempting to avoid the `if' altogether and instead run
(progn . ,timeout-forms) ;; timeout-forms in the timer, just before throwing `timeout'.
(cancel-timer with-timeout-timer) ;; But that would mean that timeout-forms are run in the deeper
with-timeout-value)))) ;; dynamic context of the timer, with inhibit-quit set etc...
(if (eq -with-timeout-value- ',timeout)
(progn ,@timeout-forms)
-with-timeout-value-))))
(defun with-timeout-suspend () (defun with-timeout-suspend ()
"Stop the clock for `with-timeout'. Used by debuggers. "Stop the clock for `with-timeout'. Used by debuggers.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment