.\" Copyright (c) 2004-2009 Hypertriton, Inc.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
.\" (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd May 9, 2004
.Dt AG_TIMEOUT 3
.Os
.ds vT Agar API Reference
.ds oS Agar 1.0
.Sh NAME
.Nm AG_Timeout
.Nd agar timer facility
.Sh SYNOPSIS
.Bd -literal
#include
.Ed
.Sh DESCRIPTION
The agar
.Nm
subsystem manages the scheduling and execution of specific callback functions
at specific points in real-time or simulated real-time.
A callback function has the prototype:
.Pp
.nr nS 1
.\" NOMANLINK
.Ft "Uint32"
.Fn fn "void *obj" "Uint32 ival" "void *arg"
.Pp
.nr nS 0
Where
.Fa obj
is a pointer to the object managing the timeout (or NULL),
.Fa ival
is the delay in ticks before the next invocation, and
.Fa arg
is the user-supplied pointer passed to
.Fn AG_ScheduleTimeout .
If the callback function returns a non-zero value, the timeout is automatically
rescheduled to occur in t+n ticks.
.Pp
Note that the object remains locked throughout the execution of
.Fn fn
(see
.Xr AG_ObjectLock 3 ) .
.Pp
Note that
.Nm
is used internally to implement
.Xr AG_SchedEvent 3 ,
which is an alternative interface to the one described here.
.Sh INTERFACE
.nr nS 1
.Ft "void"
.Fn AG_SetTimeout "AG_Timeout *to" "Uint32 (*fn)(void *obj, Uint32 ival, void *arg)" "void *arg, int flags"
.Pp
.Ft "void"
.Fn AG_ScheduleTimeout "void *obj" "AG_Timeout *to" "Uint32 ival"
.Pp
.Ft "void"
.Fn AG_DelTimeout "void *obj" "AG_Timeout *to"
.Pp
.Ft "int"
.Fn AG_TimeoutIsScheduled "void *obj" "AG_Timeout *to"
.Pp
.Ft "void"
.Fn AG_LockTimeouts "void *obj"
.Pp
.Ft "void"
.Fn AG_UnlockTimeouts "void *obj"
.Pp
.nr nS 0
The
.Fn AG_SetTimeout
function initializes a pre-allocated
.Nm
structure using the specified callback function and argument.
.Pp
The
.Fa flags
may contain:
.Pp
.Bl -tag -width "AG_CANCEL_ONDETACH "
.It AG_CANCEL_ONDETACH
In
.Fn AG_ObjectDetach ,
cancel any scheduled execution of the callback function.
.It AG_CANCEL_ONLOAD
In
.Fn AG_ObjectLoad ,
cancel any scheduled execution of the callback function.
.El
.Pp
The
.Fn AG_ScheduleTimeout
function schedules (or reschedules) the previously configured callback
function for execution in t+ival ticks.
The
.Fa obj
argument specifies the
.Xr AG_Object 3
which is responsible for the scheduling and execution of the given callback
function.
.Pp
Different types of objects may implement different timing schemes involving
either real-time or simulated real-time.
If the
.Fa obj
argument is NULL, the callback is associated with a global "timer manager"
object which uses the default timing algorithm.
.Pp
With the default (real-time) timing algorithm, a
.Dq tick
is considered equivalent to roughly 1 millisecond.
Different timing schemes can assign different meanings to a "tick".
The
.Nm
interface remains consistent across different timing schemes.
.Pp
The
.Fn AG_DelTimeout
function removes the given timeout from the queue if it is currently scheduled
for execution.
It is not necessary to invoke
.Fn AG_DelTimeout
before
.Fn AG_SchedTimeout
when re-scheduling an event.
.Pp
.Fn AG_TimeoutIsScheduled
returns 1 if the given timeout is currently scheduled for execution.
The timeouts must have been locked by the caller of the function (see
below).
.Pp
Both
.Fn AG_ScheduleTimeout
and
.Fn AG_DelTimeout
may be invoked safely from callback functions, but it is more efficient to use
the callback's return value for rescheduling or cancelling timeouts.
.Pp
The
.Fn AG_TimeoutIsScheduled
function returns 1 if the given timeout is scheduled for execution, otherwise
it returns 0.
.Pp
The
.Nm
interface is thread-safe, but it is important to use
.Fn AG_LockTimeouts
and
.Fn AG_UnlockTimeouts
in constructions such as:
.Pp
.Bd -literal
AG_LockTimeouts(obj);
if (AG_TimeoutIsScheduled(obj, &timeout)) {
AG_DelTimeout(obj, &timeout);
}
AG_UnlockTimeouts(obj);
.Ed
.Sh CANCELLATION
Whenever an
.Xr AG_Object 3
controlling timeouts is about to be detached,
.Fn AG_ObjectDetach
cancels any scheduled timeout that has the
.Dv AG_CANCEL_ONDETACH
flag set.
.Pp
Similarly,
.Fn AG_ObjectLoad
cancels scheduled timeouts with the
.Dv AG_CANCEL_ONLOAD
flag.
.Pp
.Fn AG_ObjectDestroy
always cancels all scheduled timeouts.
.Pp
With a multithreaded timing scheme, cancelling a timeout might imply waiting
for the termination of a thread (possibly sending it a signal as well).
.Sh ADVANCING TIME
.nr nS 1
.Ft "int"
.Fn AG_TIMEOUTS_QUEUED "void"
.Pp
.Ft "void"
.Fn AG_ProcessTimeouts "Uint32 ticks"
.Pp
.nr nS 0
The
.Fn AG_TIMEOUTS_QUEUED
macro evaluates to 1 if there are possibly timeouts that need to be processed.
.Pp
The
.Fn AG_ProcessTimeouts
function advances the timing wheel and executes the callback functions of
expired timeouts.
The
.Fa ticks
argument is the current time in milliseconds (usually obtained from
.Xr AG_GetTicks 3 ) .
This function intended to be invoked from an event loop function such as
.Xr AG_EventLoop 3 ,
in the following way:
.Bd -literal
if (AG_TIMEOUTS_QUEUED())
AG_ProcessTimeouts(AG_GetTicks());
.Ed
.Sh SEE ALSO
.Xr AG_Intro 3 ,
.Xr AG_Event 3 ,
.Xr AG_Object 3 ,
.Xr AG_GetTicks 3
.Rs
.%T "Hashed and Hierarchical Timing Wheels: Efficient Data Structures for Implementing a Timer Facility"
.%A "George Varghese"
.%A "Tony Lauck"
.%D "February 14, 1996"
.Re
.Sh HISTORY
The
.Nm
facility first appeared in Agar 1.0.
The interface was modeled after the OpenBSD
.Xr timeout 9
API designed by Artur Grabowski and Thomas Nordin.
Implementation uses the algorithms presented by George Varghese and Tony Lauck.