[asterisk-scf-commits] asterisk-scf/release/sip.git branch "master" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Fri Jun 15 13:57:23 CDT 2012


branch "master" has been updated
       via  4bcc38bbb526a17215d53c1791b8ea1493fb4a85 (commit)
      from  9f493878cda3744160f72866833a80f451837642 (commit)

Summary of changes:
 src/PJSIPSessionModule.cpp |   28 ++++++++++++++++++----------
 src/PJSIPSessionModule.h   |   12 ++++++++++++
 src/SIPSession.cpp         |   15 +++++++++++++++
 3 files changed, 45 insertions(+), 10 deletions(-)


- Log -----------------------------------------------------------------
commit 4bcc38bbb526a17215d53c1791b8ea1493fb4a85
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Jun 15 16:26:29 2012 -0230

    Fix a race condition between PJSIPSessionModule's handling of some helper
    classes and the SIPSession itself. The former was deleting the latter, with
    the latter still being around to use it. Bad form wot?

diff --git a/src/PJSIPSessionModule.cpp b/src/PJSIPSessionModule.cpp
index 064a5ff..93593a6 100644
--- a/src/PJSIPSessionModule.cpp
+++ b/src/PJSIPSessionModule.cpp
@@ -99,11 +99,6 @@ PJSIPSessionModInfo::PJSIPSessionModInfo(pjsip_inv_session *inv_session,
 
 PJSIPSessionModInfo::~PJSIPSessionModInfo()
 {
-    if (mSession)
-    {
-        mSession->destroy();
-        mSession = 0;
-    }
 }
 
 void PJSIPSessionModInfo::updateSessionState(pjsip_inv_session *inv_session)
@@ -114,14 +109,14 @@ void PJSIPSessionModInfo::updateSessionState(pjsip_inv_session *inv_session)
         mSessionState->endpointName = mSession->getEndpoint()->getName();
         mSessionState->sessionObjectId = mSession->getSessionProxy()->ice_getIdentity();
         mSessionState->mediaSessionObjectId = mSession->getMediaSessionProxy()->ice_getIdentity();
-	    mSessionState->sessionControllerObjectId = mSession->getOurSessionControllerProxy()->ice_getIdentity();
+        mSessionState->sessionControllerObjectId = mSession->getOurSessionControllerProxy()->ice_getIdentity();
         mSessionState->originalContext = mSession->getOperationContext();
         mSessionState->sources = mSession->getMediaSources();
         mSessionState->sinks = mSession->getMediaSinks();
         mSessionState->rtpMediaSessions = mSession->getRTPMediaSessions();
         mSessionState->udptlMediaSessions = mSession->getUDPTLMediaSessions();
         mSessionState->listeners = mSession->getListeners();
-	    mSessionState->streams = mSession->getStreams();
+        mSessionState->streams = mSession->getStreams();
         try
         {
             mSessionState->bridge = mSession->getBridge();
@@ -198,6 +193,20 @@ SessionWorkPtr PJSIPSessionModInfo::getSessionWork()
     return mSessionWork;
 }
 
+void PJSIPSessionModInfo::destroy()
+{
+    SIPSessionPtr t;
+    {
+        boost::unique_lock<boost::shared_mutex> lock(mLock);
+        t = mSession;
+        mSession = 0;
+    }
+    if (t)
+    {
+        t->destroy();
+    }
+}
+
 SIPSessionCreationExtensionPoint::SIPSessionCreationExtensionPoint() :
     mOperationContextCache(OperationContextCache::create(120))
 {
@@ -1884,12 +1893,11 @@ protected:
             }
             lg(Debug) << "Replicating state on DISCONNECTED inv_state.";
             mSessionModule->replicateState(dlg_mod_info, NULL, session_mod_info);
-            mInv->mod_data[mSessionModule->getModule().id] = 0;
-            delete session_mod_info;
+            session_mod_info->destroy();
             if (dlg_mod_info)
             {
-                delete dlg_mod_info;
                 dlg->mod_data[mSessionModule->getModule().id] = 0;
+                delete dlg_mod_info;
             }
         }
         if (mEventType == PJSIP_EVENT_RX_MSG && mInvState == PJSIP_INV_STATE_CONFIRMED)
diff --git a/src/PJSIPSessionModule.h b/src/PJSIPSessionModule.h
index 91fb6e4..bddb492 100644
--- a/src/PJSIPSessionModule.h
+++ b/src/PJSIPSessionModule.h
@@ -49,8 +49,20 @@ public:
     SIPSessionPtr getSessionPtr();
     void setSessionPtr(const SIPSessionPtr& sessionPtr);
     SessionWorkPtr getSessionWork();
+
+    //
+    // The PJSIP call should not destroy this object directly (ie. you should
+    // not see a delete anywhere!) It needs to tell it to run through the
+    // destroy protocol. How that works is it removes a reference to the
+    // session object from itself and calls destroy on the session. The Session
+    // object will take care of cleaning it up from the pjsip library.
+    // Hack'ish, I know but it's broken the way it is now!
+    //
+    void destroy();
+
     SIPSessionStateItemPtr mSessionState;
     SIPInviteSessionStateItemPtr mInviteState;
+
     bool mNeedsReplication;
     bool mNeedsRemoval;
     boost::shared_mutex mLock;
diff --git a/src/SIPSession.cpp b/src/SIPSession.cpp
index a963e9a..1a86101 100755
--- a/src/SIPSession.cpp
+++ b/src/SIPSession.cpp
@@ -3325,6 +3325,21 @@ public:
             }
         }
         mSessionPriv->mEndpoint->removeSession(mSession);
+
+        //
+        // We moved the clean up of this object to here to avoid conflicts between pjsip originating operations
+        // and the pending operations in the session object. The only other way to do it would've been to have
+        // cancelled and replaced all the pending operations... a bigger deal by far.
+        //
+        if (mSessionPriv->mInviteSession)
+        {
+            PJSIPSessionModInfo *session_mod_info =
+                static_cast<PJSIPSessionModInfo*>(
+                    mSessionPriv->mInviteSession->mod_data[mSessionPriv->mManager->getSessionModule()->getModule().id]);
+            mSessionPriv->mInviteSession->mod_data[mSessionPriv->mManager->getSessionModule()->getModule().id] = 0;
+            delete session_mod_info;
+        }
+
         return Complete;
     }
 

-----------------------------------------------------------------------


-- 
asterisk-scf/release/sip.git



More information about the asterisk-scf-commits mailing list