From e2a1710eb1cbd26d171173503d13b55f17ac3b40 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Thu, 13 Aug 2009 19:18:03 +0000 Subject: QPID-1971 - bind in fedOpReorigen mode is not threadsafe for TopicExchange Applied patch from Ken Giusti. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@803996 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/broker/DirectExchange.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'cpp/src/qpid/broker/DirectExchange.cpp') diff --git a/cpp/src/qpid/broker/DirectExchange.cpp b/cpp/src/qpid/broker/DirectExchange.cpp index 454b497f11..b9f24dee5f 100644 --- a/cpp/src/qpid/broker/DirectExchange.cpp +++ b/cpp/src/qpid/broker/DirectExchange.cpp @@ -92,12 +92,24 @@ bool DirectExchange::bind(Queue::shared_ptr queue, const string& routingKey, con if (bk.fedBinding.count() == 0) unbind(queue, routingKey, 0); } else if (fedOp == fedOpReorigin) { - for (std::map::iterator iter = bindings.begin(); - iter != bindings.end(); iter++) { - const BoundKey& bk = iter->second; - if (bk.fedBinding.hasLocal()) { - propagateFedOp(iter->first, string(), fedOpBind, string()); + /** gather up all the keys that need rebinding in a local vector + * while holding the lock. Then propagate once the lock is + * released + */ + std::vector keys2prop; + { + Mutex::ScopedLock l(lock); + for (Bindings::iterator iter = bindings.begin(); + iter != bindings.end(); iter++) { + const BoundKey& bk = iter->second; + if (bk.fedBinding.hasLocal()) { + keys2prop.push_back(iter->first); + } } + } /* lock dropped */ + for (std::vector::const_iterator key = keys2prop.begin(); + key != keys2prop.end(); key++) { + propagateFedOp( *key, string(), fedOpBind, string()); } } -- cgit v1.2.1