summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorCharles E. Rolke <chug@apache.org>2013-03-27 15:15:26 +0000
committerCharles E. Rolke <chug@apache.org>2013-03-27 15:15:26 +0000
commitec959b384ce02e438ed89968c4449b12d7e20f74 (patch)
treeb97c2dfc06c64a46b4a4397914518c9eafe8386b /cpp/src
parent83f7572676acd64993cf1c4692f01731b88963cf (diff)
downloadqpid-python-ec959b384ce02e438ed89968c4449b12d7e20f74.tar.gz
QPID-4672: C++ Broker deadlock in XmlExchange unbind
Unbind functions get the Wlock directly and do not get Rlock first. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1461634 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/qpid/xml/XmlExchange.cpp13
-rw-r--r--cpp/src/qpid/xml/XmlExchange.h2
2 files changed, 12 insertions, 3 deletions
diff --git a/cpp/src/qpid/xml/XmlExchange.cpp b/cpp/src/qpid/xml/XmlExchange.cpp
index fb6c326327..29c00d9c12 100644
--- a/cpp/src/qpid/xml/XmlExchange.cpp
+++ b/cpp/src/qpid/xml/XmlExchange.cpp
@@ -179,17 +179,24 @@ bool XmlExchange::bind(Queue::shared_ptr queue, const std::string& bindingKey, c
bool XmlExchange::unbind(Queue::shared_ptr queue, const std::string& bindingKey, const FieldTable* args)
{
+ RWlock::ScopedWlock l(lock);
+ return unbindLH(queue, bindingKey, args);
+}
+
+bool XmlExchange::unbindLH(Queue::shared_ptr queue, const std::string& bindingKey, const FieldTable* args)
+{
/*
* When called directly, no qpidFedOrigin argument will be
* present. When called from federation, it will be present.
*
* This is a bit of a hack - the binding needs the origin, but
* this interface, as originally defined, would not supply one.
+ *
+ * Note: caller must hold Wlock
*/
std::string fedOrigin;
if (args) fedOrigin = args->getAsString(qpidFedOrigin);
- RWlock::ScopedWlock l(lock);
if (bindingsMap[bindingKey].remove_if(MatchQueueAndOrigin(queue, fedOrigin))) {
if (mgmtExchange != 0) {
mgmtExchange->dec_bindingCount();
@@ -389,9 +396,9 @@ void XmlExchange::propagateFedOp(const std::string& bindingKey, const std::strin
bool XmlExchange::fedUnbind(const std::string& fedOrigin, const std::string& fedTags, Queue::shared_ptr queue, const std::string& bindingKey, const FieldTable* args)
{
- RWlock::ScopedRlock l(lock);
+ RWlock::ScopedWlock l(lock);
- if (unbind(queue, bindingKey, args)) {
+ if (unbindLH(queue, bindingKey, args)) {
propagateFedOp(bindingKey, fedTags, fedOpUnbind, fedOrigin);
return true;
}
diff --git a/cpp/src/qpid/xml/XmlExchange.h b/cpp/src/qpid/xml/XmlExchange.h
index 7b04781ad5..fd3f8d0278 100644
--- a/cpp/src/qpid/xml/XmlExchange.h
+++ b/cpp/src/qpid/xml/XmlExchange.h
@@ -107,6 +107,8 @@ class XmlExchange : public virtual Exchange {
bool operator()(XmlBinding::shared_ptr b);
};
+ private:
+ bool unbindLH(Queue::shared_ptr queue, const std::string& routingKey, const qpid::framing::FieldTable* args);
};