@c Generated by the sb-manual contrib. Do not edit.

@node timers
@chapter Timers

SBCL supports a system-wide event scheduler implemented on top of
@code{setitimer(2)} that also works with threads but does not require a
separate scheduler thread.

The following example schedules a timer that writes @code{Hello, world}
after two seconds.

@example
(schedule-timer (make-timer (lambda ()
                              (write-line "Hello, world")
                              (force-output)))
                2)
@end example

It should be noted that writing timer functions requires special
care, as the dynamic environment in which they run is unpredictable:
dynamic variable bindings, locks held, etc, all depend on whatever
code was running when the timer fired. The following example should
serve as a cautionary tale:

@example
(defvar *foo* nil)

(defun show-foo ()
  (format t "~&foo=~S~%" *foo*)
  (force-output t))

(defun demo ()
  (schedule-timer (make-timer #'show-foo) 0.5)
  (schedule-timer (make-timer #'show-foo) 1.5)
  (let ((*foo* t))
    (sleep 1.0))
  (let ((*foo* :surprise!))
    (sleep 2.0)))
@end example

@anchor{Structure sb-ext timer}
@ttindex @sortas{timer sb-ext} timer [sb-ext]
@deffn{Structure} sb-ext:timer
Timer type. Do not rely on timers being structs as it may change in
future versions.
@end deffn
@anchor{Function sb-ext make-timer}
@ffindex @sortas{make-timer sb-ext} make-timer [sb-ext]
@deffn{Function} sb-ext:make-timer function &key name thread
Create a timer that runs @code{function} when triggered.

If a @code{thread} is supplied, @code{function} is run in that thread. If @code{thread} is
@code{t}, a new thread is created for @code{function} each time the timer is
triggered. If @code{thread} is @code{nil}, @code{function} is run in an unspecified thread.

When @code{thread} is not @code{t}, @code{sb-thread:interrupt-thread} is used to run
@code{function} and the ordering guarantees of @code{sb-thread:interrupt-thread}
apply. In that case, @code{function} runs with interrupts disabled but
@code{with-interrupts} is allowed.
@end deffn
@anchor{Function sb-ext timer-name}
@ffindex @sortas{timer-name sb-ext} timer-name [sb-ext]
@deffn{Function} sb-ext:timer-name timer
Return the name of @code{timer}.
@end deffn
@anchor{Function sb-ext timer-scheduled-p}
@ffindex @sortas{timer-scheduled-p sb-ext} timer-scheduled-p [sb-ext]
@deffn{Function} sb-ext:timer-scheduled-p timer &key delta
See if @code{timer} will still need to be triggered after @code{delta} seconds
from now. For timers with a repeat interval it returns true.
@end deffn
@anchor{Function sb-ext schedule-timer}
@ffindex @sortas{schedule-timer sb-ext} schedule-timer [sb-ext]
@deffn{Function} sb-ext:schedule-timer timer time &key repeat-interval absolute-p catch-up
Schedule @code{timer} to be triggered at @code{time}. If @code{absolute-p} then @code{time} is
universal time, but non-integral values are also allowed, else @code{time} is
measured as the number of seconds from the current time.

If @code{repeat-interval} is given, @code{timer} is automatically rescheduled upon
expiry.

If @code{repeat-interval} is non-@code{nil}, the Boolean @code{catch-up} controls whether
@code{timer} will "catch up" by repeatedly calling its function without
delay in case calls are missed because of a clock discontinuity such
as a suspend and resume cycle of the computer. The default is @code{nil},
i.e. do not catch up.
@end deffn
@anchor{Function sb-ext unschedule-timer}
@ffindex @sortas{unschedule-timer sb-ext} unschedule-timer [sb-ext]
@deffn{Function} sb-ext:unschedule-timer timer
Cancel @code{timer}. Once this function returns it is guaranteed that
@code{timer} shall not be triggered again and there are no unfinished
triggers.
@end deffn
@anchor{Function sb-ext list-all-timers}
@ffindex @sortas{list-all-timers sb-ext} list-all-timers [sb-ext]
@deffn{Function} sb-ext:list-all-timers
Return a list of all timers in the system.
@end deffn
