timer.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004-2009, 2012-2014  Internet Systems Consortium, Inc. ("ISC")
00003  * Copyright (C) 1998-2002  Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and/or distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00010  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00011  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00012  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00013  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00014  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00015  * PERFORMANCE OF THIS SOFTWARE.
00016  */
00017 
00018 /* $Id: timer.h,v 1.43 2009/09/02 23:48:03 tbox Exp $ */
00019 
00020 #ifndef ISC_TIMER_H
00021 #define ISC_TIMER_H 1
00022 
00023 /*****
00024  ***** Module Info
00025  *****/
00026 
00027 /*! \file isc/timer.h
00028  * \brief Provides timers which are event sources in the task system.
00029  *
00030  * Three types of timers are supported:
00031  *
00032  *\li   'ticker' timers generate a periodic tick event.
00033  *
00034  *\li   'once' timers generate an idle timeout event if they are idle for too
00035  *      long, and generate a life timeout event if their lifetime expires.
00036  *      They are used to implement both (possibly expiring) idle timers and
00037  *      'one-shot' timers.
00038  *
00039  *\li   'limited' timers generate a periodic tick event until they reach
00040  *      their lifetime when they generate a life timeout event.
00041  *
00042  *\li   'inactive' timers generate no events.
00043  *
00044  * Timers can change type.  It is typical to create a timer as
00045  * an 'inactive' timer and then change it into a 'ticker' or
00046  * 'once' timer.
00047  *
00048  *\li MP:
00049  *      The module ensures appropriate synchronization of data structures it
00050  *      creates and manipulates.
00051  *      Clients of this module must not be holding a timer's task's lock when
00052  *      making a call that affects that timer.  Failure to follow this rule
00053  *      can result in deadlock.
00054  *      The caller must ensure that isc_timermgr_destroy() is called only
00055  *      once for a given manager.
00056  *
00057  * \li Reliability:
00058  *      No anticipated impact.
00059  *
00060  * \li Resources:
00061  *      TBS
00062  *
00063  * \li Security:
00064  *      No anticipated impact.
00065  *
00066  * \li Standards:
00067  *      None.
00068  */
00069 
00070 
00071 /***
00072  *** Imports
00073  ***/
00074 
00075 #include <isc/types.h>
00076 #include <isc/event.h>
00077 #include <isc/eventclass.h>
00078 #include <isc/lang.h>
00079 #include <isc/time.h>
00080 
00081 ISC_LANG_BEGINDECLS
00082 
00083 /***
00084  *** Types
00085  ***/
00086 
00087 /*% Timer Type */
00088 typedef enum {
00089         isc_timertype_undefined = -1,   /*%< Undefined */
00090         isc_timertype_ticker = 0,       /*%< Ticker */
00091         isc_timertype_once = 1,         /*%< Once */
00092         isc_timertype_limited = 2,      /*%< Limited */
00093         isc_timertype_inactive = 3      /*%< Inactive */
00094 } isc_timertype_t;
00095 
00096 typedef struct isc_timerevent {
00097         struct isc_event        common;
00098         isc_time_t              due;
00099 } isc_timerevent_t;
00100 
00101 #define ISC_TIMEREVENT_FIRSTEVENT       (ISC_EVENTCLASS_TIMER + 0)
00102 #define ISC_TIMEREVENT_TICK             (ISC_EVENTCLASS_TIMER + 1)
00103 #define ISC_TIMEREVENT_IDLE             (ISC_EVENTCLASS_TIMER + 2)
00104 #define ISC_TIMEREVENT_LIFE             (ISC_EVENTCLASS_TIMER + 3)
00105 #define ISC_TIMEREVENT_LASTEVENT        (ISC_EVENTCLASS_TIMER + 65535)
00106 
00107 /*% Timer and timer manager methods */
00108 typedef struct {
00109         void            (*destroy)(isc_timermgr_t **managerp);
00110         isc_result_t    (*timercreate)(isc_timermgr_t *manager,
00111                                        isc_timertype_t type,
00112                                        const isc_time_t *expires,
00113                                        const isc_interval_t *interval,
00114                                        isc_task_t *task,
00115                                        isc_taskaction_t action,
00116                                        void *arg,
00117                                        isc_timer_t **timerp);
00118 } isc_timermgrmethods_t;
00119 
00120 typedef struct {
00121         void            (*attach)(isc_timer_t *timer, isc_timer_t **timerp);
00122         void            (*detach)(isc_timer_t **timerp);
00123         isc_result_t    (*reset)(isc_timer_t *timer, isc_timertype_t type,
00124                                  const isc_time_t *expires,
00125                                  const isc_interval_t *interval,
00126                                  isc_boolean_t purge);
00127         isc_result_t    (*touch)(isc_timer_t *timer);
00128 } isc_timermethods_t;
00129 
00130 /*%
00131  * This structure is actually just the common prefix of a timer manager
00132  * object implementation's version of an isc_timermgr_t.
00133  * \brief
00134  * Direct use of this structure by clients is forbidden.  timer implementations
00135  * may change the structure.  'magic' must be ISCAPI_TIMERMGR_MAGIC for any
00136  * of the isc_timer_ routines to work.  timer implementations must maintain
00137  * all timer invariants.
00138  */
00139 struct isc_timermgr {
00140         unsigned int            impmagic;
00141         unsigned int            magic;
00142         isc_timermgrmethods_t   *methods;
00143 };
00144 
00145 #define ISCAPI_TIMERMGR_MAGIC           ISC_MAGIC('A','t','m','g')
00146 #define ISCAPI_TIMERMGR_VALID(m)        ((m) != NULL && \
00147                                          (m)->magic == ISCAPI_TIMERMGR_MAGIC)
00148 
00149 /*%
00150  * This is the common prefix of a timer object.  The same note as
00151  * that for the timermgr structure applies.
00152  */
00153 struct isc_timer {
00154         unsigned int            impmagic;
00155         unsigned int            magic;
00156         isc_timermethods_t      *methods;
00157 };
00158 
00159 #define ISCAPI_TIMER_MAGIC      ISC_MAGIC('A','t','m','r')
00160 #define ISCAPI_TIMER_VALID(s)   ((s) != NULL && \
00161                                  (s)->magic == ISCAPI_TIMER_MAGIC)
00162 
00163 /***
00164  *** Timer and Timer Manager Functions
00165  ***
00166  *** Note: all Ensures conditions apply only if the result is success for
00167  *** those functions which return an isc_result_t.
00168  ***/
00169 
00170 isc_result_t
00171 isc_timer_create(isc_timermgr_t *manager,
00172                  isc_timertype_t type,
00173                  const isc_time_t *expires,
00174                  const isc_interval_t *interval,
00175                  isc_task_t *task,
00176                  isc_taskaction_t action,
00177                  void *arg,
00178                  isc_timer_t **timerp);
00179 /*%<
00180  * Create a new 'type' timer managed by 'manager'.  The timers parameters
00181  * are specified by 'expires' and 'interval'.  Events will be posted to
00182  * 'task' and when dispatched 'action' will be called with 'arg' as the
00183  * arg value.  The new timer is returned in 'timerp'.
00184  *
00185  * Notes:
00186  *
00187  *\li   For ticker timers, the timer will generate a 'tick' event every
00188  *      'interval' seconds.  The value of 'expires' is ignored.
00189  *
00190  *\li   For once timers, 'expires' specifies the time when a life timeout
00191  *      event should be generated.  If 'expires' is 0 (the epoch), then no life
00192  *      timeout will be generated.  'interval' specifies how long the timer
00193  *      can be idle before it generates an idle timeout.  If 0, then no
00194  *      idle timeout will be generated.
00195  *
00196  *\li   If 'expires' is NULL, the epoch will be used.
00197  *
00198  *      If 'interval' is NULL, the zero interval will be used.
00199  *
00200  * Requires:
00201  *
00202  *\li   'manager' is a valid manager
00203  *
00204  *\li   'task' is a valid task
00205  *
00206  *\li   'action' is a valid action
00207  *
00208  *\li   'expires' points to a valid time, or is NULL.
00209  *
00210  *\li   'interval' points to a valid interval, or is NULL.
00211  *
00212  *\li   type == isc_timertype_inactive ||
00213  *      ('expires' and 'interval' are not both 0)
00214  *
00215  *\li   'timerp' is a valid pointer, and *timerp == NULL
00216  *
00217  * Ensures:
00218  *
00219  *\li   '*timerp' is attached to the newly created timer
00220  *
00221  *\li   The timer is attached to the task
00222  *
00223  *\li   An idle timeout will not be generated until at least Now + the
00224  *      timer's interval if 'timer' is a once timer with a non-zero
00225  *      interval.
00226  *
00227  * Returns:
00228  *
00229  *\li   Success
00230  *\li   No memory
00231  *\li   Unexpected error
00232  */
00233 
00234 isc_result_t
00235 isc_timer_reset(isc_timer_t *timer,
00236                 isc_timertype_t type,
00237                 const isc_time_t *expires,
00238                 const isc_interval_t *interval,
00239                 isc_boolean_t purge);
00240 /*%<
00241  * Change the timer's type, expires, and interval values to the given
00242  * values.  If 'purge' is TRUE, any pending events from this timer
00243  * are purged from its task's event queue.
00244  *
00245  * Notes:
00246  *
00247  *\li   If 'expires' is NULL, the epoch will be used.
00248  *
00249  *\li   If 'interval' is NULL, the zero interval will be used.
00250  *
00251  * Requires:
00252  *
00253  *\li   'timer' is a valid timer
00254  *
00255  *\li   The same requirements that isc_timer_create() imposes on 'type',
00256  *      'expires' and 'interval' apply.
00257  *
00258  * Ensures:
00259  *
00260  *\li   An idle timeout will not be generated until at least Now + the
00261  *      timer's interval if 'timer' is a once timer with a non-zero
00262  *      interval.
00263  *
00264  * Returns:
00265  *
00266  *\li   Success
00267  *\li   No memory
00268  *\li   Unexpected error
00269  */
00270 
00271 isc_result_t
00272 isc_timer_touch(isc_timer_t *timer);
00273 /*%<
00274  * Set the last-touched time of 'timer' to the current time.
00275  *
00276  * Requires:
00277  *
00278  *\li   'timer' is a valid once timer.
00279  *
00280  * Ensures:
00281  *
00282  *\li   An idle timeout will not be generated until at least Now + the
00283  *      timer's interval if 'timer' is a once timer with a non-zero
00284  *      interval.
00285  *
00286  * Returns:
00287  *
00288  *\li   Success
00289  *\li   Unexpected error
00290  */
00291 
00292 void
00293 isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp);
00294 /*%<
00295  * Attach *timerp to timer.
00296  *
00297  * Requires:
00298  *
00299  *\li   'timer' is a valid timer.
00300  *
00301  *\li   'timerp' points to a NULL timer.
00302  *
00303  * Ensures:
00304  *
00305  *\li   *timerp is attached to timer.
00306  */
00307 
00308 void
00309 isc_timer_detach(isc_timer_t **timerp);
00310 /*%<
00311  * Detach *timerp from its timer.
00312  *
00313  * Requires:
00314  *
00315  *\li   'timerp' points to a valid timer.
00316  *
00317  * Ensures:
00318  *
00319  *\li   *timerp is NULL.
00320  *
00321  *\li   If '*timerp' is the last reference to the timer,
00322  *      then:
00323  *
00324  *\code
00325  *              The timer will be shutdown
00326  *
00327  *              The timer will detach from its task
00328  *
00329  *              All resources used by the timer have been freed
00330  *
00331  *              Any events already posted by the timer will be purged.
00332  *              Therefore, if isc_timer_detach() is called in the context
00333  *              of the timer's task, it is guaranteed that no more
00334  *              timer event callbacks will run after the call.
00335  *\endcode
00336  */
00337 
00338 isc_timertype_t
00339 isc_timer_gettype(isc_timer_t *timer);
00340 /*%<
00341  * Return the timer type.
00342  *
00343  * Requires:
00344  *
00345  *\li   'timer' to be a valid timer.
00346  */
00347 
00348 isc_result_t
00349 isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
00350                          isc_timermgr_t **managerp);
00351 
00352 isc_result_t
00353 isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
00354 /*%<
00355  * Create a timer manager.  isc_timermgr_createinctx() also associates
00356  * the new manager with the specified application context.
00357  *
00358  * Notes:
00359  *
00360  *\li   All memory will be allocated in memory context 'mctx'.
00361  *
00362  * Requires:
00363  *
00364  *\li   'mctx' is a valid memory context.
00365  *
00366  *\li   'managerp' points to a NULL isc_timermgr_t.
00367  *
00368  *\li   'actx' is a valid application context (for createinctx()).
00369  *
00370  * Ensures:
00371  *
00372  *\li   '*managerp' is a valid isc_timermgr_t.
00373  *
00374  * Returns:
00375  *
00376  *\li   Success
00377  *\li   No memory
00378  *\li   Unexpected error
00379  */
00380 
00381 void
00382 isc_timermgr_destroy(isc_timermgr_t **managerp);
00383 /*%<
00384  * Destroy a timer manager.
00385  *
00386  * Notes:
00387  *
00388  *\li   This routine blocks until there are no timers left in the manager,
00389  *      so if the caller holds any timer references using the manager, it
00390  *      must detach them before calling isc_timermgr_destroy() or it will
00391  *      block forever.
00392  *
00393  * Requires:
00394  *
00395  *\li   '*managerp' is a valid isc_timermgr_t.
00396  *
00397  * Ensures:
00398  *
00399  *\li   *managerp == NULL
00400  *
00401  *\li   All resources used by the manager have been freed.
00402  */
00403 
00404 void isc_timermgr_poke(isc_timermgr_t *m);
00405 
00406 /*%<
00407  * See isc_timermgr_create() above.
00408  */
00409 typedef isc_result_t
00410 (*isc_timermgrcreatefunc_t)(isc_mem_t *mctx, isc_timermgr_t **managerp);
00411 
00412 isc_result_t
00413 isc__timer_register(void);
00414 /*%<
00415  * Register a new timer management implementation and add it to the list of
00416  * supported implementations.  This function must be called when a different
00417  * event library is used than the one contained in the ISC library.
00418  */
00419 
00420 isc_result_t
00421 isc_timer_register(isc_timermgrcreatefunc_t createfunc);
00422 /*%<
00423  * A short cut function that specifies the timer management module in the ISC
00424  * library for isc_timer_register().  An application that uses the ISC library
00425  * usually do not have to care about this function: it would call
00426  * isc_lib_register(), which internally calls this function.
00427  */
00428 
00429 ISC_LANG_ENDDECLS
00430 
00431 #endif /* ISC_TIMER_H */

Generated on Tue Apr 28 17:41:04 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha