emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r112262: * src/keyboard.c (timer_star


From: Stefan Monnier
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r112262: * src/keyboard.c (timer_start_idle): Call internal-timer-start-idle instead
Date: Wed, 10 Apr 2013 09:31:35 -0400
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 112262
committer: Stefan Monnier <address@hidden>
branch nick: trunk
timestamp: Wed 2013-04-10 09:31:35 -0400
message:
  * src/keyboard.c (timer_start_idle): Call internal-timer-start-idle instead
  of marking the idle timers directly.
  * lisp/emacs-lisp/timer.el (timer--check): New function.
  (timer--time, timer-set-function, timer-event-handler): Use it.
  (timer-set-idle-time): Simplify.
  (timer--activate): CSE.
  (timer-event-handler): Give more info in error message.
  (internal-timer-start-idle): New function, moved from C.
modified:
  lisp/ChangeLog
  lisp/emacs-lisp/timer.el
  src/ChangeLog
  src/keyboard.c
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2013-04-10 13:17:27 +0000
+++ b/lisp/ChangeLog    2013-04-10 13:31:35 +0000
@@ -1,5 +1,12 @@
 2013-04-10  Stefan Monnier  <address@hidden>
 
+       * emacs-lisp/timer.el (timer--check): New function.
+       (timer--time, timer-set-function, timer-event-handler): Use it.
+       (timer-set-idle-time): Simplify.
+       (timer--activate): CSE.
+       (timer-event-handler): Give more info in error message.
+       (internal-timer-start-idle): New function, moved from C.
+
        * mpc.el (mpc-proc): Add `restart' argument.
        (mpc-proc-cmd): Use it.
        (mpc--status-timer-run): Also catch signals from `mpc-proc'.

=== modified file 'lisp/emacs-lisp/timer.el'
--- a/lisp/emacs-lisp/timer.el  2013-04-08 02:08:45 +0000
+++ b/lisp/emacs-lisp/timer.el  2013-04-10 13:31:35 +0000
@@ -27,27 +27,34 @@
 
 ;;; Code:
 
-;; Layout of a timer vector:
-;; [triggered-p high-seconds low-seconds usecs repeat-delay
-;;  function args idle-delay psecs]
-;; triggered-p is nil if the timer is active (waiting to be triggered),
-;;  t if it is inactive ("already triggered", in theory)
-
 (eval-when-compile (require 'cl-lib))
 
 (cl-defstruct (timer
-            (:constructor nil)
-            (:copier nil)
-            (:constructor timer-create ())
-            (:type vector)
-            (:conc-name timer--))
+               (:constructor nil)
+               (:copier nil)
+               (:constructor timer-create ())
+               (:type vector)
+               (:conc-name timer--))
+  ;; nil if the timer is active (waiting to be triggered),
+  ;; non-nil if it is inactive ("already triggered", in theory).
   (triggered t)
-  high-seconds low-seconds usecs repeat-delay function args idle-delay psecs)
+  ;; Time of next trigger: for normal timers, absolute time, for idle timers,
+  ;; time relative to idle-start.
+  high-seconds low-seconds usecs
+  ;; For normal timers, time between repetitions, or nil.  For idle timers,
+  ;; non-nil iff repeated.
+  repeat-delay
+  function args                         ;What to do when triggered.
+  idle-delay                            ;If non-nil, this is an idle-timer.
+  psecs)
 
 (defun timerp (object)
   "Return t if OBJECT is a timer."
   (and (vectorp object) (= (length object) 9)))
 
+(defsubst timer--check (timer)
+  (or (timerp timer) (signal 'wrong-type-argument (list #'timerp timer))))
+
 ;; Pseudo field `time'.
 (defun timer--time (timer)
   (list (timer--high-seconds timer)
@@ -57,17 +64,17 @@
 
 (gv-define-simple-setter timer--time
   (lambda (timer time)
-    (or (timerp timer) (error "Invalid timer"))
+    (timer--check timer)
     (setf (timer--high-seconds timer) (pop time))
     (let ((low time) (usecs 0) (psecs 0))
       (if (consp time)
-         (progn
-           (setq low (pop time))
-           (if time
-               (progn
-                 (setq usecs (pop time))
-                 (if time
-                     (setq psecs (car time)))))))
+          (progn
+            (setq low (pop time))
+            (if time
+                (progn
+                  (setq usecs (pop time))
+                  (if time
+                      (setq psecs (car time)))))))
       (setf (timer--low-seconds timer) low)
       (setf (timer--usecs timer) usecs)
       (setf (timer--psecs timer) psecs))))
@@ -83,15 +90,13 @@
   timer)
 
 (defun timer-set-idle-time (timer secs &optional repeat)
+  ;; FIXME: Merge with timer-set-time.
   "Set the trigger idle time of TIMER to SECS.
 SECS may be an integer, floating point number, or the internal
 time format returned by, e.g., `current-idle-time'.
 If optional third argument REPEAT is non-nil, make the timer
 fire each time Emacs is idle for that many seconds."
