diff options
author | Alan Conway <aconway@apache.org> | 2012-04-10 20:55:26 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2012-04-10 20:55:26 +0000 |
commit | 89a1eb19653a817d2fd4dab8bf3df571af2d64c3 (patch) | |
tree | f2f023707181a5a93470ec933bf6bee446247847 /cpp | |
parent | ef86f6fa47148e4a6ec63051f7b53dab1e306da2 (diff) | |
download | qpid-python-89a1eb19653a817d2fd4dab8bf3df571af2d64c3.tar.gz |
QPID-3603: Fix race condition - destroying a lock while in use.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1311988 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/qpid/broker/Link.cpp | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/cpp/src/qpid/broker/Link.cpp b/cpp/src/qpid/broker/Link.cpp index 56a90e7fb7..c90e748077 100644 --- a/cpp/src/qpid/broker/Link.cpp +++ b/cpp/src/qpid/broker/Link.cpp @@ -202,31 +202,34 @@ void Link::opened() { void Link::closed(int, std::string text) { - Mutex::ScopedLock mutex(lock); - QPID_LOG (info, "Inter-broker link disconnected from " << host << ":" << port << " " << text); - - connection = 0; - if (state == STATE_OPERATIONAL) { - stringstream addr; - addr << host << ":" << port; - if (!hideManagement() && agent) - agent->raiseEvent(_qmf::EventBrokerLinkDown(addr.str())); - } + bool isClosing = false; + { + Mutex::ScopedLock mutex(lock); + QPID_LOG (info, "Inter-broker link disconnected from " << host << ":" << port << " " << text); - for (Bridges::iterator i = active.begin(); i != active.end(); i++) { - (*i)->closed(); - created.push_back(*i); - } - active.clear(); + connection = 0; + if (state == STATE_OPERATIONAL) { + stringstream addr; + addr << host << ":" << port; + if (!hideManagement() && agent) + agent->raiseEvent(_qmf::EventBrokerLinkDown(addr.str())); + } - if (state != STATE_FAILED && state != STATE_PASSIVE) - { - setStateLH(STATE_WAITING); - if (!hideManagement()) - mgmtObject->set_lastError (text); - } + for (Bridges::iterator i = active.begin(); i != active.end(); i++) { + (*i)->closed(); + created.push_back(*i); + } + active.clear(); - if (closing) + if (state != STATE_FAILED && state != STATE_PASSIVE) + { + setStateLH(STATE_WAITING); + if (!hideManagement()) + mgmtObject->set_lastError (text); + } + } + // Call destroy outside of the lock, don't want to be deleted with lock held. + if (isClosing) destroy(); } |