[asterisk-scf-commits] asterisk-scf/integration/routing.git branch "master" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Fri Oct 15 15:21:14 CDT 2010


branch "master" has been updated
       via  a463ab8ecb76e29a31182414770378fd885b01b8 (commit)
      from  749f74b5a4faf5bccab919d85600729a8b233975 (commit)

Summary of changes:
 src/SessionRouter.cpp |  139 ++++++++++++++++++++++++++++++++++--------------
 1 files changed, 98 insertions(+), 41 deletions(-)


- Log -----------------------------------------------------------------
commit a463ab8ecb76e29a31182414770378fd885b01b8
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Fri Oct 15 15:20:31 2010 -0500

    Fix the removal of session listener.

diff --git a/src/SessionRouter.cpp b/src/SessionRouter.cpp
index f61d58d..3f1a501 100644
--- a/src/SessionRouter.cpp
+++ b/src/SessionRouter.cpp
@@ -36,20 +36,29 @@ namespace BasicRoutingService
 class SessionListenerImpl : public SessionListener
 {
 public:
-    SessionListenerImpl(Ice::ObjectAdapterPtr adapter, const SessionPrx& source) : 
+    SessionListenerImpl(Ice::ObjectAdapterPtr adapter, const SessionPrx& session) : 
         mAdapter(adapter), mTerminated(false), mListenerPrx(0)
     {
         Ice::ObjectPrx prx = adapter->addWithUUID(this);
         mListenerPrx = SessionListenerPrx::checkedCast(prx);
 
-        addSession(source);
+        addSession(session);
     }
 
-    ~SessionListenerImpl()
+    SessionListenerImpl(Ice::ObjectAdapterPtr adapter, SessionSeq& sessionSequence) : 
+        mAdapter(adapter), mTerminated(false), mListenerPrx(0)
     {
-       unregister();
+        Ice::ObjectPrx prx = adapter->addWithUUID(this);
+        mListenerPrx = SessionListenerPrx::checkedCast(prx);
+
+        for(SessionSeq::iterator s = sessionSequence.begin(); s != sessionSequence.end(); ++s)
+        {
+           addSession(*s);
+        }
+    }
 
-       mAdapter->remove(mListenerPrx->ice_getIdentity());
+    ~SessionListenerImpl()
+    {
     }
 
     void connected(const SessionPrx& session, const Ice::Current&)
@@ -96,7 +105,13 @@ public:
 
         if (mListenerPrx != 0)
         {
-            session->addListener(mListenerPrx);
+            try
+            {
+                session->addListener(mListenerPrx);
+            }
+            catch(...)
+            {
+            }
         }
     }
 
@@ -134,6 +149,56 @@ private:
 };
 typedef IceInternal::Handle<SessionListenerImpl> SessionListenerImplPtr;
 
