You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2012/10/03 17:30:53 UTC

svn commit: r1393545 - in /activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core: ActiveMQConnection.cpp kernels/ActiveMQSessionKernel.cpp

Author: tabish
Date: Wed Oct  3 15:30:53 2012
New Revision: 1393545

URL: http://svn.apache.org/viewvc?rev=1393545&view=rev
Log:
The dispose methods need to take a copy of their collections for iterating to avoid ConcurrentModiciationException. 

Modified:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core/ActiveMQConnection.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core/kernels/ActiveMQSessionKernel.cpp

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core/ActiveMQConnection.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core/ActiveMQConnection.cpp?rev=1393545&r1=1393544&r2=1393545&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core/ActiveMQConnection.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core/ActiveMQConnection.cpp Wed Oct  3 15:30:53 2012
@@ -590,22 +590,36 @@ void ActiveMQConnection::close() {
             }
         }
 
+        long long lastDeliveredSequenceId = 0;
+
         // Get the complete list of active sessions.
-        this->config->sessionsLock.writeLock().lock();
-        std::auto_ptr< Iterator<Pointer<ActiveMQSessionKernel> > > iter(this->config->activeSessions.iterator());
+        try {
+            this->config->sessionsLock.writeLock().lock();
 
-        long long lastDeliveredSequenceId = 0;
+            // We need to use a copy since we aren't able to use CopyOnWriteArrayList
+            ArrayList<Pointer<ActiveMQSessionKernel> > sessions(this->config->activeSessions);
+            std::auto_ptr<Iterator<Pointer<ActiveMQSessionKernel> > > iter(sessions.iterator());
 
-        // Dispose of all the Session resources we know are still open.
-        while (iter->hasNext()) {
-            Pointer<ActiveMQSessionKernel> session = iter->next();
-            try {
-                session->dispose();
-                lastDeliveredSequenceId = Math::max(lastDeliveredSequenceId, session->getLastDeliveredSequenceId());
-            } catch (cms::CMSException& ex) {
+            // Dispose of all the Session resources we know are still open.
+            while (iter->hasNext()) {
+                Pointer<ActiveMQSessionKernel> session = iter->next();
+                try {
+                    session->dispose();
+                    lastDeliveredSequenceId = Math::max(lastDeliveredSequenceId, session->getLastDeliveredSequenceId());
+                } catch (cms::CMSException& ex) {
+                }
+            }
+
+            this->config->activeSessions.clear();
+            this->config->sessionsLock.writeLock().unlock();
+        } catch(Exception& error) {
+            this->config->sessionsLock.writeLock().unlock();
+            if (!hasException) {
+                ex = error;
+                ex.setMark(__FILE__, __LINE__);
+                hasException = true;
             }
         }
-        this->config->sessionsLock.writeLock().unlock();
 
         // As TemporaryQueue and TemporaryTopic instances are bound to a connection
         // we should just delete them after the connection is closed to free up memory

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core/kernels/ActiveMQSessionKernel.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core/kernels/ActiveMQSessionKernel.cpp?rev=1393545&r1=1393544&r2=1393545&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core/kernels/ActiveMQSessionKernel.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/core/kernels/ActiveMQSessionKernel.cpp Wed Oct  3 15:30:53 2012
@@ -342,7 +342,10 @@ void ActiveMQSessionKernel::dispose() {
         // Dispose of all Consumers, the dispose method skips the RemoveInfo command.
         this->config->consumerLock.writeLock().lock();
         try {
-            Pointer<Iterator< Pointer<ActiveMQConsumerKernel> > > consumerIter(this->config->consumers.iterator());
+            // We have to copy all the consumers to another list since we aren't using a
+            // CopyOnWriteArrayList right now.
+            ArrayList<Pointer<ActiveMQConsumerKernel> > consumers(this->config->consumers);
+            Pointer<Iterator< Pointer<ActiveMQConsumerKernel> > > consumerIter(consumers.iterator());
             while (consumerIter->hasNext()) {
                 try{
                     Pointer<ActiveMQConsumerKernel> consumer = consumerIter->next();
@@ -361,10 +364,13 @@ void ActiveMQSessionKernel::dispose() {
             throw;
         }
 
+        // Dispose of all Producers, the dispose method skips the RemoveInfo command.
         this->config->producerLock.writeLock().lock();
         try {
-            // Dispose of all Producers, the dispose method skips the RemoveInfo command.
-            std::auto_ptr<Iterator<Pointer<ActiveMQProducerKernel> > > producerIter(this->config->producers.iterator());
+            // We have to copy all the producers to another list since we aren't using a
+            // CopyOnWriteArrayList right now.
+            ArrayList<Pointer<ActiveMQProducerKernel> > producers(this->config->producers);
+            std::auto_ptr<Iterator<Pointer<ActiveMQProducerKernel> > > producerIter(producers.iterator());
 
             while (producerIter->hasNext()) {
                 try{