Provided by: freebsd-manpages_9.2+1-1_all bug

NAME

       timeout,  untimeout,  callout_handle_init, callout_init, callout_init_mtx, callout_init_rw, callout_stop,
       callout_drain, callout_reset, callout_schedule,  callout_pending,  callout_active,  callout_deactivate  —
       execute a function after a specified length of time

SYNOPSIS

       #include <sys/types.h>
       #include <sys/systm.h>

       typedef void timeout_t (void *);

       struct callout_handle
       timeout(timeout_t *func, void *arg, int ticks);

       void
       callout_handle_init(struct callout_handle *handle);

       struct callout_handle handle = CALLOUT_HANDLE_INITIALIZER(&handle)

       void
       untimeout(timeout_t *func, void *arg, struct callout_handle handle);

       void
       callout_init(struct callout *c, int mpsafe);

       void
       callout_init_mtx(struct callout *c, struct mtx *mtx, int flags);

       void
       callout_init_rw(struct callout *c, struct rwlock *rw, int flags);

       int
       callout_stop(struct callout *c);

       int
       callout_drain(struct callout *c);

       int
       callout_reset(struct callout *c, int ticks, timeout_t *func, void *arg);

       int
       callout_schedule(struct callout *c, int ticks);

       int
       callout_pending(struct callout *c);

       int
       callout_active(struct callout *c);

       callout_deactivate(struct callout *c);

