diff options
| author | Charles E. Rolke <chug@apache.org> | 2013-03-27 15:15:26 +0000 |
|---|---|---|
| committer | Charles E. Rolke <chug@apache.org> | 2013-03-27 15:15:26 +0000 |
| commit | ec959b384ce02e438ed89968c4449b12d7e20f74 (patch) | |
| tree | b97c2dfc06c64a46b4a4397914518c9eafe8386b /cpp/src | |
| parent | 83f7572676acd64993cf1c4692f01731b88963cf (diff) | |
| download | qpid-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.cpp | 13 | ||||
| -rw-r--r-- | cpp/src/qpid/xml/XmlExchange.h | 2 |
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); }; |
