emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r106073: * lisp/emacs-lisp/timer.el (


From: Stefan Monnier
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r106073: * lisp/emacs-lisp/timer.el (with-timeout): Make sure we cancel the timer
Date: Thu, 13 Oct 2011 01:18:12 -0400
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 106073
committer: Stefan Monnier <address@hidden>
branch nick: trunk
timestamp: Thu 2011-10-13 01:18:12 -0400
message:
  * 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.
modified:
  lisp/ChangeLog
  lisp/emacs-lisp/timer.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2011-10-12 18:32:35 +0000
+++ b/lisp/ChangeLog    2011-10-13 05:18:12 +0000
@@ -1,3 +1,9 @@
+2011-10-13  Stefan Monnier  <address@hidden>
+
+       * 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  <address@hidden>
 
        Fix Bug#6019, Bug#9315.

=== modified file 'lisp/emacs-lisp/timer.el'
--- a/lisp/emacs-lisp/timer.el  2011-07-04 06:25:23 +0000
+++ b/lisp/emacs-lisp/timer.el  2011-10-13 05:18:12 +0000
@@ -402,10 +402,6 @@
     (timer-activate-when-idle timer t)
     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
   "List of all timers used by currently pending `with-timeout' calls.")
 
@@ -417,24 +413,27 @@
 if the program loops without waiting in any way, the timeout will not
 be detected.
 \n(fn (SECONDS TIMEOUT-FORMS...) BODY)"
-  (declare (indent 1))
+  (declare (indent 1) (debug ((form body) body)))
   (let ((seconds (car list))
-       (timeout-forms (cdr list)))
-    `(let ((with-timeout-tag (cons nil nil))
-          with-timeout-value with-timeout-timer
-          (with-timeout-timers with-timeout-timers))
-       (if (catch with-timeout-tag
-            (progn
-              (setq with-timeout-timer
-                    (run-with-timer ,seconds nil
-                                     'with-timeout-handler
-                                     with-timeout-tag))
-              (push with-timeout-timer with-timeout-timers)
-              (setq with-timeout-value (progn . ,body))
-              nil))
-          (progn . ,timeout-forms)
-        (cancel-timer with-timeout-timer)
-        with-timeout-value))))
+       (timeout-forms (cdr list))
+        (timeout (make-symbol "timeout")))
+    `(let ((-with-timeout-value-
+            (catch ',timeout
+              (let* ((-with-timeout-timer-
+                      (run-with-timer ,seconds nil
+                                      (lambda () (throw ',timeout ',timeout))))
+                     (with-timeout-timers
+                         (cons -with-timeout-timer- with-timeout-timers)))
+                (unwind-protect
+                    ,@body
+                  (cancel-timer -with-timeout-timer-))))))
+       ;; It is tempting to avoid the `if' altogether and instead run
+       ;; timeout-forms in the timer, just before throwing `timeout'.
+       ;; But that would mean that timeout-forms are run in the deeper
+       ;; 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 ()
   "Stop the clock for `with-timeout'.  Used by debuggers.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]