DESCRIPTION

       The  function  timeout()  schedules a call to the function given by the argument func to take place after
       ticks/hz seconds.  Non-positive values of ticks are silently converted to the value ‘1’.  func should  be
       a pointer to a function that takes a void * argument.  Upon invocation, func will receive arg as its only
       argument.   The  return  value from timeout() is a struct callout_handle which can be used in conjunction
       with the untimeout() function to request that a scheduled timeout be canceled.  The timeout() call is the
       old style and new code should use the callout_*() functions.

       The function callout_handle_init() can be used to initialize a handle to a state  which  will  cause  any
       calls to untimeout() with that handle to return with no side effects.

       Assigning  a  callout  handle  the  value  of  CALLOUT_HANDLE_INITIALIZER() performs the same function as
       callout_handle_init() and is provided for use on statically declared or global callout handles.

       The function untimeout() cancels the timeout associated with handle using the func and arg  arguments  to
       validate  the  handle.   If the handle does not correspond to a timeout with the function func taking the
       argument arg no action  is  taken.   handle  must  be  initialized  by  a  previous  call  to  timeout(),
       callout_handle_init(),  or  assigned the value of CALLOUT_HANDLE_INITIALIZER(&handle) before being passed
       to untimeout().  The behavior of calling untimeout() with an  uninitialized  handle  is  undefined.   The
       untimeout() call is the old style and new code should use the callout_*() functions.

       As  handles  are  recycled  by  the  system,  it  is  possible (although unlikely) that a handle from one
       invocation of timeout() may match the handle of another invocation of timeout() if both  calls  used  the
       same  function pointer and argument, and the first timeout is expired or canceled before the second call.
       The timeout facility offers O(1) running time for timeout() and untimeout().  Timeouts are executed  from
       softclock() with the Giant lock held.  Thus they are protected from re-entrancy.

       The  functions  callout_init(),  callout_init_mtx(),  callout_init_rw(), callout_stop(), callout_drain(),
       callout_reset() and callout_schedule() are low-level routines for clients who wish to allocate their  own
       callout structures.

       The function callout_init() initializes a callout so it can be passed to callout_stop(), callout_drain(),
       callout_reset()  or  callout_schedule()  without  any  side effects.  If the mpsafe argument is zero, the
       callout structure is not considered to be “multi-processor  safe”;  that  is,  the  Giant  lock  will  be
       acquired before calling the callout function, and released when the callout function returns.

       The  callout_init_mtx()  function  may  be  used  as an alternative to callout_init().  The parameter mtx
       specifies a mutex that is to be acquired by the callout subsystem before calling  the  callout  function,
       and released when the callout function returns.  The following flags may be specified:

       CALLOUT_RETURNUNLOCKED  The callout function will release mtx itself, so the callout subsystem should not
                               attempt to unlock it after the callout function returns.

       The  callout_init_rw()  function  serves  the  need  of  using rwlocks in conjunction with callouts.  The
       function does basically the same as callout_init_mtx() with the possibility of  specifying  an  extra  rw
       argument.  The usable lock classes are currently limited to mutexes and rwlocks, because callout handlers
       run in softclock swi, so they cannot sleep nor acquire sleepable locks like sx or lockmgr.  The following
       flags may be specified:

       CALLOUT_SHAREDLOCK  The  lock  is only acquired in read mode when running the callout handler.  It has no
                           effects when used in conjunction with mtx.

       The function callout_stop() cancels a callout if it is currently pending.  If  the  callout  is  pending,
       then  callout_stop()  will return a non-zero value.  If the callout is not set, has already been serviced
       or is currently being serviced, then zero will be returned.  If the callout has an associated mutex, then
       that mutex must be held when this function is called.

       The function callout_drain() is identical to callout_stop() except that it will wait for the  callout  to
       be  completed  if it is already in progress.  This function MUST NOT be called while holding any locks on
       which the callout might block, or deadlock will result.  Note that if the callout subsystem  has  already
       begun  processing  this  callout,  then  the  callout  function  may  be  invoked during the execution of
       callout_drain().  However, the callout subsystem does guarantee that the callout will  be  fully  stopped
       before callout_drain() returns.

       The function callout_reset() first performs the equivalent of callout_stop() to disestablish the callout,
       and  then  establishes  a  new  callout  in the same manner as timeout().  If there was already a pending
       callout and it was rescheduled, then callout_reset() will return a non-zero value.  If the callout has an
       associated  mutex,  then  that  mutex  must  be  held  when  this  function  is  called.   The   function
       callout_schedule()  (re)schedules  an  existing  callout  for  a  new period of time; it is equivalent to
       calling callout_reset() with the func and arg parameters extracted from  the  callout  structure  (though
       possibly with lower overhead).

       The  macros  callout_pending(),  callout_active()  and callout_deactivate() provide access to the current
       state of the callout.  Careful use of these macros can  avoid  many  of  the  race  conditions  that  are
       inherent in asynchronous timer facilities; see “Avoiding Race Conditions” below for further details.  The
       callout_pending()  macro  checks  whether  a  callout  is pending; a callout is considered pending when a
       timeout has been set but the time has not yet arrived.  Note that once the timeout time arrives  and  the
       callout  subsystem  starts  to  process this callout, callout_pending() will return FALSE even though the
       callout function may not have finished (or even begun)  executing.   The  callout_active()  macro  checks
       whether  a  callout  is  marked as active, and the callout_deactivate() macro clears the callout's active
       flag.  The callout subsystem marks a callout as active when a timeout is set and  it  clears  the  active
       flag  in callout_stop() and callout_drain(), but it does not clear it when a callout expires normally via
       the execution of the callout function.

   Avoiding Race Conditions
       The callout subsystem invokes callout functions from  its  own  timer  context.   Without  some  kind  of
       synchronization  it  is  possible that a callout function will be invoked concurrently with an attempt to
       stop or reset the callout by another thread.  In particular, since callout functions typically acquire  a
       mutex  as  their first action, the callout function may have already been invoked, but be blocked waiting
       for that mutex at the time that another thread tries to reset or stop the callout.

       The callout subsystem provides a number of mechanisms to address these synchronization concerns:

             1.   If the callout has an  associated  mutex  that  was  specified  using  the  callout_init_mtx()
                  function  (or  implicitly specified as the Giant mutex using callout_init() with mpsafe set to
                  FALSE), then this mutex is used to avoid the race conditions.  The associated  mutex  must  be
                  acquired  by  the caller before calling callout_stop() or callout_reset() and it is guaranteed
                  that the callout will be correctly stopped or reset  as  expected.   Note  that  it  is  still
                  necessary to use callout_drain() before destroying the callout or its associated mutex.

             2.   The  return value from callout_stop() and callout_reset() indicates whether or not the callout
                  was removed.  If it is known that the callout was set and the callout  function  has  not  yet
                  executed,  then  a  return  value  of FALSE indicates that the callout function is about to be
                  called.  For example:

                        if (sc->sc_flags & SCFLG_CALLOUT_RUNNING) {
                                if (callout_stop(&sc->sc_callout)) {
                                        sc->sc_flags &= ~SCFLG_CALLOUT_RUNNING;
                                        /* successfully stopped */
                                } else {
                                        /*
                                         * callout has expired and callout
                                         * function is about to be executed
                                         */
                                }
                        }

             3.   The callout_pending(), callout_active() and callout_deactivate() macros can be  used  together
                  to  work  around  the race conditions.  When a callout's timeout is set, the callout subsystem
                  marks the callout as both active and pending.  When the  timeout  time  arrives,  the  callout
                  subsystem  begins  processing the callout by first clearing the pending flag.  It then invokes
                  the callout function without changing the active flag, and does not clear the active flag even
                  after the callout function  returns.   The  mechanism  described  here  requires  the  callout
                  function  itself  to  clear  the  active  flag  using  the  callout_deactivate()  macro.   The
                  callout_stop() and callout_drain() functions always clear both the active  and  pending  flags
                  before returning.

                  The  callout  function  should  first  check  the  pending  flag  and return without action if
                  callout_pending() returns TRUE.   This  indicates  that  the  callout  was  rescheduled  using
                  callout_reset()  just  before  the  callout function was invoked.  If callout_active() returns
                  FALSE then the callout function should also return without action.  This  indicates  that  the
                  callout  has  been stopped.  Finally, the callout function should call callout_deactivate() to
                  clear the active flag.  For example:

                        mtx_lock(&sc->sc_mtx);
                        if (callout_pending(&sc->sc_callout)) {
                                /* callout was reset */
                                mtx_unlock(&sc->sc_mtx);
                                return;
                        }
                        if (!callout_active(&sc->sc_callout)) {
                                /* callout was stopped */
                                mtx_unlock(&sc->sc_mtx);
                                return;
                        }
                        callout_deactivate(&sc->sc_callout);
                        /* rest of callout function */

                  Together with appropriate synchronization, such as the mutex used above, this approach permits
                  the callout_stop() and callout_reset() functions to be used at any time  without  races.   For
                  example:

                        mtx_lock(&sc->sc_mtx);
                        callout_stop(&sc->sc_callout);
                        /* The callout is effectively stopped now. */

                  If  the  callout  is still pending then these functions operate normally, but if processing of
                  the callout has already begun then the tests in  the  callout  function  cause  it  to  return
                  without  further  action.  Synchronization between the callout function and other code ensures
                  that stopping or resetting the callout will never be attempted while the callout  function  is
                  past the callout_deactivate() call.

                  The  above  technique  additionally  ensures  that the active flag always reflects whether the
                  callout is effectively enabled or disabled.   If  callout_active()  returns  false,  then  the
                  callout is effectively disabled, since even if the callout subsystem is actually just about to
                  invoke the callout function, the callout function will return without action.

       There  is  one  final race condition that must be considered when a callout is being stopped for the last
       time.  In this case it may not be safe to let the callout function itself detect  that  the  callout  was
       stopped,  since  it  may  need  to  access data objects that have already been destroyed or recycled.  To
       ensure that the callout is completely finished, a call to callout_drain() should be used.

RETURN VALUES

       The timeout() function  returns  a  struct  callout_handle  that  can  be  passed  to  untimeout().   The
       callout_stop() and callout_drain() functions return non-zero if the callout was still pending when it was
       called or zero otherwise.

HISTORY

       The current timeout and untimeout routines are based on the work of Adam M. Costello and George Varghese,
       published  in  a  technical report entitled Redesigning the BSD Callout and Timer Facilities and modified
       slightly for inclusion in FreeBSD by Justin T. Gibbs.  The original work on the data structures  used  in
       this implementation was published by G. Varghese and A. Lauck in the paper Hashed and Hierarchical Timing
       Wheels:  Data  Structures  for the Efficient Implementation of a Timer Facility in the Proceedings of the
       11th ACM Annual Symposium on Operating Systems Principles.  The current implementation replaces the  long
       standing  BSD linked list callout mechanism which offered O(n) insertion and removal running time but did
       not generate or require handles for untimeout operations.

Debian                                           August 2, 2008                                       TIMEOUT(9)