b/f: fixes possible deadlock when messages are sent from handle_sip_reply().

Original patch by Stefan, slightly extended.
sayer/1.4-spce2.6
Raphael Coeffic 15 years ago committed by Stefan Sayer
parent cf0e0486dc
commit e8da7b8945

@ -155,13 +155,15 @@ void trans_timer_cb(timer* t, unsigned int bucket_id, sip_trans* tr)
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);
// timer_expired unlocks the bucket
trans_layer::instance()->timer_expired(t,bucket,tr);
}
else {
WARN("Ignoring expired timer (%p): transaction"
" %p does not exist anymore\n",t,tr);
bucket->unlock();
}
bucket->unlock();
}
else {
ERROR("Invalid bucket id\n");

@ -747,9 +747,10 @@ void _trans_layer::timeout(trans_bucket* bucket, sip_trans* t)
msg.cseq = req->cseq;
msg.callid = req->callid;
ua->handle_sip_reply(&msg);
bucket->remove(t);
bucket->unlock();
ua->handle_sip_reply(&msg);
}
int _trans_layer::send_request(sip_msg* msg, trans_ticket* tt,
@ -1202,10 +1203,18 @@ void _trans_layer::received_msg(sip_msg* msg)
// Reply matched UAC transaction
DBG("Reply matched an existing transaction\n");
if(update_uac_reply(bucket,t,msg) < 0){
int res = update_uac_reply(bucket,t,msg);
if(res < 0){
ERROR("update_uac_trans() failed, so what happens now???\n");
break;
}
if (res) {
bucket->unlock();
ua->handle_sip_reply(msg);
DROP_MSG;
//return; - part of DROP_MSG
}
// do not touch the transaction anymore:
// it could have been deleted !!!
}
@ -1414,8 +1423,7 @@ int _trans_layer::update_uac_reply(trans_bucket* bucket, sip_trans* t, sip_msg*
}
pass_reply:
assert(ua);
ua->handle_sip_reply(msg);
return 1;
end:
return 0;
}
@ -1656,7 +1664,9 @@ void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr)
tr->clear_timer(STIMER_B);
if(tr->state == TS_CALLING) {
DBG("Transaction timeout!\n");
// unlocks the bucket
timeout(bucket,tr);
return;
}
else {
DBG("Transaction timeout timer hit while state=0x%x",tr->state);
@ -1697,8 +1707,9 @@ void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr)
case TS_TRYING:
case TS_PROCEEDING:
DBG("Transaction timeout!\n");
// unlocks the bucket
timeout(bucket,tr);
break;
return;
}
break;
@ -1787,7 +1798,7 @@ void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr)
// get the next ip
if(tr->msg->h_dns.next_ip(&sa) < 0){
tr->clear_timer(STIMER_M);
return;
break;
}
//If a SRV record is involved, the port number
@ -1822,6 +1833,8 @@ void _trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr)
ERROR("Invalid timer type %i\n",t->type);
break;
}
bucket->unlock();
}
/**

Loading…
Cancel
Save