From 1632488ab1ff6270b4ef37974b5de2b422365bdb Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Mon, 16 Apr 2007 11:32:43 +0000 Subject: Fixes QPID-303 and QPID-409. * qpid/client/Connector: atomic test-and-set for closed, don't try to close if already closed * qpid/client/Connection: atomic test-and-set for isOpen, don't send requests to broker on shutdown git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@529209 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/client/ClientConnection.cpp | 39 ++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'cpp/src/qpid/client/ClientConnection.cpp') diff --git a/cpp/src/qpid/client/ClientConnection.cpp b/cpp/src/qpid/client/ClientConnection.cpp index 48616cf3d9..177c9c4b73 100644 --- a/cpp/src/qpid/client/ClientConnection.cpp +++ b/cpp/src/qpid/client/ClientConnection.cpp @@ -75,30 +75,49 @@ void Connection::open( } void Connection::shutdown() { - close(); + //this indicates that the socket to the server has closed we do + //not want to send a close request (or any other requests) + if(markClosed()) { + std::cout << "Connection to peer closed!" << std::endl; + closeChannels(); + } } void Connection::close( ReplyCode code, const string& msg, ClassId classId, MethodId methodId ) { - if(isOpen) { + if(markClosed()) { // TODO aconway 2007-01-29: Exception handling - could end up // partly closed with threads left unjoined. - isOpen = false; channel0.sendAndReceive( make_shared_ptr(new ConnectionCloseBody( - getVersion(), code, msg, classId, methodId))); - - using boost::bind; - for_each(channels.begin(), channels.end(), - bind(&Channel::closeInternal, - bind(&ChannelMap::value_type::second, _1))); - channels.clear(); + getVersion(), code, msg, classId, methodId))); + closeChannels(); connector->close(); } } +bool Connection::markClosed() +{ + Mutex::ScopedLock locker(shutdownLock); + if (isOpen) { + isOpen = false; + return true; + } else { + return false; + } +} + +void Connection::closeChannels() +{ + using boost::bind; + for_each(channels.begin(), channels.end(), + bind(&Channel::closeInternal, + bind(&ChannelMap::value_type::second, _1))); + channels.clear(); +} + void Connection::openChannel(Channel& channel) { ChannelId id = ++channelIdCounter; assert (channels.find(id) == channels.end()); -- cgit v1.2.1