From 39f068763c649f63f2c42ab19e76d4f76d612ff5 Mon Sep 17 00:00:00 2001 From: Ted Ross Date: Fri, 13 Jan 2012 16:20:11 +0000 Subject: QPID-3755 - Concurrent queue bind on the same queue results in crash git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1231158 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/broker/QueueBindings.cpp | 10 ++++++++-- cpp/src/qpid/broker/QueueBindings.h | 11 ++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) (limited to 'cpp/src') diff --git a/cpp/src/qpid/broker/QueueBindings.cpp b/cpp/src/qpid/broker/QueueBindings.cpp index 60d315acfe..c6b3ddf9a9 100644 --- a/cpp/src/qpid/broker/QueueBindings.cpp +++ b/cpp/src/qpid/broker/QueueBindings.cpp @@ -30,16 +30,22 @@ using namespace qpid::broker; void QueueBindings::add(const string& exchange, const string& key, const FieldTable& args) { + sys::Mutex::ScopedLock l(lock); bindings.push_back(QueueBinding(exchange, key, args)); } void QueueBindings::unbind(ExchangeRegistry& exchanges, Queue::shared_ptr queue) { - for (Bindings::iterator i = bindings.begin(); i != bindings.end(); i++) { + Bindings local; + { + sys::Mutex::ScopedLock l(lock); + local = bindings; + } + + for (Bindings::iterator i = local.begin(); i != local.end(); i++) try { exchanges.get(i->exchange)->unbind(queue, i->key, &(i->args)); } catch (const NotFoundException&) {} - } } QueueBinding::QueueBinding(const string& _exchange, const string& _key, const FieldTable& _args) diff --git a/cpp/src/qpid/broker/QueueBindings.h b/cpp/src/qpid/broker/QueueBindings.h index 1b90ba5540..f9b07e7431 100644 --- a/cpp/src/qpid/broker/QueueBindings.h +++ b/cpp/src/qpid/broker/QueueBindings.h @@ -22,6 +22,7 @@ #define _QueueBindings_ #include "qpid/framing/FieldTable.h" +#include "qpid/sys/Mutex.h" #include #include #include @@ -44,12 +45,20 @@ class QueueBindings public: /** Apply f to each QueueBinding. */ - template void eachBinding(F f) const { std::for_each(bindings.begin(), bindings.end(), f); } + template void eachBinding(F f) const { + Bindings local; + { + sys::Mutex::ScopedLock l(lock); + local = bindings; + } + std::for_each(local.begin(), local.end(), f); + } void add(const std::string& exchange, const std::string& key, const qpid::framing::FieldTable& args); void unbind(ExchangeRegistry& exchanges, boost::shared_ptr queue); private: + mutable sys::Mutex lock; typedef std::vector Bindings; Bindings bindings; }; -- cgit v1.2.1