[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