From c04659aff9662296e2fa4ce58b03a926acaf493a Mon Sep 17 00:00:00 2001 From: Gordon Sim Date: Thu, 18 Aug 2011 16:09:03 +0000 Subject: QPID-3435: Revised strategy for closing senders/receivers to prevent possible infinite loop git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1159293 13f79535-47bb-0310-9956-ffa450edef68 --- qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp | 38 +++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'qpid/cpp') diff --git a/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp b/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp index e6255dcd6f..be5eab1f2b 100644 --- a/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp +++ b/qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp @@ -60,12 +60,14 @@ SessionImpl::SessionImpl(ConnectionImpl& c, bool t) : connection(&c), transactio void SessionImpl::checkError() { + ScopedLock l(lock); qpid::client::SessionBase_0_10Access s(session); s.get()->assertOpen(); } bool SessionImpl::hasError() { + ScopedLock l(lock); qpid::client::SessionBase_0_10Access s(session); return s.get()->hasError(); } @@ -129,27 +131,29 @@ void SessionImpl::close() senders.clear(); receivers.clear(); } else { - while (true) { - Sender s; - { - ScopedLock l(lock); - if (senders.empty()) break; - s = senders.begin()->second; - } - s.close(); // outside the lock, will call senderCancelled + Senders sCopy; + Receivers rCopy; + { + ScopedLock l(lock); + senders.swap(sCopy); + receivers.swap(rCopy); } - while (true) { - Receiver r; - { - ScopedLock l(lock); - if (receivers.empty()) break; - r = receivers.begin()->second; - } - r.close(); // outside the lock, will call receiverCancelled + for (Senders::iterator i = sCopy.begin(); i != sCopy.end(); ++i) + { + // outside the lock, will call senderCancelled + i->second.close(); + } + for (Receivers::iterator i = rCopy.begin(); i != rCopy.end(); ++i) + { + // outside the lock, will call receiverCancelled + i->second.close(); } } connection->closed(*this); - if (!hasError()) session.close(); + if (!hasError()) { + ScopedLock l(lock); + session.close(); + } } template boost::intrusive_ptr getImplPtr(T& t) -- cgit v1.2.1