1 /* $Id$ */
2 /*
3  * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #ifndef __PJPP_TIMER_HPP__
21 #define __PJPP_TIMER_HPP__
22 
23 #include <pj/timer.h>
24 #include <pj++/types.hpp>
25 #include <pj/assert.h>
26 #include <pj++/lock.hpp>
27 
28 class Pj_Timer_Heap;
29 
30 //////////////////////////////////////////////////////////////////////////////
31 // Timer entry.
32 //
33 // How to use:
34 //  Derive class from Pj_Timer_Entry and override on_timeout().
35 //  Scheduler timer in Pj_Timer_Heap.
36 //
37 class Pj_Timer_Entry : public Pj_Object
38 {
39     friend class Pj_Timer_Heap;
40 
41 public:
42     //
43     // Default constructor.
44     //
Pj_Timer_Entry()45     Pj_Timer_Entry()
46     {
47         entry_.user_data = this;
48         entry_.cb = &timer_heap_callback;
49     }
50 
51     //
52     // Destructor, do nothing.
53     //
~Pj_Timer_Entry()54     ~Pj_Timer_Entry()
55     {
56     }
57 
58     //
59     // Override this to get the timeout notification.
60     //
61     virtual void on_timeout(int id) = 0;
62 
63 private:
64     pj_timer_entry entry_;
65 
timer_heap_callback(pj_timer_heap_t *,pj_timer_entry * e)66     static void timer_heap_callback(pj_timer_heap_t*, pj_timer_entry *e)
67     {
68         Pj_Timer_Entry *entry = (Pj_Timer_Entry*) e->user_data;
69         entry->on_timeout(e->id);
70     }
71 
72 };
73 
74 //////////////////////////////////////////////////////////////////////////////
75 // Timer heap.
76 //
77 class Pj_Timer_Heap : public Pj_Object
78 {
79 public:
80     //
81     // Default constructor.
82     //
Pj_Timer_Heap()83     Pj_Timer_Heap()
84         : ht_(NULL)
85     {
86     }
87 
88     //
89     // Construct timer heap.
90     //
Pj_Timer_Heap(Pj_Pool * pool,pj_size_t initial_count)91     Pj_Timer_Heap(Pj_Pool *pool, pj_size_t initial_count)
92         : ht_(NULL)
93     {
94         create(pool, initial_count);
95     }
96 
97     //
98     // Destructor.
99     //
~Pj_Timer_Heap()100     ~Pj_Timer_Heap()
101     {
102         destroy();
103     }
104 
105     //
106     // Create
107     //
create(Pj_Pool * pool,pj_size_t initial_count)108     pj_status_t create(Pj_Pool *pool, pj_size_t initial_count)
109     {
110         destroy();
111 	return pj_timer_heap_create(pool->pool_(), initial_count, &ht_);
112     }
113 
114     //
115     // Destroy
116     //
destroy()117     void destroy()
118     {
119         if (ht_) {
120             pj_timer_heap_destroy(ht_);
121             ht_ = NULL;
122         }
123     }
124 
125     //
126     // Get pjlib compatible timer heap object.
127     //
get_timer_heap()128     pj_timer_heap_t *get_timer_heap()
129     {
130 	return ht_;
131     }
132 
133     //
134     // Set the lock object.
135     //
set_lock(Pj_Lock * lock,bool auto_delete)136     void set_lock( Pj_Lock *lock, bool auto_delete )
137     {
138         pj_timer_heap_set_lock( ht_, lock->pj_lock_t_(), auto_delete);
139     }
140 
141     //
142     // Set maximum number of timed out entries to be processed per poll.
143     //
set_max_timed_out_per_poll(unsigned count)144     unsigned set_max_timed_out_per_poll(unsigned count)
145     {
146         return pj_timer_heap_set_max_timed_out_per_poll(ht_, count);
147     }
148 
149     //
150     // Schedule a timer.
151     //
schedule(Pj_Timer_Entry * ent,const Pj_Time_Val & delay,int id)152     bool schedule( Pj_Timer_Entry *ent, const Pj_Time_Val &delay,
153                    int id)
154     {
155         ent->entry_.id = id;
156 	return pj_timer_heap_schedule(ht_, &ent->entry_, &delay) == 0;
157     }
158 
159     //
160     // Cancel a timer.
161     //
cancel(Pj_Timer_Entry * ent)162     bool cancel(Pj_Timer_Entry *ent)
163     {
164 	return pj_timer_heap_cancel(ht_, &ent->entry_) == 1;
165     }
166 
167     //
168     // Get current number of timers
169     //
count()170     pj_size_t count()
171     {
172 	return pj_timer_heap_count(ht_);
173     }
174 
175     //
176     // Get the earliest time.
177     // Return false if no timer is found.
178     //
earliest_time(Pj_Time_Val * t)179     bool earliest_time(Pj_Time_Val *t)
180     {
181 	return pj_timer_heap_earliest_time(ht_, t) == PJ_SUCCESS;
182     }
183 
184     //
185     // Poll the timer.
186     // Return number of timed out entries has been called.
187     //
poll(Pj_Time_Val * next_delay=NULL)188     unsigned poll(Pj_Time_Val *next_delay = NULL)
189     {
190 	return pj_timer_heap_poll(ht_, next_delay);
191     }
192 
193 private:
194     pj_timer_heap_t *ht_;
195 };
196 
197 #endif	/* __PJPP_TIMER_HPP__ */
198 
199