summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2012-04-10 20:55:26 +0000
committerAlan Conway <aconway@apache.org>2012-04-10 20:55:26 +0000
commit89a1eb19653a817d2fd4dab8bf3df571af2d64c3 (patch)
treef2f023707181a5a93470ec933bf6bee446247847 /cpp
parentef86f6fa47148e4a6ec63051f7b53dab1e306da2 (diff)
downloadqpid-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.cpp47
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();
}