Module: sems
Branch: master
Commit: 1645a7d3c6bcf566cd5aa2a8c1a9d3dabaa8dafc
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=1645a7d3c6bcf566cd5aa2a8c1a9d3dabaa8dafc

Author: Raphael Coeffic <[email protected]>
Committer: Raphael Coeffic <[email protected]>
Date:   Thu Jan 26 12:28:49 2012 +0100

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

Original patch by Stefan, slightly extended.

---

 core/sip/sip_trans.cpp   |    4 +++-
 core/sip/trans_layer.cpp |   27 ++++++++++++++++++++-------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/core/sip/sip_trans.cpp b/core/sip/sip_trans.cpp
index 375b531..82c0e24 100644
--- a/core/sip/sip_trans.cpp
+++ b/core/sip/sip_trans.cpp
@@ -154,13 +154,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");
diff --git a/core/sip/trans_layer.cpp b/core/sip/trans_layer.cpp
index 823f9a9..2e8effd 100644
--- a/core/sip/trans_layer.cpp
+++ b/core/sip/trans_layer.cpp
@@ -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,
@@ -1204,10 +1205,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 !!!
        }
@@ -1406,8 +1415,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;
 }
@@ -1648,7 +1656,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);
@@ -1664,8 +1674,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;
 
@@ -1751,7 +1762,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
@@ -1786,6 +1797,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();
 }
 
 /**

_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to