diff options
author | Gordon Sim <gsim@apache.org> | 2011-08-18 16:09:03 +0000 |
---|---|---|
committer | Gordon Sim <gsim@apache.org> | 2011-08-18 16:09:03 +0000 |
commit | 5ab2b64897189b7f82b5e1e8bcdc72a2ca7394ce (patch) | |
tree | d55760ab04de4af0cce677807d41bc56a3ecaedf /cpp/src | |
parent | d930f07d077945ebc1db161e6b6691b987938484 (diff) | |
download | qpid-python-5ab2b64897189b7f82b5e1e8bcdc72a2ca7394ce.tar.gz |
QPID-3435: Revised strategy for closing senders/receivers to prevent possible infinite loop
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1159293 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/qpid/client/amqp0_10/SessionImpl.cpp | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp b/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp index e6255dcd6f..be5eab1f2b 100644 --- a/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp +++ b/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 <class T, class S> boost::intrusive_ptr<S> getImplPtr(T& t) |