[asterisk-scf-commits] asterisk-scf/integration/bridging.git branch "transfer" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Wed Oct 13 11:56:35 CDT 2010


branch "transfer" has been updated
       via  3db2d797682558f57434654fd64f8f8295d31a64 (commit)
      from  b5d1c9aa263ce7b70b6d2a7bfc97257c833faf59 (commit)

Summary of changes:
 src/MediaSplicer.cpp |   99 ++++++++++++++++++++++++++++++++++++++++++--------
 src/MediaSplicer.h   |    1 +
 2 files changed, 85 insertions(+), 15 deletions(-)


- Log -----------------------------------------------------------------
commit 3db2d797682558f57434654fd64f8f8295d31a64
Author: Brent Eagles <beagles at digium.com>
Date:   Wed Oct 13 14:25:25 2010 -0230

    Add some locking to media parts to prevent corruption of the connector objects.
    Also added some reaping logic and locking to the splicer for the same reason.

diff --git a/src/MediaSplicer.cpp b/src/MediaSplicer.cpp
index 95ac18c..6332bdb 100644
--- a/src/MediaSplicer.cpp
+++ b/src/MediaSplicer.cpp
@@ -22,13 +22,19 @@ namespace BridgeService
     typedef std::pair<Media::V1::StreamSinkPrx, Media::V1::StreamSourcePrx> OutgoingPairing;
     typedef std::pair<Media::V1::StreamSourcePrx, Media::V1::StreamSinkPrx> IncomingPairing;
 
+    //
+    // TODO: These proxies could use some retry properties added to them...
+    // particularily for the media stream connect/disconnect operations.
+    //
+
     class MediaConnectorI : public MediaConnector
     {
     public:
 
         MediaConnectorI(const std::vector<OutgoingPairing>& outgoing, const std::vector<IncomingPairing>& incoming):
             mOutgoing(outgoing),
-            mIncoming(incoming)
+            mIncoming(incoming),
+            mConnected(true)
         {
             for(std::vector<OutgoingPairing>::iterator i = mOutgoing.begin(); i != mOutgoing.end(); ++i)
             {
@@ -44,21 +50,68 @@ namespace BridgeService
 
         void unplug()
         {
-            for(std::vector<OutgoingPairing>::iterator i = mOutgoing.begin(); i != mOutgoing.end(); ++i)
+            std::vector<OutgoingPairing> outgoing;
+            std::vector<IncomingPairing> incoming;
             {
-                i->second->setSink(0);
-                i->first->setSource(0);
+                IceUtil::Mutex::Lock lock(mMutex);
+                outgoing.swap(mOutgoing);
+                mOutgoing.clear();
+                incoming.swap(mIncoming);
+                mIncoming.clear();
             }
-            for(std::vector<IncomingPairing>::iterator i = mIncoming.begin(); i != mIncoming.end(); ++i)
+
+
+            //
+            // Disconnect everybody, eating up exceptions in case things have gone away. This is a perfect spot 
+            // for oneways or, at the very least, AMI.
+            //
+            for(std::vector<OutgoingPairing>::iterator i = outgoing.begin(); i != outgoing.end(); ++i)
             {
-                i->first->setSink(0);
-                i->second->setSource(0);
+                try
+                {
+                    i->second->setSink(0);
+                }
+                catch(const Ice::Exception&)
+                {
+                }
+                try
+                {
+                    i->first->setSource(0);
+                }
+                catch(const Ice::Exception&)
+                {
+                }
+            }
+            for(std::vector<IncomingPairing>::iterator i = incoming.begin(); i != incoming.end(); ++i)
+            {
+                try
+                {
+                    i->first->setSink(0);
+                }
+                catch(const Ice::Exception&)
+                {
+                }
+                try
+                {
+                    i->second->setSource(0);
+                }
+                catch(const Ice::Exception&)
+                {
+                }
             }
         }
 
+        bool isConnected()
+        {
+            IceUtil::Mutex::Lock lock(mMutex);
+            return mConnected;
+        }
+
     private:
+        IceUtil::Mutex mMutex;
         std::vector<OutgoingPairing> mOutgoing;
         std::vector<IncomingPairing> mIncoming;
+        bool mConnected;
     };
 
     //
@@ -76,15 +129,29 @@ namespace BridgeService
             {
                 return 0;
             }
-            
 
-            MediaSessions::iterator existing = std::find_if(mSessions.begin(), mSessions.end(), FindImpl(media));
-            if(existing != mSessions.end())
+            IceUtil::Mutex::Lock lock(mMutex);
+            MediaConnectorPtr result;
+
+            //
+            // Loop through looking for an identical media session, also reaping disconnected connectors as we go.
+            //
+            for(MediaSessions::iterator i = mSessions.begin(); i != mSessions.end(); ++i)
+            {
+                if(!i->connector->isConnected())
+                {
+                    MediaSessions::iterator t = i;
+                    mSessions.erase(t);
+                    continue;
+                }
+                if(i->mediaSession == media)
+                {
+                    result = i->connector;
+                }
+            }
+            if(result)
             {
-                //
-                // TODO: Needs to throw some kind of media connect error. For now, we will simply return the connector
-                //
-                return existing->connector;
+                return result;
             }
 
             //
@@ -98,13 +165,15 @@ namespace BridgeService
             std::vector<OutgoingPairing> outgoingPairings(findCompatiblePairings(sinks));
             std::vector<IncomingPairing> incomingPairings(findCompatiblePairings(sources));
 
-            MediaConnectorPtr result(new MediaConnectorI(outgoingPairings, incomingPairings));
+            result = new MediaConnectorI(outgoingPairings, incomingPairings);
             mSessions.push_back(MediaSessionStruct(media, result));
             return result;
         }
 
     private:
 
+        IceUtil::Mutex mMutex;
+
         struct MediaSessionStruct 
         {
             Media::V1::SessionPrx mediaSession;
diff --git a/src/MediaSplicer.h b/src/MediaSplicer.h
index ac7276c..e4d1b77 100644
--- a/src/MediaSplicer.h
+++ b/src/MediaSplicer.h
@@ -21,6 +21,7 @@ namespace BridgeService
     public:
         virtual ~MediaConnector() {}
         virtual void unplug() = 0;
+        virtual bool isConnected() = 0;
     };
 
     typedef IceUtil::Handle<MediaConnector> MediaConnectorPtr;

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


-- 
asterisk-scf/integration/bridging.git



More information about the asterisk-scf-commits mailing list