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 2009/11/17 22:13:38 UTC

svn commit: r881525 - /activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/transport/correlator/ResponseCorrelator.cpp

Author: tabish
Date: Tue Nov 17 21:13:38 2009
New Revision: 881525

URL: http://svn.apache.org/viewvc?rev=881525&view=rev
Log:
https://issues.apache.org/activemq/browse/AMQCPP-267

Fix potential leak in response correlator.

Modified:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/transport/correlator/ResponseCorrelator.cpp

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/transport/correlator/ResponseCorrelator.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/transport/correlator/ResponseCorrelator.cpp?rev=881525&r1=881524&r2=881525&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/transport/correlator/ResponseCorrelator.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/transport/correlator/ResponseCorrelator.cpp Tue Nov 17 21:13:38 2009
@@ -27,6 +27,30 @@
 using namespace decaf::io;
 using namespace decaf::lang;
 using namespace decaf::lang::exceptions;
+using namespace decaf::util::concurrent;
+
+namespace {
+
+    class ResponseFinalizer {
+    private:
+
+        Mutex* mutex;
+        int commandId;
+        std::map<unsigned int, Pointer<FutureResponse> >* map;
+
+    public:
+
+        ResponseFinalizer( Mutex* mutex, int commandId, std::map<unsigned int, Pointer<FutureResponse> >* map ) :
+            mutex( mutex ), commandId( commandId ), map( map ) {
+        }
+
+        ~ResponseFinalizer() {
+            synchronized( mutex ){
+                map->erase( commandId );
+            }
+        }
+    };
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 ResponseCorrelator::ResponseCorrelator( const Pointer<Transport>& next )
@@ -81,6 +105,9 @@
             requestMap.insert( make_pair( command->getCommandId(), futureResponse ) );
         }
 
+        // The finalizer will cleanup the map even if an exception is thrown.
+        ResponseFinalizer finalizer( &mapMutex, command->getCommandId(), &requestMap );
+
         // Wait to be notified of the response via the futureResponse
         // object.
         Pointer<commands::Response> response;
@@ -91,14 +118,6 @@
         // Get the response.
         response = futureResponse->getResponse();
 
-        // Perform cleanup on the map.
-        synchronized( &mapMutex ){
-
-            // We've done our waiting - get this thing out
-            // of the map.
-            requestMap.erase( command->getCommandId() );
-        }
-
         if( response == NULL ){
 
             throw IOException( __FILE__, __LINE__,
@@ -131,6 +150,9 @@
             requestMap.insert( make_pair( command->getCommandId(), futureResponse ) );
         }
 
+        // The finalizer will cleanup the map even if an exception is thrown.
+        ResponseFinalizer finalizer( &mapMutex, command->getCommandId(), &requestMap );
+
         // Wait to be notified of the response via the futureResponse
         // object.
         Pointer<commands::Response> response;
@@ -141,14 +163,6 @@
         // Get the response.
         response = futureResponse->getResponse( timeout );
 
-        // Perform cleanup on the map.
-        synchronized( &mapMutex ){
-
-            // We've done our waiting - get this thing out
-            // of the map.
-            requestMap.erase( command->getCommandId() );
-        }
-
         if( response == NULL ){
 
             throw IOException( __FILE__, __LINE__,