]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/bind9/lib/isc/include/isc/timer.h
Update BIND to 9.9.6-P1
[FreeBSD/stable/9.git] / contrib / bind9 / lib / isc / include / isc / timer.h
1 /*
2  * Copyright (C) 2004-2009, 2012, 2014  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.43 2009/09/02 23:48:03 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
81 ISC_LANG_BEGINDECLS
82
83 /***
84  *** Types
85  ***/
86
87 /*% Timer Type */
88 typedef 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
95 typedef 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 /*% Timer and timer manager methods */
107 typedef struct {
108         void            (*destroy)(isc_timermgr_t **managerp);
109         isc_result_t    (*timercreate)(isc_timermgr_t *manager,
110                                        isc_timertype_t type,
111                                        const isc_time_t *expires,
112                                        const isc_interval_t *interval,
113                                        isc_task_t *task,
114                                        isc_taskaction_t action,
115                                        void *arg,
116                                        isc_timer_t **timerp);
117 } isc_timermgrmethods_t;
118
119 typedef struct {
120         void            (*attach)(isc_timer_t *timer, isc_timer_t **timerp);
121         void            (*detach)(isc_timer_t **timerp);
122         isc_result_t    (*reset)(isc_timer_t *timer, isc_timertype_t type,
123                                  const isc_time_t *expires,
124                                  const isc_interval_t *interval,
125                                  isc_boolean_t purge);
126         isc_result_t    (*touch)(isc_timer_t *timer);
127 } isc_timermethods_t;
128
129 /*%
130  * This structure is actually just the common prefix of a timer manager
131  * object implementation's version of an isc_timermgr_t.
132  * \brief
133  * Direct use of this structure by clients is forbidden.  timer implementations
134  * may change the structure.  'magic' must be ISCAPI_TIMERMGR_MAGIC for any
135  * of the isc_timer_ routines to work.  timer implementations must maintain
136  * all timer invariants.
137  */
138 struct isc_timermgr {
139         unsigned int            impmagic;
140         unsigned int            magic;
141         isc_timermgrmethods_t   *methods;
142 };
143
144 #define ISCAPI_TIMERMGR_MAGIC           ISC_MAGIC('A','t','m','g')
145 #define ISCAPI_TIMERMGR_VALID(m)        ((m) != NULL && \
146                                          (m)->magic == ISCAPI_TIMERMGR_MAGIC)
147
148 /*%
149  * This is the common prefix of a timer object.  The same note as
150  * that for the timermgr structure applies.
151  */
152 struct isc_timer {
153         unsigned int            impmagic;
154         unsigned int            magic;
155         isc_timermethods_t      *methods;
156 };
157
158 #define ISCAPI_TIMER_MAGIC      ISC_MAGIC('A','t','m','r')
159 #define ISCAPI_TIMER_VALID(s)   ((s) != NULL && \
160                                  (s)->magic == ISCAPI_TIMER_MAGIC)
161
162 /***
163  *** Timer and Timer Manager Functions
164  ***
165  *** Note: all Ensures conditions apply only if the result is success for
166  *** those functions which return an isc_result_t.
167  ***/
168
169 isc_result_t
170 isc_timer_create(isc_timermgr_t *manager,
171                  isc_timertype_t type,
172                  const isc_time_t *expires,
173                  const isc_interval_t *interval,
174                  isc_task_t *task,
175                  isc_taskaction_t action,
176                  void *arg,
177                  isc_timer_t **timerp);
178 /*%<
179  * Create a new 'type' timer managed by 'manager'.  The timers parameters
180  * are specified by 'expires' and 'interval'.  Events will be posted to
181  * 'task' and when dispatched 'action' will be called with 'arg' as the
182  * arg value.  The new timer is returned in 'timerp'.
183  *
184  * Notes:
185  *
186  *\li   For ticker timers, the timer will generate a 'tick' event every
187  *      'interval' seconds.  The value of 'expires' is ignored.
188  *
189  *\li   For once timers, 'expires' specifies the time when a life timeout
190  *      event should be generated.  If 'expires' is 0 (the epoch), then no life
191  *      timeout will be generated.  'interval' specifies how long the timer
192  *      can be idle before it generates an idle timeout.  If 0, then no
193  *      idle timeout will be generated.
194  *
195  *\li   If 'expires' is NULL, the epoch will be used.
196  *
197  *      If 'interval' is NULL, the zero interval will be used.
198  *
199  * Requires:
200  *
201  *\li   'manager' is a valid manager
202  *
203  *\li   'task' is a valid task
204  *
205  *\li   'action' is a valid action
206  *
207  *\li   'expires' points to a valid time, or is NULL.
208  *
209  *\li   'interval' points to a valid interval, or is NULL.
210  *
211  *\li   type == isc_timertype_inactive ||
212  *      ('expires' and 'interval' are not both 0)
213  *
214  *\li   'timerp' is a valid pointer, and *timerp == NULL
215  *
216  * Ensures:
217  *
218  *\li   '*timerp' is attached to the newly created timer
219  *
220  *\li   The timer is attached to the task
221  *
222  *\li   An idle timeout will not be generated until at least Now + the
223  *      timer's interval if 'timer' is a once timer with a non-zero
224  *      interval.
225  *
226  * Returns:
227  *
228  *\li   Success
229  *\li   No memory
230  *\li   Unexpected error
231  */
232
233 isc_result_t
234 isc_timer_reset(isc_timer_t *timer,
235                 isc_timertype_t type,
236                 const isc_time_t *expires,
237                 const isc_interval_t *interval,
238                 isc_boolean_t purge);
239 /*%<
240  * Change the timer's type, expires, and interval values to the given
241  * values.  If 'purge' is TRUE, any pending events from this timer
242  * are purged from its task's event queue.
243  *
244  * Notes:
245  *
246  *\li   If 'expires' is NULL, the epoch will be used.
247  *
248  *\li   If 'interval' is NULL, the zero interval will be used.
249  *
250  * Requires:
251  *
252  *\li   'timer' is a valid timer
253  *
254  *\li   The same requirements that isc_timer_create() imposes on 'type',
255  *      'expires' and 'interval' apply.
256  *
257  * Ensures:
258  *
259  *\li   An idle timeout will not be generated until at least Now + the
260  *      timer's interval if 'timer' is a once timer with a non-zero
261  *      interval.
262  *
263  * Returns:
264  *
265  *\li   Success
266  *\li   No memory
267  *\li   Unexpected error
268  */
269
270 isc_result_t
271 isc_timer_touch(isc_timer_t *timer);
272 /*%<
273  * Set the last-touched time of 'timer' to the current time.
274  *
275  * Requires:
276  *
277  *\li   'timer' is a valid once timer.
278  *
279  * Ensures:
280  *
281  *\li   An idle timeout will not be generated until at least Now + the
282  *      timer's interval if 'timer' is a once timer with a non-zero
283  *      interval.
284  *
285  * Returns:
286  *
287  *\li   Success
288  *\li   Unexpected error
289  */
290
291 void
292 isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp);
293 /*%<
294  * Attach *timerp to timer.
295  *
296  * Requires:
297  *
298  *\li   'timer' is a valid timer.
299  *
300  *\li   'timerp' points to a NULL timer.
301  *
302  * Ensures:
303  *
304  *\li   *timerp is attached to timer.
305  */
306
307 void
308 isc_timer_detach(isc_timer_t **timerp);
309 /*%<
310  * Detach *timerp from its timer.
311  *
312  * Requires:
313  *
314  *\li   'timerp' points to a valid timer.
315  *
316  * Ensures:
317  *
318  *\li   *timerp is NULL.
319  *
320  *\li   If '*timerp' is the last reference to the timer,
321  *      then:
322  *
323  *\code
324  *              The timer will be shutdown
325  *
326  *              The timer will detach from its task
327  *
328  *              All resources used by the timer have been freed
329  *
330  *              Any events already posted by the timer will be purged.
331  *              Therefore, if isc_timer_detach() is called in the context
332  *              of the timer's task, it is guaranteed that no more
333  *              timer event callbacks will run after the call.
334  *\endcode
335  */
336
337 isc_timertype_t
338 isc_timer_gettype(isc_timer_t *timer);
339 /*%<
340  * Return the timer type.
341  *
342  * Requires:
343  *
344  *\li   'timer' to be a valid timer.
345  */
346
347 isc_result_t
348 isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
349                          isc_timermgr_t **managerp);
350
351 isc_result_t
352 isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
353 /*%<
354  * Create a timer manager.  isc_timermgr_createinctx() also associates
355  * the new manager with the specified application context.
356  *
357  * Notes:
358  *
359  *\li   All memory will be allocated in memory context 'mctx'.
360  *
361  * Requires:
362  *
363  *\li   'mctx' is a valid memory context.
364  *
365  *\li   'managerp' points to a NULL isc_timermgr_t.
366  *
367  *\li   'actx' is a valid application context (for createinctx()).
368  *
369  * Ensures:
370  *
371  *\li   '*managerp' is a valid isc_timermgr_t.
372  *
373  * Returns:
374  *
375  *\li   Success
376  *\li   No memory
377  *\li   Unexpected error
378  */
379
380 void
381 isc_timermgr_destroy(isc_timermgr_t **managerp);
382 /*%<
383  * Destroy a timer manager.
384  *
385  * Notes:
386  *
387  *\li   This routine blocks until there are no timers left in the manager,
388  *      so if the caller holds any timer references using the manager, it
389  *      must detach them before calling isc_timermgr_destroy() or it will
390  *      block forever.
391  *
392  * Requires:
393  *
394  *\li   '*managerp' is a valid isc_timermgr_t.
395  *
396  * Ensures:
397  *
398  *\li   *managerp == NULL
399  *
400  *\li   All resources used by the manager have been freed.
401  */
402
403 void isc_timermgr_poke(isc_timermgr_t *m);
404
405 #ifdef USE_TIMERIMPREGISTER
406 /*%<
407  * See isc_timermgr_create() above.
408  */
409 typedef isc_result_t
410 (*isc_timermgrcreatefunc_t)(isc_mem_t *mctx, isc_timermgr_t **managerp);
411
412 isc_result_t
413 isc__timer_register(void);
414 /*%<
415  * Register a new timer management implementation and add it to the list of
416  * supported implementations.  This function must be called when a different
417  * event library is used than the one contained in the ISC library.
418  */
419
420 isc_result_t
421 isc_timer_register(isc_timermgrcreatefunc_t createfunc);
422 /*%<
423  * A short cut function that specifies the timer management module in the ISC
424  * library for isc_timer_register().  An application that uses the ISC library
425  * usually do not have to care about this function: it would call
426  * isc_lib_register(), which internally calls this function.
427  */
428 #endif /* USE_TIMERIMPREGISTER */
429
430 ISC_LANG_ENDDECLS
431
432 #endif /* ISC_TIMER_H */