blob: 591493854afa27ef74e6d1a1b437f58ce72f62a4 [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id$ */
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18#ifndef __PJ_TIMER_H__
19#define __PJ_TIMER_H__
20
21/**
22 * @file timer.h
23 * @brief Timer Heap
24 */
25
26#include <pj/types.h>
27#include <pj/lock.h>
28
29PJ_BEGIN_DECL
30
31/**
32 * @defgroup PJ_TIMER Timer Heap Management.
33 * @ingroup PJ_MISC
34 * @brief
35 * The timer scheduling implementation here is based on ACE library's
36 * ACE_Timer_Heap, with only little modification to suit our library's style
37 * (I even left most of the comments in the original source).
38 *
39 * To quote the original quote in ACE_Timer_Heap_T class:
40 *
41 * This implementation uses a heap-based callout queue of
42 * absolute times. Therefore, in the average and worst case,
43 * scheduling, canceling, and expiring timers is O(log N) (where
44 * N is the total number of timers). In addition, we can also
45 * preallocate as many \a ACE_Timer_Nodes as there are slots in
46 * the heap. This allows us to completely remove the need for
47 * dynamic memory allocation, which is important for real-time
48 * systems.
49 *
50 * You can find the fine ACE library at:
51 * http://www.cs.wustl.edu/~schmidt/ACE.html
52 *
53 * ACE is Copyright (C)1993-2006 Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
54 *
55 * @{
56 *
57 * \section pj_timer_examples_sec Examples
58 *
59 * For some examples on how to use the timer heap, please see the link below.
60 *
61 * - \ref page_pjlib_timer_test
62 */
63
64
65/**
66 * The type for internal timer ID.
67 */
68typedef int pj_timer_id_t;
69
70/**
71 * Forward declaration for pj_timer_entry.
72 */
73struct pj_timer_entry;
74
75/**
76 * The type of callback function to be called by timer scheduler when a timer
77 * has expired.
78 *
79 * @param timer_heap The timer heap.
80 * @param entry Timer entry which timer's has expired.
81 */
82typedef void pj_timer_heap_callback(pj_timer_heap_t *timer_heap,
83 struct pj_timer_entry *entry);
84
85
86/**
87 * This structure represents an entry to the timer.
88 */
89typedef struct pj_timer_entry
90{
91 /**
92 * User data to be associated with this entry.
93 * Applications normally will put the instance of object that
94 * owns the timer entry in this field.
95 */
96 void *user_data;
97
98 /**
99 * Arbitrary ID assigned by the user/owner of this entry.
100 * Applications can use this ID to distinguish multiple
101 * timer entries that share the same callback and user_data.
102 */
103 int id;
104
105 /**
106 * Callback to be called when the timer expires.
107 */
108 pj_timer_heap_callback *cb;
109
110 /**
111 * Internal unique timer ID, which is assigned by the timer heap.
112 * Application should not touch this ID.
113 */
114 pj_timer_id_t _timer_id;
115
116 /**
117 * The future time when the timer expires, which the value is updated
118 * by timer heap when the timer is scheduled.
119 */
120 pj_time_val _timer_value;
121
122 /**
123 * Internal: the group lock used by this entry, set when
124 * pj_timer_heap_schedule_w_lock() is used.
125 */
126 pj_grp_lock_t *_grp_lock;
127
128#if PJ_TIMER_DEBUG
129 const char *src_file;
130 int src_line;
131#endif
132} pj_timer_entry;
133
134
135/**
136 * Calculate memory size required to create a timer heap.
137 *
138 * @param count Number of timer entries to be supported.
139 * @return Memory size requirement in bytes.
140 */
141PJ_DECL(pj_size_t) pj_timer_heap_mem_size(pj_size_t count);
142
143/**
144 * Create a timer heap.
145 *
146 * @param pool The pool where allocations in the timer heap will be
147 * allocated. The timer heap will dynamicly allocate
148 * more storate from the pool if the number of timer
149 * entries registered is more than the size originally
150 * requested when calling this function.
151 * @param count The maximum number of timer entries to be supported
152 * initially. If the application registers more entries
153 * during runtime, then the timer heap will resize.
154 * @param ht Pointer to receive the created timer heap.
155 *
156 * @return PJ_SUCCESS, or the appropriate error code.
157 */
158PJ_DECL(pj_status_t) pj_timer_heap_create( pj_pool_t *pool,
159 pj_size_t count,
160 pj_timer_heap_t **ht);
161
162/**
163 * Destroy the timer heap.
164 *
165 * @param ht The timer heap.
166 */
167PJ_DECL(void) pj_timer_heap_destroy( pj_timer_heap_t *ht );
168
169
170/**
171 * Set lock object to be used by the timer heap. By default, the timer heap
172 * uses dummy synchronization.
173 *
174 * @param ht The timer heap.
175 * @param lock The lock object to be used for synchronization.
176 * @param auto_del If nonzero, the lock object will be destroyed when
177 * the timer heap is destroyed.
178 */
179PJ_DECL(void) pj_timer_heap_set_lock( pj_timer_heap_t *ht,
180 pj_lock_t *lock,
181 pj_bool_t auto_del );
182
183/**
184 * Set maximum number of timed out entries to process in a single poll.
185 *
186 * @param ht The timer heap.
187 * @param count Number of entries.
188 *
189 * @return The old number.
190 */
191PJ_DECL(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht,
192 unsigned count );
193
194/**
195 * Initialize a timer entry. Application should call this function at least
196 * once before scheduling the entry to the timer heap, to properly initialize
197 * the timer entry.
198 *
199 * @param entry The timer entry to be initialized.
200 * @param id Arbitrary ID assigned by the user/owner of this entry.
201 * Applications can use this ID to distinguish multiple
202 * timer entries that share the same callback and user_data.
203 * @param user_data User data to be associated with this entry.
204 * Applications normally will put the instance of object that
205 * owns the timer entry in this field.
206 * @param cb Callback function to be called when the timer elapses.
207 *
208 * @return The timer entry itself.
209 */
210PJ_DECL(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,
211 int id,
212 void *user_data,
213 pj_timer_heap_callback *cb );
214
215/**
216 * Schedule a timer entry which will expire AFTER the specified delay.
217 *
218 * @param ht The timer heap.
219 * @param entry The entry to be registered.
220 * @param delay The interval to expire.
221 * @return PJ_SUCCESS, or the appropriate error code.
222 */
223#if PJ_TIMER_DEBUG
224# define pj_timer_heap_schedule(ht,e,d) \
225 pj_timer_heap_schedule_dbg(ht,e,d,__FILE__,__LINE__)
226
227 PJ_DECL(pj_status_t) pj_timer_heap_schedule_dbg( pj_timer_heap_t *ht,
228 pj_timer_entry *entry,
229 const pj_time_val *delay,
230 const char *src_file,
231 int src_line);
232#else
233PJ_DECL(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht,
234 pj_timer_entry *entry,
235 const pj_time_val *delay);
236#endif /* PJ_TIMER_DEBUG */
237
238/**
239 * Schedule a timer entry which will expire AFTER the specified delay, and
240 * increment the reference counter of the group lock while the timer entry
241 * is active. The group lock reference counter will automatically be released
242 * after the timer callback is called or when the timer is cancelled.
243 *
244 * @param ht The timer heap.
245 * @param entry The entry to be registered.
246 * @param id_val The value to be set to the "id" field of the timer entry
247 * once the timer is scheduled.
248 * @param delay The interval to expire.
249 * @param grp_lock The group lock.
250 *
251 * @return PJ_SUCCESS, or the appropriate error code.
252 */
253#if PJ_TIMER_DEBUG
254# define pj_timer_heap_schedule_w_grp_lock(ht,e,d,id,g) \
255 pj_timer_heap_schedule_w_grp_lock_dbg(ht,e,d,id,g,__FILE__,__LINE__)
256
257 PJ_DECL(pj_status_t) pj_timer_heap_schedule_w_grp_lock_dbg(
258 pj_timer_heap_t *ht,
259 pj_timer_entry *entry,
260 const pj_time_val *delay,
261 int id_val,
262 pj_grp_lock_t *grp_lock,
263 const char *src_file,
264 int src_line);
265#else
266PJ_DECL(pj_status_t) pj_timer_heap_schedule_w_grp_lock(
267 pj_timer_heap_t *ht,
268 pj_timer_entry *entry,
269 const pj_time_val *delay,
270 int id_val,
271 pj_grp_lock_t *grp_lock);
272#endif /* PJ_TIMER_DEBUG */
273
274
275/**
276 * Cancel a previously registered timer. This will also decrement the
277 * reference counter of the group lock associated with the timer entry,
278 * if the entry was scheduled with one.
279 *
280 * @param ht The timer heap.
281 * @param entry The entry to be cancelled.
282 * @return The number of timer cancelled, which should be one if the
283 * entry has really been registered, or zero if no timer was
284 * cancelled.
285 */
286PJ_DECL(int) pj_timer_heap_cancel( pj_timer_heap_t *ht,
287 pj_timer_entry *entry);
288
289/**
290 * Cancel only if the previously registered timer is active. This will
291 * also decrement the reference counter of the group lock associated
292 * with the timer entry, if the entry was scheduled with one. In any
293 * case, set the "id" to the specified value.
294 *
295 * @param ht The timer heap.
296 * @param entry The entry to be cancelled.
297 * @param id_val Value to be set to "id"
298 *
299 * @return The number of timer cancelled, which should be one if the
300 * entry has really been registered, or zero if no timer was
301 * cancelled.
302 */
303PJ_DECL(int) pj_timer_heap_cancel_if_active(pj_timer_heap_t *ht,
304 pj_timer_entry *entry,
305 int id_val);
306
307/**
308 * Get the number of timer entries.
309 *
310 * @param ht The timer heap.
311 * @return The number of timer entries.
312 */
313PJ_DECL(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht );
314
315/**
316 * Get the earliest time registered in the timer heap. The timer heap
317 * MUST have at least one timer being scheduled (application should use
318 * #pj_timer_heap_count() before calling this function).
319 *
320 * @param ht The timer heap.
321 * @param timeval The time deadline of the earliest timer entry.
322 *
323 * @return PJ_SUCCESS, or PJ_ENOTFOUND if no entry is scheduled.
324 */
325PJ_DECL(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t *ht,
326 pj_time_val *timeval);
327
328/**
329 * Poll the timer heap, check for expired timers and call the callback for
330 * each of the expired timers.
331 *
332 * Note: polling the timer heap is not necessary in Symbian. Please see
333 * @ref PJ_SYMBIAN_OS for more info.
334 *
335 * @param ht The timer heap.
336 * @param next_delay If this parameter is not NULL, it will be filled up with
337 * the time delay until the next timer elapsed, or
338 * PJ_MAXINT32 in the sec part if no entry exist.
339 *
340 * @return The number of timers expired.
341 */
342PJ_DECL(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht,
343 pj_time_val *next_delay);
344
345#if PJ_TIMER_DEBUG
346/**
347 * Dump timer heap entries.
348 *
349 * @param ht The timer heap.
350 */
351PJ_DECL(void) pj_timer_heap_dump(pj_timer_heap_t *ht);
352#endif
353
354/**
355 * @}
356 */
357
358PJ_END_DECL
359
360#endif /* __PJ_TIMER_H__ */
361