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 | c04659aff9662296e2fa4ce58b03a926acaf493a (patch) | |
| tree | abc77e8204f3421257dad887f0b13432ae449df0 /qpid/cpp/src | |
| parent | 3dbb71f39734ae769d258bb1548ba946e859a13a (diff) | |
| download | qpid-python-c04659aff9662296e2fa4ce58b03a926acaf493a.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@1159293 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src')
| -rw-r--r-- | qpid/cpp/src/qpid/client/amqp0_10/SessionImpl.cpp | 38 |
1 files changed, 21 insertions, 17 deletions
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 <class T, class S> boost::intrusive_ptr<S> getImplPtr(T& t) |
