X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b0144c1bbe7c2d53b5255f44e176a4e57f6c3a30..1169bd863a0a7a8c9a49039e4dd1a9860845cf1d:/lisp/timer.el diff --git a/lisp/timer.el b/lisp/timer.el index 68a9e105da..3131fe3c17 100644 --- a/lisp/timer.el +++ b/lisp/timer.el @@ -1,4 +1,4 @@ -;;; timer.el --- run a function with args at some time in future. +;;; timer.el --- run a function with args at some time in future ;; Copyright (C) 1996 Free Software Foundation, Inc. @@ -45,7 +45,7 @@ (defun timer-set-time (timer time &optional delta) "Set the trigger time of TIMER to TIME. TIME must be in the internal format returned by, e.g., `current-time'. -If optional third argument DELTA is a non-zero integer, make the timer +If optional third argument DELTA is a positive number, make the timer fire repeatedly that many seconds apart." (or (timerp timer) (error "Invalid timer")) @@ -116,16 +116,18 @@ SECS may be a fraction." (setq low (+ low (floor secs))) ;; Normalize - (setq low (+ low (/ micro 1000000))) + ;; `/' rounds towards zero while `mod' returns a positive number, + ;; so we can't rely on (= a (+ (* 100 (/ a 100)) (mod a 100))). + (setq low (+ low (/ micro 1000000) (if (< micro 0) -1 0))) (setq micro (mod micro 1000000)) - (setq high (+ high (/ low 65536))) + (setq high (+ high (/ low 65536) (if (< low 0) -1 0))) (setq low (logand low 65535)) (list high low (and (/= micro 0) micro)))) (defun timer-inc-time (timer secs &optional usecs) "Increment the time set in TIMER by SECS seconds and USECS microseconds. -SECS may be a fraction." +SECS may be a fraction. If USECS is omitted, that means it is zero." (let ((time (timer-relative-time (list (aref timer 1) (aref timer 2) (aref timer 3)) secs @@ -135,17 +137,21 @@ SECS may be a fraction." (aset timer 3 (or (nth 2 time) 0)))) (defun timer-set-time-with-usecs (timer time usecs &optional delta) - "Set the trigger time of TIMER to TIME. + "Set the trigger time of TIMER to TIME plus USECS. TIME must be in the internal format returned by, e.g., `current-time'. -If optional third argument DELTA is a non-zero integer, make the timer +The microsecond count from TIME is ignored, and USECS is used instead. +If optional fourth argument DELTA is a positive number, make the timer fire repeatedly that many seconds apart." (or (timerp timer) (error "Invalid timer")) - (aset timer 1 (car time)) - (aset timer 2 (if (consp (cdr time)) (car (cdr time)) (cdr time))) + (aset timer 1 (nth 0 time)) + (aset timer 2 (nth 1 time)) (aset timer 3 usecs) (aset timer 4 (and (numberp delta) (> delta 0) delta)) timer) +(make-obsolete 'timer-set-time-with-usecs + "use `timer-set-time' and `timer-inc-time' instead." + "21.4") (defun timer-set-function (timer function &optional args) "Make TIMER call FUNCTION with optional ARGS when triggering." @@ -183,8 +189,11 @@ fire repeatedly that many seconds apart." nil) (error "Invalid or uninitialized timer"))) -(defun timer-activate-when-idle (timer) - "Arrange to activate TIMER whenever Emacs is next idle." +(defun timer-activate-when-idle (timer &optional dont-wait) + "Arrange to activate TIMER whenever Emacs is next idle. +If optional argument DONT-WAIT is non-nil, then enable the +timer to activate immediately, or at the right time, if Emacs +is already idle." (if (and (timerp timer) (integerp (aref timer 1)) (integerp (aref timer 2)) @@ -206,7 +215,7 @@ fire repeatedly that many seconds apart." (if last (setcdr last (cons timer timers)) (setq timer-idle-list (cons timer timers))) - (aset timer 0 t) + (aset timer 0 (not dont-wait)) (aset timer 7 t) nil) (error "Invalid or uninitialized timer"))) @@ -264,10 +273,6 @@ This function is called, by name, directly by the C code." (progn ;; Delete from queue. (cancel-timer timer) - ;; Run handler - (condition-case nil - (apply (aref timer 5) (aref timer 6)) - (error nil)) ;; Re-schedule if requested. (if (aref timer 4) (if (aref timer 7) @@ -282,7 +287,13 @@ This function is called, by name, directly by the C code." (aref timer 4)))) (if (> repeats timer-max-repeats) (timer-inc-time timer (* (aref timer 4) repeats))))) - (timer-activate timer)))) + (timer-activate timer))) + ;; Run handler. + ;; We do this after rescheduling so that the handler function + ;; can cancel its own timer successfully with cancel-timer. + (condition-case nil + (apply (aref timer 5) (aref timer 6)) + (error nil))) (error "Bogus timer event")))) ;; This function is incompatible with the one in levents.el. @@ -368,9 +379,11 @@ This function is for compatibility; see also `run-with-timer'." ;;;###autoload (defun run-with-idle-timer (secs repeat function &rest args) "Perform an action the next time Emacs is idle for SECS seconds. -If REPEAT is non-nil, do this each time Emacs is idle for SECS seconds. -SECS may be an integer or a floating point number. The action is to call FUNCTION with arguments ARGS. +SECS may be an integer or a floating point number. + +If REPEAT is non-nil, do the action each time Emacs has been idle for +exactly SECS seconds (that is, only once for each time Emacs becomes idle). This function returns a timer object which you can use in `cancel-timer'." (interactive