From 165d9cb4734734882082d472db91aabc846c6909 Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Tue, 27 Apr 2010 14:09:31 +0000 Subject: QPID-664: allow safe closing of session as part of handling a session exception git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@938460 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/client/SessionImpl.cpp | 6 +++++ cpp/src/qpid/client/SessionImpl.h | 1 + cpp/src/qpid/client/amqp0_10/SessionImpl.cpp | 36 ++++++++++++++++++---------- cpp/src/qpid/client/amqp0_10/SessionImpl.h | 1 + 4 files changed, 31 insertions(+), 13 deletions(-) (limited to 'cpp/src/qpid') diff --git a/cpp/src/qpid/client/SessionImpl.cpp b/cpp/src/qpid/client/SessionImpl.cpp index 05d90b4314..b7ff4307b6 100644 --- a/cpp/src/qpid/client/SessionImpl.cpp +++ b/cpp/src/qpid/client/SessionImpl.cpp @@ -789,6 +789,12 @@ void SessionImpl::assertOpen() const checkOpen(); } +bool SessionImpl::hasError() const +{ + Lock l(state); + return !exceptionHolder.empty(); +} + void SessionImpl::handleClosed() { demux.close(exceptionHolder.empty() ? diff --git a/cpp/src/qpid/client/SessionImpl.h b/cpp/src/qpid/client/SessionImpl.h index 2f35032c4e..7259bc0733 100644 --- a/cpp/src/qpid/client/SessionImpl.h +++ b/cpp/src/qpid/client/SessionImpl.h @@ -84,6 +84,7 @@ public: void suspend(); void assertOpen() const; + bool hasError() const; Future send(const framing::AMQBody& command); Future send(const framing::AMQBody& command, const framing::MethodContent& content); diff --git a/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp b/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp index 15a936465b..a55a2737cb 100644 --- a/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp +++ b/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp @@ -61,6 +61,12 @@ void SessionImpl::checkError() s.get()->assertOpen(); } +bool SessionImpl::hasError() +{ + qpid::client::SessionBase_0_10Access s(session); + return s.get()->hasError(); +} + void SessionImpl::sync(bool block) { if (block) retry(); @@ -105,22 +111,26 @@ void SessionImpl::release(qpid::messaging::Message& m) void SessionImpl::close() { - //close all the senders and receivers (get copy of names and then - //make the calls to avoid modifying maps while iterating over - //them): - std::vector s; - std::vector r; - { - qpid::sys::Mutex::ScopedLock l(lock); - for (Senders::const_iterator i = senders.begin(); i != senders.end(); ++i) s.push_back(i->first); - for (Receivers::const_iterator i = receivers.begin(); i != receivers.end(); ++i) r.push_back(i->first); + if (hasError()) { + senders.clear(); + receivers.clear(); + } else { + //close all the senders and receivers (get copy of names and then + //make the calls to avoid modifying maps while iterating over + //them): + std::vector s; + std::vector r; + { + qpid::sys::Mutex::ScopedLock l(lock); + for (Senders::const_iterator i = senders.begin(); i != senders.end(); ++i) s.push_back(i->first); + for (Receivers::const_iterator i = receivers.begin(); i != receivers.end(); ++i) r.push_back(i->first); + } + for (std::vector::const_iterator i = s.begin(); i != s.end(); ++i) getSender(*i).close(); + for (std::vector::const_iterator i = r.begin(); i != r.end(); ++i) getReceiver(*i).close(); } - for (std::vector::const_iterator i = s.begin(); i != s.end(); ++i) getSender(*i).close(); - for (std::vector::const_iterator i = r.begin(); i != r.end(); ++i) getReceiver(*i).close(); - connection->closed(*this); - session.close(); + if (!hasError()) session.close(); } template boost::intrusive_ptr getImplPtr(T& t) diff --git a/cpp/src/qpid/client/amqp0_10/SessionImpl.h b/cpp/src/qpid/client/amqp0_10/SessionImpl.h index 0613074f7c..bc02f0ff8b 100644 --- a/cpp/src/qpid/client/amqp0_10/SessionImpl.h +++ b/cpp/src/qpid/client/amqp0_10/SessionImpl.h @@ -76,6 +76,7 @@ class SessionImpl : public qpid::messaging::SessionImpl qpid::messaging::Connection getConnection() const; void checkError(); + bool hasError(); bool get(ReceiverImpl& receiver, qpid::messaging::Message& message, qpid::messaging::Duration timeout); -- cgit v1.2.1