diff options
author | Alan Conway <aconway@apache.org> | 2010-03-01 21:34:47 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2010-03-01 21:34:47 +0000 |
commit | b761239e6e9c471d8a4de11cdc7de9ee18c204ae (patch) | |
tree | cd3cb28080f6396b6c9b5c1d1cac8586b0b767ff /cpp/src/qpid/cluster/Connection.cpp | |
parent | b20fc1108a8cc7a2fde90fc2012cb19bd45cf94a (diff) | |
download | qpid-python-b761239e6e9c471d8a4de11cdc7de9ee18c204ae.tar.gz |
Fix: decoding error causes cluster broker to exit.
An error decoding a connection was causing the broker::Connection
object to be deleted in the connection IO thread rather than the
cluster deliver thread, causing an exit with "critical Modified
cluster state outside of cluster context"
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@917734 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/cluster/Connection.cpp')
-rw-r--r-- | cpp/src/qpid/cluster/Connection.cpp | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/cpp/src/qpid/cluster/Connection.cpp b/cpp/src/qpid/cluster/Connection.cpp index a375a65851..909ff68d92 100644 --- a/cpp/src/qpid/cluster/Connection.cpp +++ b/cpp/src/qpid/cluster/Connection.cpp @@ -159,6 +159,11 @@ bool Connection::doOutput() { // Received from a directly connected client. void Connection::received(framing::AMQFrame& f) { + if (!connection.get()) { + QPID_LOG(warning, cluster << " ignoring frame on closed connection " + << *this << ": " << f); + return; + } QPID_LOG(trace, cluster << " RECV " << *this << ": " << f); if (isLocal()) { // Local catch-up connection. currentChannel = f.getChannel(); @@ -231,7 +236,7 @@ void Connection::closed() { } else if (isUpdated()) { QPID_LOG(debug, cluster << " closed update connection " << *this); - connection->closed(); + if (connection.get()) connection->closed(); } else if (isLocal()) { QPID_LOG(debug, cluster << " local close of replicated connection " << *this); @@ -250,13 +255,21 @@ void Connection::closed() { // Self-delivery of close message, close the connection. void Connection::deliverClose () { assert(!catchUp); - connection->closed(); + if (connection.get()) { + connection->closed(); + // Ensure we delete the broker::Connection in the deliver thread. + connection.reset(); + } cluster.erase(self); } // The connection has been killed for misbehaving void Connection::abort() { - if (connection.get()) connection->abort(); + if (connection.get()) { + connection->abort(); + // Ensure we delete the broker::Connection in the deliver thread. + connection.reset(); + } cluster.erase(self); } @@ -324,7 +337,6 @@ void Connection::sessionState( const SequenceSet& unknownCompleted, const SequenceSet& receivedIncomplete) { - sessionState().setState( replayStart, sendCommandPoint, |