Author: aconway
Date: Tue Apr 10 20:55:26 2012
New Revision: 1311988

URL: http://svn.apache.org/viewvc?rev=1311988&view=rev
Log:
QPID-3603: Fix race condition - destroying a lock while in use.

Modified:
    qpid/trunk/qpid/cpp/src/qpid/broker/Link.cpp

Modified: qpid/trunk/qpid/cpp/src/qpid/broker/Link.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/Link.cpp?rev=1311988&r1=1311987&r2=1311988&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/Link.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/Link.cpp Tue Apr 10 20:55:26 2012
@@ -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);
+    bool isClosing = false;
+    {
+        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()));
-    }
+        connection = 0;
+        if (state == STATE_OPERATIONAL) {
+            stringstream addr;
+            addr << host << ":" << port;
+            if (!hideManagement() && agent)
+                agent->raiseEvent(_qmf::EventBrokerLinkDown(addr.str()));
+        }
 
-    for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
-        (*i)->closed();
-        created.push_back(*i);
-    }
-    active.clear();
+        for (Bridges::iterator i = active.begin(); i != active.end(); i++) {
+            (*i)->closed();
+            created.push_back(*i);
+        }
+        active.clear();
 
-    if (state != STATE_FAILED && state != STATE_PASSIVE)
-    {
-        setStateLH(STATE_WAITING);
-        if (!hideManagement())
-            mgmtObject->set_lastError (text);
+        if (state != STATE_FAILED && state != STATE_PASSIVE)
+        {
+            setStateLH(STATE_WAITING);
+            if (!hideManagement())
+                mgmtObject->set_lastError (text);
+        }
     }
-
-    if (closing)
+    // Call destroy outside of the lock, don't want to be deleted with lock 
held.
+    if (isClosing)
         destroy();
 }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to