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__,