Browse code

wheeltimer: timers use inheritance instead of generic params

Raphael Coeffic authored on 23/09/2012 11:39:31
Showing 8 changed files
... ...
@@ -32,30 +32,17 @@
32 32
 
33 33
 using std::map;
34 34
 
35
-void app_timer_cb(timer* t, unsigned int data1, void* data2) {
36
-  AmAppTimer::instance()->app_timer_cb(t, data1, data2);
37
-}
38
-
39 35
 app_timer::app_timer(const string& q_id, int timer_id, unsigned int expires)
40
-  : timer(timer_id<0 ? 1 : 0, expires, (timer_cb)app_timer_cb,
41
-	  abs(timer_id), strdup(q_id.c_str())) { }
36
+  : timer(expires),
37
+    timer_id(timer_id), q_id(q_id)
38
+{ }
42 39
 
43
-app_timer::~app_timer() {
44
-  if (NULL != data2) {
45
-    free(data2);
46
-    //    delete[] data2;
47
-  }
48
-}
40
+app_timer::~app_timer() 
41
+{ }
49 42
 
50
-int app_timer::get_id() {
51
-  return type == 1 ? -data1 : data1;
52
-}
53
-
54
-string app_timer::get_q_id() {
55
-  if (NULL != data2)
56
-    return string((char*)data2);
57
-  else
58
-    return string();
43
+void app_timer::fire() 
44
+{
45
+  AmAppTimer::instance()->app_timer_cb(this);
59 46
 }
60 47
 
61 48
 _AmAppTimer::_AmAppTimer() {
... ...
@@ -64,17 +51,8 @@ _AmAppTimer::_AmAppTimer() {
64 51
 _AmAppTimer::~_AmAppTimer() {
65 52
 }
66 53
 
67
-void _AmAppTimer::app_timer_cb(timer* t, unsigned int data1, void* data2) {
68
-  if (NULL == t)
69
-    return;
70
-
71
-  app_timer* at = dynamic_cast<app_timer*>(t);
72
-  if (NULL == at) {
73
-    ERROR("internal: wrong timer object\n");
74
-    //   delete t; // ???
75
-    return;
76
-  }
77
-
54
+void _AmAppTimer::app_timer_cb(app_timer* at)
55
+{
78 56
   app_timer* at_local = erase_timer(at->get_q_id(), at->get_id());
79 57
 
80 58
   if (NULL != at_local) {
... ...
@@ -33,12 +33,20 @@
33 33
 using std::string;
34 34
 
35 35
 #include <map>
36
-class app_timer : public timer {
36
+class app_timer : public timer 
37
+{
38
+  string q_id;
39
+  int    timer_id;
40
+
37 41
  public:
38 42
   app_timer(const string& q_id, int timer_id, unsigned int expires);
39 43
   ~app_timer();
40
-  int get_id();
41
-  string get_q_id();
44
+
45
+  int get_id() { return timer_id; }
46
+  string get_q_id() { return q_id; }
47
+
48
+  // timer interface
49
+  void fire();
42 50
 };
43 51
 
44 52
 
... ...
@@ -63,7 +71,7 @@ class _AmAppTimer : public _wheeltimer {
63 71
   /** remove all timers for event queue eventqueue_name */
64 72
   void removeTimers(const string& eventqueue_name);
65 73
 
66
-  void app_timer_cb(timer* t, unsigned int data1, void* data2);
74
+  void app_timer_cb(app_timer* at);
67 75
 };
68 76
 
69 77
 typedef singleton<_AmAppTimer> AmAppTimer;
... ...
@@ -49,7 +49,7 @@ int _timer_type_lookup[] = {
49 49
     1,     // STIMER_C; shares the same slot at STIMER_B (INV trans only)
50 50
 };
51 51
 
52
-inline timer** fetch_timer(unsigned int timer_type, timer** base)
52
+inline trans_timer** fetch_timer(unsigned int timer_type, trans_timer** base)
53 53
 {
54 54
     timer_type &= 0xFFFF;
55 55
 
... ...
@@ -115,7 +115,7 @@ bool sip_trans::is_timer_set(unsigned int timer_type)
115 115
  *
116 116
  * @param timer_type @see sip_timer_type
117 117
  */
118
-timer* sip_trans::get_timer(unsigned int timer_type)
118
+trans_timer* sip_trans::get_timer(unsigned int timer_type)
119 119
 {
120 120
     return *fetch_timer(timer_type,timers);
121 121
 }
... ...
@@ -131,37 +131,37 @@ char _timer_name_lookup[] = {'0','A','B','D','E','F','K','G','H','I','J','L','M'
131 131
  * @param t the new timer
132 132
  * @param timer_type @see sip_timer_type
133 133
  */
134
-void sip_trans::reset_timer(timer* t, unsigned int timer_type)
134
+void sip_trans::reset_timer(trans_timer* t, unsigned int timer_type)
135 135
 {
136
-    timer** tp = fetch_timer(timer_type,timers);
136
+    trans_timer** tp = fetch_timer(timer_type,timers);
137 137
     
138 138
     if(*tp != NULL){
139 139
 
140 140
 	DBG("Clearing old timer of type %c (this=%p)\n",timer_name((*tp)->type),*tp);
141
-	wheeltimer::instance()->remove_timer(*tp);
141
+	wheeltimer::instance()->remove_timer((timer*)*tp);
142 142
     }
143 143
 
144 144
     *tp = t;
145 145
 
146 146
     if(t)
147
-	wheeltimer::instance()->insert_timer(t);
147
+	wheeltimer::instance()->insert_timer((timer*)t);
148 148
 }
149 149
 
150
-void trans_timer_cb(timer* t, unsigned int bucket_id, sip_trans* tr)
150
+void trans_timer::fire()
151 151
 {
152 152
     trans_bucket* bucket = get_trans_bucket(bucket_id);
153 153
     if(bucket){
154 154
 	bucket->lock();
155
-	if(bucket->exist(tr)){
155
+	if(bucket->exist(t)){
156 156
 	    DBG("Transaction timer expired: type=%c, trans=%p, eta=%i, t=%i\n",
157
-		timer_name(t->type),tr,t->expires,wheeltimer::instance()->wall_clock);
157
+		timer_name(type),t,expires,wheeltimer::instance()->wall_clock);
158 158
 
159 159
 	    // timer_expired unlocks the bucket
160
-	    trans_layer::instance()->timer_expired(t,bucket,tr);
160
+	    trans_layer::instance()->timer_expired(this,bucket,t);
161 161
 	}
162 162
 	else {
163 163
 	    WARN("Ignoring expired timer (%p): transaction"
164
-		 " %p does not exist anymore\n",t,tr);
164
+		 " %p does not exist anymore\n",this,t);
165 165
 	    bucket->unlock();
166 166
 	}
167 167
     }
... ...
@@ -187,16 +187,15 @@ void sip_trans::reset_timer(unsigned int timer_type, unsigned int expire_delay /
187 187
     DBG("New timer of type %c at time=%i (repeated=%i)\n",
188 188
 	timer_name(timer_type),expires,timer_type>>16);
189 189
 
190
-    timer* t = new timer(timer_type,expires,
191
-			 (timer_cb)trans_timer_cb,
192
-			 bucket_id,this);
190
+    trans_timer* t = new trans_timer(timer_type,expires,
191
+				     bucket_id,this);
193 192
 
194 193
     reset_timer(t,timer_type);
195 194
 }
196 195
 
197 196
 void sip_trans::clear_timer(unsigned int timer_type)
198 197
 {
199
-    reset_timer((timer*)NULL,timer_type);
198
+    reset_timer((trans_timer*)NULL,timer_type);
200 199
 }
201 200
 
202 201
 void sip_trans::reset_all_timers()
... ...
@@ -204,7 +203,7 @@ void sip_trans::reset_all_timers()
204 203
     for(int i=0; i<SIP_TRANS_TIMERS; i++){
205 204
 	
206 205
 	if(timers[i]){
207
-	    wheeltimer::instance()->remove_timer(timers[i]);
206
+	    wheeltimer::instance()->remove_timer((timer*)timers[i]);
208 207
 	    timers[i] = NULL;
209 208
 	}
210 209
     }
... ...
@@ -31,6 +31,7 @@
31 31
 #define _sip_trans_h
32 32
 
33 33
 #include "cstring.h"
34
+#include "wheeltimer.h"
34 35
 
35 36
 #include <sys/socket.h>
36 37
 
... ...
@@ -70,12 +71,28 @@ enum {
70 71
  */
71 72
 #define SIP_TRANS_TIMERS 3
72 73
 
73
-class timer;
74
+class sip_trans;
74 75
 
76
+class trans_timer
77
+    : protected timer
78
+{
79
+public:
80
+    unsigned int type;
81
+    unsigned int bucket_id;
82
+    sip_trans*   t;
83
+
84
+    trans_timer(unsigned int timer_type, unsigned int expires,
85
+		int bucket_id, sip_trans* t)
86
+        : timer(expires), type(timer_type),
87
+	  bucket_id(bucket_id), t(t)
88
+    {}
89
+
90
+    void fire();
91
+};
75 92
 
76 93
 class sip_trans
77 94
 {
78
-    timer* timers[SIP_TRANS_TIMERS];
95
+    trans_timer* timers[SIP_TRANS_TIMERS];
79 96
 
80 97
     /**
81 98
      * Resets a specific timer
... ...
@@ -83,7 +100,7 @@ class sip_trans
83 100
      * @param t the new timer
84 101
      * @param timer_type @see sip_timer_type
85 102
     */
86
-    void reset_timer(timer* t, unsigned int timer_type);    
103
+    void reset_timer(trans_timer* t, unsigned int timer_type);
87 104
 
88 105
  public:
89 106
     /** Transaction type */
... ...
@@ -133,7 +150,7 @@ class sip_trans
133 150
      *
134 151
      * @param timer_type @see sip_timer_type
135 152
      */
136
-    timer* get_timer(unsigned int timer_type);
153
+    trans_timer* get_timer(unsigned int timer_type);
137 154
 
138 155
     
139 156
     /**
... ...
@@ -1730,7 +1730,8 @@ void _trans_layer::send_non_200_ack(sip_msg* reply, sip_trans* t)
1730 1730
 
1731 1731
 }
1732 1732
 
1733
-void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr)
1733
+void _trans_layer::timer_expired(trans_timer* t, trans_bucket* bucket,
1734
+				 sip_trans* tr)
1734 1735
 {
1735 1736
     int n = t->type >> 16;
1736 1737
     int type = t->type & 0xFFFF;
... ...
@@ -1880,7 +1881,7 @@ void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr)
1880 1881
 	break;
1881 1882
 
1882 1883
     default:
1883
-	ERROR("Invalid timer type %i\n",t->type);
1884
+	ERROR("Invalid timer type %i\n",type);
1884 1885
 	break;
1885 1886
     }
1886 1887
 
... ...
@@ -1989,7 +1990,7 @@ int _trans_layer::try_next_ip(trans_bucket* bucket, sip_trans* tr)
1989 1990
     tr->msg->send();
1990 1991
     
1991 1992
     // reset counter for timer A & E
1992
-    timer* A_E_timer = tr->get_timer(STIMER_A);
1993
+    trans_timer* A_E_timer = tr->get_timer(STIMER_A);
1993 1994
     tr->reset_timer(A_E_timer->type & 0xFFFF,A_TIMER,bucket->get_id());
1994 1995
     
1995 1996
     if(!tr->msg->h_dns.eoip())
... ...
@@ -46,9 +46,9 @@ struct sockaddr_storage;
46 46
 
47 47
 class trans_ticket;
48 48
 class trans_bucket;
49
+class trans_timer;
49 50
 class trsp_socket;
50 51
 class sip_ua;
51
-class timer;
52 52
 
53 53
 /** 
54 54
  * The transaction layer object.
... ...
@@ -123,7 +123,7 @@ public:
123 123
      * At this place, the bucket is already locked, so
124 124
      * please be quick.
125 125
      */
126
-    void timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr);
126
+    void timer_expired(trans_timer* t, trans_bucket* bucket, sip_trans* tr);
127 127
 
128 128
     sip_ua*              ua;
129 129
     vector<trsp_socket*> transports;
... ...
@@ -180,7 +180,7 @@ void _wheeltimer::process_current_timers()
180 180
 	t->next = NULL;
181 181
 	t->prev = NULL;
182 182
 
183
-	t->cb(t,t->data1,t->data2);
183
+	t->fire();
184 184
 
185 185
 	t = t1;
186 186
     }
... ...
@@ -43,9 +43,6 @@
43 43
 // do not change
44 44
 #define WHEELS 4
45 45
 
46
-class timer;
47
-typedef void (*timer_cb)(timer*,unsigned int /*data1*/,void* /*data2*/);
48
-
49 46
 class base_timer
50 47
 {
51 48
 public:
... ...
@@ -61,26 +58,19 @@ public:
61 58
     base_timer*  prev;
62 59
     u_int32_t    expires;
63 60
 
64
-    unsigned int type;
65
-    timer_cb     cb;
66
-    unsigned int data1;
67
-    void*        data2;
68
-    
69
-
70 61
     timer() 
71
-	: base_timer(),type(0),
72
-	  prev(0), expires(0),cb(0),
73
-	  data1(0),data2(0) 
62
+	: base_timer(),
63
+	  prev(0), expires(0) 
74 64
     {}
75 65
 
76
-    timer(unsigned int timer_type, unsigned int expires, timer_cb cb, int data1, void* data2)
77
-	: base_timer(),type(timer_type),
78
-	  prev(0), expires(expires), cb(cb), 
79
-	  data1(data1),data2(data2)
66
+    timer(unsigned int expires)
67
+        : base_timer(),
68
+	  prev(0), expires(expires)
80 69
     {}
81 70
 
82 71
     ~timer(); 
83
-    
72
+
73
+    virtual void fire()=0;
84 74
 };
85 75
 
86 76
 #include "singleton.h"
... ...
@@ -128,7 +118,6 @@ public:
128 118
     //clock reference
129 119
     volatile u_int32_t wall_clock; // 32 bits
130 120
 
131
-    void clock_work();
132 121
     void insert_timer(timer* t);
133 122
     void remove_timer(timer* t);
134 123
 };