/* returns number of ticks before retrying the del, or 0 if the del. * was succesfull */ inline static ticks_t delete_cell(struct cell *p_cell, int unlock) { /* there may still be FR/RETR timers, which have been reset (i.e., time_out==TIMER_DELETED) but are stilled linked to timer lists and must be removed from there before the structures are released */ unlink_timers(p_cell); /* still in use ... don't delete */ if(IS_REFFED_UNSAFE(p_cell)) { if(unlock) UNLOCK_HASH(p_cell->hash_index); LM_DBG("%p: can't delete -- still reffed (%d)\n", p_cell, p_cell->ref_count); /* delay the delete */ /* TODO: change refcnts and delete on refcnt==0 */ return cfg_get(tm, tm_cfg, delete_timeout); } else { if(unlock) UNLOCK_HASH(p_cell->hash_index); #ifdef EXTRA_DEBUG LM_DBG("delete transaction %p\n", p_cell); #endif free_cell(p_cell); return 0; } }
static void delete_cell( struct cell *p_cell, int unlock ) { #ifdef EXTRA_DEBUG int i; #endif /* there may still be FR/RETR timers, which have been reset (i.e., time_out==TIMER_DELETED) but are stilled linked to timer lists and must be removed from there before the structures are released */ unlink_timers( p_cell ); #ifdef EXTRA_DEBUG if (is_in_timer_list2(& p_cell->wait_tl )) { LM_ERR("transaction %p scheduled for deletion and still on WAIT," " timeout=%lld\n",p_cell, p_cell->wait_tl.time_out); abort(); } if (is_in_timer_list2(& p_cell->uas.response.retr_timer )) { LM_ERR("transaction %p scheduled for deletion and still on RETR (rep)," "timeout=%lld\n",p_cell, p_cell->uas.response.retr_timer.time_out); abort(); } if (is_in_timer_list2(& p_cell->uas.response.fr_timer )) { LM_ERR("transaction %p scheduled for deletion and still on FR (rep)," " timeout=%lld\n", p_cell,p_cell->uas.response.fr_timer.time_out); abort(); } for (i=0; i<p_cell->nr_of_outgoings; i++) { if (is_in_timer_list2(& p_cell->uac[i].request.retr_timer)) { LM_ERR("transaction %p scheduled for deletion and still on RETR " "(req %d), timeout %lld\n", p_cell, i, p_cell->uac[i].request.retr_timer.time_out); abort(); } if (is_in_timer_list2(& p_cell->uac[i].request.fr_timer)) { LM_ERR("transaction %p scheduled for deletion and" " still on FR (req %d), timeout %lld\n", p_cell, i, p_cell->uac[i].request.fr_timer.time_out); abort(); } if (is_in_timer_list2(& p_cell->uac[i].local_cancel.retr_timer)) { LM_ERR("transaction %p scheduled for deletion and" " still on RETR/cancel (req %d), timeout %lld\n", p_cell, i, p_cell->uac[i].request.retr_timer.time_out); abort(); } if (is_in_timer_list2(& p_cell->uac[i].local_cancel.fr_timer)) { LM_ERR("transaction %p scheduled for deletion and" " still on FR/cancel (req %d), timeout %lld\n", p_cell, i, p_cell->uac[i].request.fr_timer.time_out); abort(); } } /* reset_retr_timers( hash__XX_table, p_cell ); */ #endif /* still in use ... don't delete */ if ( IS_REFFED_UNSAFE(p_cell) ) { LM_DBG("delete_cell %p: can't delete -- still reffed (%d)\n", p_cell, p_cell->ref_count); if (unlock) UNLOCK_HASH(p_cell->hash_index); /* set to NULL so that set_timer will work */ p_cell->dele_tl.timer_list= NULL; /* it's added to del list for future del */ set_timer( &(p_cell->dele_tl), DELETE_LIST, 0 ); } else { if (unlock) UNLOCK_HASH(p_cell->hash_index); LM_DBG("delete transaction %p\n", p_cell ); free_cell( p_cell ); } }