+/**
+ * This class uses RAII to manage the lifecycle of a session listener. 
+ * 
+ */
+class SessionListenerAllocator
+{
+public:
+    SessionListenerAllocator(Ice::ObjectAdapterPtr adapter, const SessionPrx& session) 
+        : mSessionListener(new SessionListenerImpl(adapter, session)),
+          mAdapter(adapter)
+    {
+    }
+
+    SessionListenerAllocator(Ice::ObjectAdapterPtr adapter, SessionSeq& sessionSequence) 
+        : mSessionListener(new SessionListenerImpl(adapter, sessionSequence)),
+          mAdapter(adapter)
+    {
+    }
+
+    ~SessionListenerAllocator()
+    {
+       try
+       {
+           mSessionListener->unregister();
+       }
+       catch(...)
+       {
+       }
+
+       try
+       {
+           // Only the adapter holds a smart pointer for this servant, so this will
+           // cause it to be delted. 
+           mAdapter->remove(mSessionListener->getProxy()->ice_getIdentity());
+       }
+       catch(...)
+       {
+       }
+    }
+
+	SessionListenerImpl* operator->()
+	{
+		return mSessionListener;
+	}
+
+private:
+    SessionListenerImpl *mSessionListener;
+    Ice::ObjectAdapterPtr mAdapter;
+};
+
 class SessionRouterPriv
 {
 public: 
@@ -230,7 +295,9 @@ void SessionRouter::routeSession(const AsteriskSCF::SessionCommunications::V1::S
   const Ice::Current& current)
 {
     // Create a listener for the source to handle early termination. 
-    SessionListenerImplPtr listener = new SessionListenerImpl(mImpl->mAdapter, source); 
+    // The wrapper we're using will remove the listener and free it when 
+    // this method is left. 
+    SessionListenerAllocator listener(mImpl->mAdapter, source); 
 
     // Route the destination
     EndpointSeq endpoints = mImpl->lookupEndpoints(destination, current);
@@ -315,25 +382,20 @@ void SessionRouter::connectBridgedSessionsWithDestination(const SessionPrx& sess
        throw e; // rethrow
     }
 
-    // Add a listener to the sessions not being replaced to handle early termination.
-    SessionListenerImplPtr listener(0);
-    SessionPrx source(0);
+    SessionSeq remainingSessions;
     for(SessionSeq::iterator s = seq.begin(); s !=seq.end(); ++s)
     {
-        if (sessionToReplace->ice_getIdentity() != (*s)->ice_getIdentity()) // Only listening to the session NOT being dropped out of bridge.
+        if (sessionToReplace->ice_getIdentity() != (*s)->ice_getIdentity()) // Don't listen to the session being replaced.
         {
-            if (listener == 0)
-            {
-                source = (*s);
-                listener = new SessionListenerImpl(mImpl->mAdapter, *s);  
-            }
-            else
-            { 
-                listener->addSession(*s);
-            }
+            remainingSessions.push_back(*s);
         }
     }
 
+    // Create a listener for the sessions not being replaced to handle early termination. 
+    // The wrapper we're using will remove the listener and free it when 
+    // this method is left. 
+    SessionListenerAllocator listener(mImpl->mAdapter, remainingSessions); 
+
     // Route the destination
     EndpointSeq endpoints = mImpl->lookupEndpoints(destination, current);
 
@@ -367,7 +429,7 @@ void SessionRouter::connectBridgedSessionsWithDestination(const SessionPrx& sess
     if (listener->isTerminated())
     {
         lg(Notice) << "Source ended session before transfer in connectBridgedSessionsWithDestination(). " ;
-        throw SourceTerminatedPreBridgingException(source->getEndpoint()->getId());
+        throw SourceTerminatedPreBridgingException(remainingSessions[0]->getEndpoint()->getId());
     }
 
     // Modify the bridge
@@ -383,7 +445,7 @@ void SessionRouter::connectBridgedSessionsWithDestination(const SessionPrx& sess
 
         lg(Error) << "Exception replacing the session in connectBridgedSessionsWithDestination. " << e.what() ;
 
-        throw BridgingException(source->getEndpoint()->getId(), destination);
+        throw BridgingException(remainingSessions[0]->getEndpoint()->getId(), destination);
     }
 
     mImpl->forwardStart(newSessions);
@@ -423,7 +485,14 @@ void SessionRouter::connectBridgedSessions(const SessionPrx& sessionToReplace,
     SessionSeq preserveSessions;
     try
     {
-        preserveSessions = mergeBridge->listSessions();
+        SessionSeq sourceSessions = mergeBridge->listSessions();
+        for(SessionSeq::iterator s = sourceSessions.begin(); s !=sourceSessions.end(); ++s)
+        {
+            if (sessionToReplace->ice_getIdentity() != (*s)->ice_getIdentity())
+            {
+                preserveSessions.push_back(*s);
+            }
+        }
     }
     catch(const Ice::Exception &e)
     {
@@ -431,23 +500,11 @@ void SessionRouter::connectBridgedSessions(const SessionPrx& sessionToReplace,
        throw e; // rethrow
     }
 
-    // Add a listener to the session not being replaced to handle early termination.
-    SessionListenerImplPtr listener(0);
-    SessionPrx source(0);
-    for(SessionSeq::iterator s = preserveSessions.begin(); s !=preserveSessions.end(); ++s)
-    {
-        if (sessionToReplace->ice_getIdentity() != (*s)->ice_getIdentity())
-        {
-            if (listener == 0)
-            {
-                listener = new SessionListenerImpl(mImpl->mAdapter, *s);   // Only listening to sessions NOT being replaced.
-            }
-            else
-            { 
-                listener->addSession(*s);
-            }
-        }
-    }
+
+    // Create a listener for the sessions not being replaced to handle early termination. 
+    // The wrapper we're using will remove the listener and free it when 
+    // this method is left. 
+    SessionListenerAllocator listener(mImpl->mAdapter, preserveSessions); 
 
     // Get the bridge for the sessions being moved. 
     BridgePrx oldBridge(0);
@@ -464,7 +521,7 @@ void SessionRouter::connectBridgedSessions(const SessionPrx& sessionToReplace,
     if (listener->isTerminated())
     {
         lg(Notice) << "Source ended session before transfer in connectBridgedSessions(). " ;
-        throw SourceTerminatedPreBridgingException(source->getEndpoint()->getId());
+        throw SourceTerminatedPreBridgingException(preserveSessions[0]->getEndpoint()->getId());
     }
 
     SessionSeq migratingSessions;

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


-- 
asterisk-scf/integration/routing.git



More information about the asterisk-scf-commits mailing list