|
@@ -98,6 +98,8 @@
|
|
* 2003-06-27 timers are not unlinked if timerlist is 0 (andrei)
|
|
* 2003-06-27 timers are not unlinked if timerlist is 0 (andrei)
|
|
* 2004-02-13 t->is_invite, t->local, t->noisy_ctimer replaced;
|
|
* 2004-02-13 t->is_invite, t->local, t->noisy_ctimer replaced;
|
|
* timer_link.payload removed (bogdan)
|
|
* timer_link.payload removed (bogdan)
|
|
|
|
+ * 2006-11-27 added del_fr_timer(): fr timers are immediately removed
|
|
|
|
+ * from the FR* lists (andrei)
|
|
*/
|
|
*/
|
|
|
|
|
|
#include "defs.h"
|
|
#include "defs.h"
|
|
@@ -322,7 +324,7 @@ inline static void retransmission_handler( struct timer_link *retr_tl )
|
|
"request resending (t=%p, %.9s ... )\n",
|
|
"request resending (t=%p, %.9s ... )\n",
|
|
r_buf->my_T, r_buf->buffer);
|
|
r_buf->my_T, r_buf->buffer);
|
|
if (SEND_BUFFER( r_buf )==-1) {
|
|
if (SEND_BUFFER( r_buf )==-1) {
|
|
- reset_timer( &r_buf->fr_timer );
|
|
|
|
|
|
+ del_fr_timer( &r_buf->fr_timer );
|
|
fake_reply(r_buf->my_T, r_buf->branch, 503 );
|
|
fake_reply(r_buf->my_T, r_buf->branch, 503 );
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -436,7 +438,7 @@ void cleanup_localcancel_timers( struct cell *t )
|
|
int i;
|
|
int i;
|
|
for (i=0; i<t->nr_of_outgoings; i++ ) {
|
|
for (i=0; i<t->nr_of_outgoings; i++ ) {
|
|
reset_timer( &t->uac[i].local_cancel.retr_timer );
|
|
reset_timer( &t->uac[i].local_cancel.retr_timer );
|
|
- reset_timer( &t->uac[i].local_cancel.fr_timer );
|
|
|
|
|
|
+ del_fr_timer( &t->uac[i].local_cancel.fr_timer );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -778,6 +780,33 @@ void reset_timer( struct timer_link* tl )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+/* remove a timer from the FR_TIMER_LIST or FR_INV_TIMER_LIST
|
|
|
|
+ * (it allows immediate delete of a fr timer => solves the race with
|
|
|
|
+ * variables timers inserted after longer deleted timers)
|
|
|
|
+ * WARNING: - don't try to use it to "move" a timer from one list
|
|
|
|
+ * to another, you'll run into races
|
|
|
|
+ */
|
|
|
|
+void del_fr_timer( struct timer_link *tl)
|
|
|
|
+{
|
|
|
|
+ /* the FR lock is common/shared by both FR_INV_TIMER_LIST
|
|
|
|
+ * and FR_TIMER_LIST, so we must lock only one of them */
|
|
|
|
+ lock(timertable->timers[FR_TIMER_LIST].mutex);
|
|
|
|
+ /* check first if we are on the "detached" timer_routine list (the fr
|
|
|
|
+ * handle is executing or timer_routine prepares to execute it).
|
|
|
|
+ * if so do nothing, except reseting the timer to TIMER_DELETED
|
|
|
|
+ * (just to give us a change at racing with timer_routine, if
|
|
|
|
+ * TIMER_DELETED is set and the fr handle is not already executing =>
|
|
|
|
+ * it will not be called anymore)
|
|
|
|
+ */
|
|
|
|
+ if (tl->timer_list!=DETACHED_LIST){
|
|
|
|
+ remove_timer_unsafe(tl); /* safe to call for null list */
|
|
|
|
+ }else{
|
|
|
|
+ reset_timer(tl);
|
|
|
|
+ }
|
|
|
|
+ unlock(timertable->timers[FR_TIMER_LIST].mutex);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
|
|
/* determine timer length and put on a correct timer list
|
|
/* determine timer length and put on a correct timer list
|
|
* WARNING: - don't try to use it to "move" a timer from one list
|
|
* WARNING: - don't try to use it to "move" a timer from one list
|