dlg_timer.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "../../mem/shm_mem.h"
00037 #include "../../timer.h"
00038 #include "dlg_timer.h"
00039
00040
00041 struct dlg_timer *d_timer = 0;
00042
00043 dlg_timer_handler timer_hdl = 0;
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 int init_dlg_timer(dlg_timer_handler hdl)
00054 {
00055 d_timer = (struct dlg_timer*)shm_malloc(sizeof(struct dlg_timer));
00056 if (d_timer==0) {
00057 LM_ERR("no more shm mem\n");
00058 return -1;
00059 }
00060 memset( d_timer, 0, sizeof(struct dlg_timer) );
00061
00062 d_timer->first.next = d_timer->first.prev = &(d_timer->first);
00063
00064 d_timer->lock = lock_alloc();
00065 if (d_timer->lock==0) {
00066 LM_ERR("failed to alloc lock\n");
00067 goto error0;
00068 }
00069
00070 if (lock_init(d_timer->lock)==0) {
00071 LM_ERR("failed to init lock\n");
00072 goto error1;
00073 }
00074
00075 timer_hdl = hdl;
00076 return 0;
00077 error1:
00078 lock_dealloc(d_timer->lock);
00079 error0:
00080 shm_free(d_timer);
00081 d_timer = 0;
00082 return -1;
00083 }
00084
00085
00086
00087
00088
00089 void destroy_dlg_timer(void)
00090 {
00091 if (d_timer==0)
00092 return;
00093
00094 lock_destroy(d_timer->lock);
00095 lock_dealloc(d_timer->lock);
00096
00097 shm_free(d_timer);
00098 d_timer = 0;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 static inline void insert_dialog_timer_unsafe(struct dlg_tl *tl)
00108 {
00109 struct dlg_tl* ptr;
00110
00111
00112 for(ptr = d_timer->first.prev; ptr != &d_timer->first ; ptr = ptr->prev) {
00113 if ( ptr->timeout <= tl->timeout )
00114 break;
00115 }
00116
00117 LM_DBG("inserting %p for %d\n", tl,tl->timeout);
00118 tl->prev = ptr;
00119 tl->next = ptr->next;
00120 tl->prev->next = tl;
00121 tl->next->prev = tl;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131 int insert_dlg_timer(struct dlg_tl *tl, int interval)
00132 {
00133 lock_get( d_timer->lock);
00134
00135 if (tl->next!=0 || tl->prev!=0) {
00136 lock_release( d_timer->lock);
00137 LM_CRIT("Trying to insert a bogus dlg tl=%p tl->next=%p tl->prev=%p\n",
00138 tl, tl->next, tl->prev);
00139 return -1;
00140 }
00141 tl->timeout = get_ticks()+interval;
00142 insert_dialog_timer_unsafe( tl );
00143
00144 lock_release( d_timer->lock);
00145
00146 return 0;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155 static inline void remove_dialog_timer_unsafe(struct dlg_tl *tl)
00156 {
00157 tl->prev->next = tl->next;
00158 tl->next->prev = tl->prev;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168 int remove_dialog_timer(struct dlg_tl *tl)
00169 {
00170 lock_get( d_timer->lock);
00171
00172 if (tl->prev==NULL && tl->timeout==0) {
00173 lock_release( d_timer->lock);
00174 return 1;
00175 }
00176
00177 if (tl->prev==NULL || tl->next==NULL) {
00178 LM_CRIT("bogus tl=%p tl->prev=%p tl->next=%p\n",
00179 tl, tl->prev, tl->next);
00180 lock_release( d_timer->lock);
00181 return -1;
00182 }
00183
00184 remove_dialog_timer_unsafe(tl);
00185 tl->next = NULL;
00186 tl->prev = NULL;
00187 tl->timeout = 0;
00188
00189 lock_release( d_timer->lock);
00190 return 0;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 int update_dlg_timer(struct dlg_tl *tl, int timeout)
00202 {
00203 lock_get( d_timer->lock);
00204
00205 if ( tl->next ) {
00206 if (tl->prev==0) {
00207 lock_release( d_timer->lock);
00208 return -1;
00209 }
00210 remove_dialog_timer_unsafe(tl);
00211 }
00212
00213 tl->timeout = get_ticks()+timeout;
00214 insert_dialog_timer_unsafe( tl );
00215
00216 lock_release( d_timer->lock);
00217 return 0;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 static inline struct dlg_tl* get_expired_dlgs(unsigned int time)
00227 {
00228 struct dlg_tl *tl , *end, *ret;
00229
00230 lock_get( d_timer->lock);
00231
00232 if (d_timer->first.next==&(d_timer->first)
00233 || d_timer->first.next->timeout > time ) {
00234 lock_release( d_timer->lock);
00235 return 0;
00236 }
00237
00238 end = &d_timer->first;
00239 tl = d_timer->first.next;
00240 LM_WARN("start with tl=%p tl->prev=%p tl->next=%p (%d) at %d "
00241 "and end with end=%p end->prev=%p end->next=%p\n",
00242 tl,tl->prev,tl->next,tl->timeout,time,
00243 end,end->prev,end->next);
00244 while( tl!=end && tl->timeout <= time) {
00245 LM_WARN("getting tl=%p tl->prev=%p tl->next=%p with %d\n",
00246 tl,tl->prev,tl->next,tl->timeout);
00247 tl->prev = 0;
00248 tl->timeout = 0;
00249 tl=tl->next;
00250 }
00251 LM_WARN("end with tl=%p tl->prev=%p tl->next=%p and d_timer->first.next->prev=%p\n",
00252 tl,tl->prev,tl->next,d_timer->first.next->prev);
00253
00254 if (tl==end && d_timer->first.next->prev) {
00255 ret = 0;
00256 } else {
00257 ret = d_timer->first.next;
00258 tl->prev->next = 0;
00259 d_timer->first.next = tl;
00260 tl->prev = &d_timer->first;
00261 }
00262
00263 lock_release( d_timer->lock);
00264
00265 return ret;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275 void dlg_timer_routine(unsigned int ticks , void * attr)
00276 {
00277 struct dlg_tl *tl, *ctl;
00278
00279 tl = get_expired_dlgs( ticks );
00280
00281 while (tl) {
00282 ctl = tl;
00283 tl = tl->next;
00284 ctl->next = NULL;
00285 LM_DBG("tl=%p next=%p\n", ctl, tl);
00286 timer_hdl( ctl );
00287 }
00288 }