1/* 2 * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1998-2002 Internet Software Consortium. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18/* $Id: timer.h,v 1.40 2008/06/23 23:47:11 tbox Exp $ */ 19 20#ifndef ISC_TIMER_H 21#define ISC_TIMER_H 1 22 23/***** 24 ***** Module Info 25 *****/ 26 27/*! \file isc/timer.h 28 * \brief Provides timers which are event sources in the task system. 29 * 30 * Three types of timers are supported: 31 * 32 *\li 'ticker' timers generate a periodic tick event. 33 * 34 *\li 'once' timers generate an idle timeout event if they are idle for too 35 * long, and generate a life timeout event if their lifetime expires. 36 * They are used to implement both (possibly expiring) idle timers and 37 * 'one-shot' timers. 38 * 39 *\li 'limited' timers generate a periodic tick event until they reach 40 * their lifetime when they generate a life timeout event. 41 * 42 *\li 'inactive' timers generate no events. 43 * 44 * Timers can change type. It is typical to create a timer as 45 * an 'inactive' timer and then change it into a 'ticker' or 46 * 'once' timer. 47 * 48 *\li MP: 49 * The module ensures appropriate synchronization of data structures it 50 * creates and manipulates. 51 * Clients of this module must not be holding a timer's task's lock when 52 * making a call that affects that timer. Failure to follow this rule 53 * can result in deadlock. 54 * The caller must ensure that isc_timermgr_destroy() is called only 55 * once for a given manager. 56 * 57 * \li Reliability: 58 * No anticipated impact. 59 * 60 * \li Resources: 61 * TBS 62 * 63 * \li Security: 64 * No anticipated impact. 65 * 66 * \li Standards: 67 * None. 68 */ 69 70 71/*** 72 *** Imports 73 ***/ 74 75#include <isc/types.h> 76#include <isc/event.h> 77#include <isc/eventclass.h> 78#include <isc/lang.h> 79#include <isc/time.h> 80 81ISC_LANG_BEGINDECLS 82 83/*** 84 *** Types 85 ***/ 86 87/*% Timer Type */ 88typedef enum { 89 isc_timertype_ticker = 0, /*%< Ticker */ 90 isc_timertype_once = 1, /*%< Once */ 91 isc_timertype_limited = 2, /*%< Limited */ 92 isc_timertype_inactive = 3 /*%< Inactive */ 93} isc_timertype_t; 94 95typedef struct isc_timerevent { 96 struct isc_event common; 97 isc_time_t due; 98} isc_timerevent_t; 99 100#define ISC_TIMEREVENT_FIRSTEVENT (ISC_EVENTCLASS_TIMER + 0) 101#define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 1) 102#define ISC_TIMEREVENT_IDLE (ISC_EVENTCLASS_TIMER + 2) 103#define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3) 104#define ISC_TIMEREVENT_LASTEVENT (ISC_EVENTCLASS_TIMER + 65535) 105 106/*** 107 *** Timer and Timer Manager Functions 108 *** 109 *** Note: all Ensures conditions apply only if the result is success for 110 *** those functions which return an isc_result_t. 111 ***/ 112 113isc_result_t 114isc_timer_create(isc_timermgr_t *manager, 115 isc_timertype_t type, 116 isc_time_t *expires, 117 isc_interval_t *interval, 118 isc_task_t *task, 119 isc_taskaction_t action, 120 const void *arg, 121 isc_timer_t **timerp); 122/*%< 123 * Create a new 'type' timer managed by 'manager'. The timers parameters 124 * are specified by 'expires' and 'interval'. Events will be posted to 125 * 'task' and when dispatched 'action' will be called with 'arg' as the 126 * arg value. The new timer is returned in 'timerp'. 127 * 128 * Notes: 129 * 130 *\li For ticker timers, the timer will generate a 'tick' event every 131 * 'interval' seconds. The value of 'expires' is ignored. 132 * 133 *\li For once timers, 'expires' specifies the time when a life timeout 134 * event should be generated. If 'expires' is 0 (the epoch), then no life 135 * timeout will be generated. 'interval' specifies how long the timer 136 * can be idle before it generates an idle timeout. If 0, then no 137 * idle timeout will be generated. 138 * 139 *\li If 'expires' is NULL, the epoch will be used. 140 * 141 * If 'interval' is NULL, the zero interval will be used. 142 * 143 * Requires: 144 * 145 *\li 'manager' is a valid manager 146 * 147 *\li 'task' is a valid task 148 * 149 *\li 'action' is a valid action 150 * 151 *\li 'expires' points to a valid time, or is NULL. 152 * 153 *\li 'interval' points to a valid interval, or is NULL. 154 * 155 *\li type == isc_timertype_inactive || 156 * ('expires' and 'interval' are not both 0) 157 * 158 *\li 'timerp' is a valid pointer, and *timerp == NULL 159 * 160 * Ensures: 161 * 162 *\li '*timerp' is attached to the newly created timer 163 * 164 *\li The timer is attached to the task 165 * 166 *\li An idle timeout will not be generated until at least Now + the 167 * timer's interval if 'timer' is a once timer with a non-zero 168 * interval. 169 * 170 * Returns: 171 * 172 *\li Success 173 *\li No memory 174 *\li Unexpected error 175 */ 176 177isc_result_t 178isc_timer_reset(isc_timer_t *timer, 179 isc_timertype_t type, 180 isc_time_t *expires, 181 isc_interval_t *interval, 182 isc_boolean_t purge); 183/*%< 184 * Change the timer's type, expires, and interval values to the given 185 * values. If 'purge' is TRUE, any pending events from this timer 186 * are purged from its task's event queue. 187 * 188 * Notes: 189 * 190 *\li If 'expires' is NULL, the epoch will be used. 191 * 192 *\li If 'interval' is NULL, the zero interval will be used. 193 * 194 * Requires: 195 * 196 *\li 'timer' is a valid timer 197 * 198 *\li The same requirements that isc_timer_create() imposes on 'type', 199 * 'expires' and 'interval' apply. 200 * 201 * Ensures: 202 * 203 *\li An idle timeout will not be generated until at least Now + the 204 * timer's interval if 'timer' is a once timer with a non-zero 205 * interval. 206 * 207 * Returns: 208 * 209 *\li Success 210 *\li No memory 211 *\li Unexpected error 212 */ 213 214isc_result_t 215isc_timer_touch(isc_timer_t *timer); 216/*%< 217 * Set the last-touched time of 'timer' to the current time. 218 * 219 * Requires: 220 * 221 *\li 'timer' is a valid once timer. 222 * 223 * Ensures: 224 * 225 *\li An idle timeout will not be generated until at least Now + the 226 * timer's interval if 'timer' is a once timer with a non-zero 227 * interval. 228 * 229 * Returns: 230 * 231 *\li Success 232 *\li Unexpected error 233 */ 234 235void 236isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp); 237/*%< 238 * Attach *timerp to timer. 239 * 240 * Requires: 241 * 242 *\li 'timer' is a valid timer. 243 * 244 *\li 'timerp' points to a NULL timer. 245 * 246 * Ensures: 247 * 248 *\li *timerp is attached to timer. 249 */ 250 251void 252isc_timer_detach(isc_timer_t **timerp); 253/*%< 254 * Detach *timerp from its timer. 255 * 256 * Requires: 257 * 258 *\li 'timerp' points to a valid timer. 259 * 260 * Ensures: 261 * 262 *\li *timerp is NULL. 263 * 264 *\li If '*timerp' is the last reference to the timer, 265 * then: 266 * 267 *\code 268 * The timer will be shutdown 269 * 270 * The timer will detach from its task 271 * 272 * All resources used by the timer have been freed 273 * 274 * Any events already posted by the timer will be purged. 275 * Therefore, if isc_timer_detach() is called in the context 276 * of the timer's task, it is guaranteed that no more 277 * timer event callbacks will run after the call. 278 *\endcode 279 */ 280 281isc_timertype_t 282isc_timer_gettype(isc_timer_t *timer); 283/*%< 284 * Return the timer type. 285 * 286 * Requires: 287 * 288 *\li 'timer' to be a valid timer. 289 */ 290 291isc_result_t 292isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp); 293/*%< 294 * Create a timer manager. 295 * 296 * Notes: 297 * 298 *\li All memory will be allocated in memory context 'mctx'. 299 * 300 * Requires: 301 * 302 *\li 'mctx' is a valid memory context. 303 * 304 *\li 'managerp' points to a NULL isc_timermgr_t. 305 * 306 * Ensures: 307 * 308 *\li '*managerp' is a valid isc_timermgr_t. 309 * 310 * Returns: 311 * 312 *\li Success 313 *\li No memory 314 *\li Unexpected error 315 */ 316 317void 318isc_timermgr_destroy(isc_timermgr_t **managerp); 319/*%< 320 * Destroy a timer manager. 321 * 322 * Notes: 323 * 324 *\li This routine blocks until there are no timers left in the manager, 325 * so if the caller holds any timer references using the manager, it 326 * must detach them before calling isc_timermgr_destroy() or it will 327 * block forever. 328 * 329 * Requires: 330 * 331 *\li '*managerp' is a valid isc_timermgr_t. 332 * 333 * Ensures: 334 * 335 *\li *managerp == NULL 336 * 337 *\li All resources used by the manager have been freed. 338 */ 339 340void isc_timermgr_poke(isc_timermgr_t *m); 341 342ISC_LANG_ENDDECLS 343 344#endif /* ISC_TIMER_H */ 345