aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2011-10-13 01:18:12 -0400
committerStefan Monnier2011-10-13 01:18:12 -0400
commitbad4122976909500e8989aad56e415afdacaa28d (patch)
treee6e214583c816b2e9d86ae9bd0c2324db0e193b0
parent2be4956d356f48ae65127679994a6ef6fa208914 (diff)
downloademacs-bad4122976909500e8989aad56e415afdacaa28d.tar.gz
emacs-bad4122976909500e8989aad56e415afdacaa28d.zip
* 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.
-rw-r--r--lisp/ChangeLog6
-rw-r--r--lisp/emacs-lisp/timer.el41
2 files changed, 26 insertions, 21 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 62d7cc449ab..1ec96318116 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,9 @@
12011-10-13 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * emacs-lisp/timer.el (with-timeout): Make sure we cancel the timer
4 even in case of error; add debug spec; simplify data flow.
5 (with-timeout-handler): Remove.
6
12011-10-12 Michael Albinus <michael.albinus@gmx.de> 72011-10-12 Michael Albinus <michael.albinus@gmx.de>
2 8
3 Fix Bug#6019, Bug#9315. 9 Fix Bug#6019, Bug#9315.
diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el
index 0e007ff7176..706c6fd0ba3 100644
--- a/lisp/emacs-lisp/timer.el
+++ b/lisp/emacs-lisp/timer.el
@@ -402,10 +402,6 @@ This function returns a timer object which you can use in `cancel-timer'."
402 (timer-activate-when-idle timer t) 402 (timer-activate-when-idle timer t)
403 timer)) 403 timer))
404 404
405(defun with-timeout-handler (tag)
406 "This is the timer function used for the timer made by `with-timeout'."
407 (throw tag 'timeout))
408
409(defvar with-timeout-timers nil 405(defvar with-timeout-timers nil
410 "List of all timers used by currently pending `with-timeout' calls.") 406 "List of all timers used by currently pending `with-timeout' calls.")
411 407
@@ -417,24 +413,27 @@ event (such as keyboard input, input from subprocesses, or a certain time);
417if the program loops without waiting in any way, the timeout will not 413if the program loops without waiting in any way, the timeout will not
418be detected. 414be detected.
419\n(fn (SECONDS TIMEOUT-FORMS...) BODY)" 415\n(fn (SECONDS TIMEOUT-FORMS...) BODY)"
420 (declare (indent 1)) 416 (declare (indent 1) (debug ((form body) body)))
421 (let ((seconds (car list)) 417 (let ((seconds (car list))
422 (timeout-forms (cdr list))) 418 (timeout-forms (cdr list))
423 `(let ((with-timeout-tag (cons nil nil)) 419 (timeout (make-symbol "timeout")))
424 with-timeout-value with-timeout-timer 420 `(let ((-with-timeout-value-
425 (with-timeout-timers with-timeout-timers)) 421 (catch ',timeout
426 (if (catch with-timeout-tag 422 (let* ((-with-timeout-timer-
427 (progn 423 (run-with-timer ,seconds nil
428 (setq with-timeout-timer 424 (lambda () (throw ',timeout ',timeout))))
429 (run-with-timer ,seconds nil 425 (with-timeout-timers
430 'with-timeout-handler 426 (cons -with-timeout-timer- with-timeout-timers)))
431 with-timeout-tag)) 427 (unwind-protect
432 (push with-timeout-timer with-timeout-timers) 428 ,@body
433 (setq with-timeout-value (progn . ,body)) 429 (cancel-timer -with-timeout-timer-))))))
434 nil)) 430 ;; It is tempting to avoid the `if' altogether and instead run
435 (progn . ,timeout-forms) 431 ;; timeout-forms in the timer, just before throwing `timeout'.
436 (cancel-timer with-timeout-timer) 432 ;; But that would mean that timeout-forms are run in the deeper
437 with-timeout-value)))) 433 ;; dynamic context of the timer, with inhibit-quit set etc...
434 (if (eq -with-timeout-value- ',timeout)
435 (progn ,@timeout-forms)
436 -with-timeout-value-))))
438 437
439(defun with-timeout-suspend () 438(defun with-timeout-suspend ()
440 "Stop the clock for `with-timeout'. Used by debuggers. 439 "Stop the clock for `with-timeout'. Used by debuggers.