void trans_timer::fire() { trans_bucket* bucket = get_trans_bucket(bucket_id); if(bucket){ bucket->lock(); if(bucket->exist(t)){ DBG("Transaction timer expired: type=%s, trans=%p, eta=%i, t=%i\n", timer_name(type),t,expires,wheeltimer::instance()->wall_clock); trans_timer* tt = t->get_timer(this->type & 0xFFFF); if(tt != this) { // timer has been reset while very close to firing!!! // 1. it is not yet deleted in the wheeltimer // 2. we have already set a new one // -> anyway, don't fire the old one !!! bucket->unlock(); return; } // timer_expired unlocks the bucket trans_layer::instance()->timer_expired(this,bucket,t); } else { WARN("Ignoring expired timer (%p/%s): transaction" " %p does not exist anymore\n",this,timer_name(type),t); bucket->unlock(); } } else { ERROR("Invalid bucket id\n"); } }
void sip_trans::dump() const { DBG("type=%s (0x%x); msg=%p; to_tag=%.*s;" " reply_status=%i; state=%s (%i); retr_buf=%p; timers [%s,%s,%s]\n", type_str(),type,msg,to_tag.len,to_tag.s, reply_status,state_str(),state,retr_buf, timers[0]==NULL?"none":timer_name(timers[0]->type), timers[1]==NULL?"none":timer_name(timers[1]->type), timers[2]==NULL?"none":timer_name(timers[2]->type)); }
void trans_timer_cb(timer* t, unsigned int bucket_id, sip_trans* tr) { trans_bucket* bucket = get_trans_bucket(bucket_id); if(bucket){ bucket->lock(); if(bucket->exist(tr)){ DBG("Transaction timer expired: type=%c, trans=%p, eta=%i, t=%i\n", timer_name(t->type),tr,t->expires,wheeltimer::instance()->wall_clock); trans_layer::instance()->timer_expired(t,bucket,tr); } else { WARN("Transaction %p does not exist anymore\n",tr); WARN("Timer type=%c will be deleted without further processing\n",timer_name(t->type)); } bucket->unlock(); } else { ERROR("Invalid bucket id\n"); } }
/** * Resets a specific timer * * @param t the new timer * @param timer_type @see sip_timer_type */ void sip_trans::reset_timer(timer* t, unsigned int timer_type) { timer** tp = fetch_timer(timer_type,timers); if(*tp != NULL){ DBG("Clearing old timer of type %c\n",timer_name((*tp)->type)); wheeltimer::instance()->remove_timer(*tp); } *tp = t; if(t) wheeltimer::instance()->insert_timer(t); }
/** * Resets a specific timer with a delay value * * @param timer_type @see sip_timer_type * @param expires_delay delay before expiration in millisecond */ void sip_trans::reset_timer(unsigned int timer_type, unsigned int expire_delay /* ms */, unsigned int bucket_id) { wheeltimer* wt = wheeltimer::instance(); unsigned int expires = expire_delay / (TIMER_RESOLUTION/1000); expires += wt->wall_clock; DBG("New timer of type %s at time=%i (repeated=%i)\n", timer_name(timer_type),expires,timer_type>>16); trans_timer* t = new trans_timer(timer_type,expires, bucket_id,this); reset_timer(t,timer_type); }