You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by gs...@apache.org on 2011/08/18 18:09:04 UTC

svn commit: r1159293 - /qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp

Author: gsim
Date: Thu Aug 18 16:09:03 2011
New Revision: 1159293

URL: http://svn.apache.org/viewvc?rev=1159293&view=rev
Log:
QPID-3435: Revised strategy for closing senders/receivers to prevent possible infinite loop

Modified:
    qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp

Modified: qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp?rev=1159293&r1=1159292&r2=1159293&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp Thu Aug 18 16:09:03 2011
@@ -60,12 +60,14 @@ SessionImpl::SessionImpl(ConnectionImpl&
 
 void SessionImpl::checkError()
 {
+    ScopedLock l(lock);
     qpid::client::SessionBase_0_10Access s(session);
     s.get()->assertOpen();
 }
 
 bool SessionImpl::hasError()
 {
+    ScopedLock l(lock);
     qpid::client::SessionBase_0_10Access s(session);
     return s.get()->hasError();
 }
@@ -129,27 +131,29 @@ void SessionImpl::close()
         senders.clear();
         receivers.clear();
     } else {
-        while (true) {
-            Sender s;
-            {
-                ScopedLock l(lock);
-                if (senders.empty()) break;
-                s = senders.begin()->second;
-            }
-            s.close();  // outside the lock, will call senderCancelled
+        Senders sCopy;
+        Receivers rCopy;
+        {
+            ScopedLock l(lock);
+            senders.swap(sCopy);
+            receivers.swap(rCopy);
         }
-        while (true) {
-            Receiver r;
-            {
-                ScopedLock l(lock);
-                if (receivers.empty()) break;
-                r = receivers.begin()->second;
-            }
-            r.close();  // outside the lock, will call receiverCancelled
+        for (Senders::iterator i = sCopy.begin(); i != sCopy.end(); ++i)
+        {
+            // outside the lock, will call senderCancelled
+            i->second.close();
+        }
+        for (Receivers::iterator i = rCopy.begin(); i != rCopy.end(); ++i)
+        {
+            // outside the lock, will call receiverCancelled
+            i->second.close();
         }
     }
     connection->closed(*this);
-    if (!hasError()) session.close();
+    if (!hasError()) {
+        ScopedLock l(lock);
+        session.close();
+    }
 }
 
 template <class T, class S> boost::intrusive_ptr<S> getImplPtr(T& t)



---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:commits-subscribe@qpid.apache.org