From ec959b384ce02e438ed89968c4449b12d7e20f74 Mon Sep 17 00:00:00 2001 From: "Charles E. Rolke" Date: Wed, 27 Mar 2013 15:15:26 +0000 Subject: 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 --- cpp/src/qpid/xml/XmlExchange.cpp | 13 ++++++++++--- cpp/src/qpid/xml/XmlExchange.h | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'cpp/src') 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 @@ -178,6 +178,12 @@ 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 @@ -185,11 +191,12 @@ bool XmlExchange::unbind(Queue::shared_ptr queue, const std::string& bindingKey, * * 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); }; -- cgit v1.2.1