-  (if (consp secs)
-      (setf (timer--time timer) secs)
-    (setf (timer--time timer) '(0 0 0))
-    (timer-inc-time timer secs))
+  (setf (timer--time timer) (if (consp secs) secs (seconds-to-time secs)))
   (setf (timer--repeat-delay timer) repeat)
   timer)
 
@@ -156,8 +161,7 @@
 
 (defun timer-set-function (timer function &optional args)
   "Make TIMER call FUNCTION with optional ARGS when triggering."
-  (or (timerp timer)
-      (error "Invalid timer"))
+  (timer--check timer)
   (setf (timer--function timer) function)
   (setf (timer--args timer) args)
   timer)
@@ -181,9 +185,10 @@
              (setcdr reuse-cell timers))
          (setq reuse-cell (cons timer timers)))
        ;; Insert new timer after last which possibly means in front of queue.
-       (cond (last (setcdr last reuse-cell))
-             (idle (setq timer-idle-list reuse-cell))
-             (t    (setq timer-list reuse-cell)))
+        (setf (cond (last (cdr last))
+                    (idle timer-idle-list)
+                    (t    timer-list))
+              reuse-cell)
        (setf (timer--triggered timer) triggered-p)
        (setf (timer--idle-delay timer) idle)
        nil)
@@ -223,8 +228,7 @@
 
 (defun cancel-timer (timer)
   "Remove TIMER from the list of active timers."
-  (or (timerp timer)
-      (error "Invalid timer"))
+  (timer--check timer)
   (setq timer-list (delq timer timer-list))
   (setq timer-idle-list (delq timer timer-idle-list))
   nil)
@@ -283,44 +287,47 @@
   (setq timer-event-last-1 timer-event-last)
   (setq timer-event-last timer)
   (let ((inhibit-quit t))
-    (if (timerp timer)
-       (let (retrigger cell)
-         ;; Delete from queue.  Record the cons cell that was used.
-         (setq cell (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)))))
-               (timer-activate timer t cell)
-               (setq retrigger t)))
-         ;; Run handler.
-         ;; We do this after rescheduling so that the handler function
-         ;; can cancel its own timer successfully with cancel-timer.
-         (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 in timer: %S" 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)))
-      (error "Bogus timer event"))))
+    (timer--check timer)
+    (let ((retrigger nil)
+          (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)))))
 
 ;; This function is incompatible with the one in levents.el.
 (defun timeout-event-p (event)
@@ -531,6 +538,12 @@
        secs
       (if (string-match-p "\\`[0-9.]+\\'" string)
          (string-to-number string)))))
+
+(defun internal-timer-start-idle ()
+  "Mark all idle-time timers as once again candidates for running."
+  (dolist (timer timer-idle-list)
+    (if (timerp timer) ;; FIXME: Why test?
+        (setf (timer--triggered timer) nil))))
 
 (provide 'timer)
 

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-04-09 20:10:47 +0000
+++ b/src/ChangeLog     2013-04-10 13:31:35 +0000
@@ -1,3 +1,8 @@
+2013-04-10  Stefan Monnier  <address@hidden>
+
+       * keyboard.c (timer_start_idle): Call internal-timer-start-idle instead
+       of marking the idle timers directly.
+
 2013-04-09  Stefan Monnier  <address@hidden>
 
        * minibuf.c (Ftest_completion): Ignore non-string/symbol keys in hash

=== modified file 'src/keyboard.c'
--- a/src/keyboard.c    2013-04-08 18:04:58 +0000
+++ b/src/keyboard.c    2013-04-10 13:31:35 +0000
@@ -4198,16 +4198,7 @@
   timer_last_idleness_start_time = timer_idleness_start_time;
 
   /* Mark all idle-time timers as once again candidates for running.  */
-  for (timers = Vtimer_idle_list; CONSP (timers); timers = XCDR (timers))
-    {
-      Lisp_Object timer;
-
-      timer = XCAR (timers);
-
-      if (!VECTORP (timer) || ASIZE (timer) != 9)
-       continue;
-      ASET (timer, 0, Qnil);
-    }
+  call0 (intern ("internal-timer-start-idle"));
 }
 
 /* Record that Emacs is no longer idle, so stop running idle-time timers.  */


reply via email to

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