summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/client/ConnectionImpl.cpp
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2009-10-21 17:03:33 +0000
committerAlan Conway <aconway@apache.org>2009-10-21 17:03:33 +0000
commit9c12f89c6ee28f2741e288b6155bc900ef1c4f05 (patch)
tree2fa86b352e831781245f4c27092bad77dcff2aa0 /cpp/src/qpid/client/ConnectionImpl.cpp
parent4214ec3e632be1f9a8cb1553280c5948fa9161bb (diff)
downloadqpid-python-9c12f89c6ee28f2741e288b6155bc900ef1c4f05.tar.gz
Fix problems with sessions going out of scope and session numbers wrapping around.
Fixes QPID-1789: sessions that go out of scope without being detached will detach themselves. Also fixes several issues that arise when the session numbers wraps around and start re-using old numbers. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@828108 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/client/ConnectionImpl.cpp')
-rw-r--r--cpp/src/qpid/client/ConnectionImpl.cpp23
1 files changed, 16 insertions, 7 deletions
diff --git a/cpp/src/qpid/client/ConnectionImpl.cpp b/cpp/src/qpid/client/ConnectionImpl.cpp
index c56d6a6807..6a46cb6249 100644
--- a/cpp/src/qpid/client/ConnectionImpl.cpp
+++ b/cpp/src/qpid/client/ConnectionImpl.cpp
@@ -95,11 +95,21 @@ ConnectionImpl::~ConnectionImpl() {
void ConnectionImpl::addSession(const boost::shared_ptr<SessionImpl>& session, uint16_t channel)
{
Mutex::ScopedLock l(lock);
- session->setChannel(channel == NEXT_CHANNEL ? nextChannel++ : channel);
- boost::weak_ptr<SessionImpl>& s = sessions[session->getChannel()];
- boost::shared_ptr<SessionImpl> ss = s.lock();
- if (ss) throw SessionBusyException(QPID_MSG("Channel " << ss->getChannel() << " attached to " << ss->getId()));
- s = session;
+ for (uint16_t i = 0; i < NEXT_CHANNEL; i++) { //will at most search through channels once
+ uint16_t c = channel == NEXT_CHANNEL ? nextChannel++ : channel;
+ boost::weak_ptr<SessionImpl>& s = sessions[c];
+ boost::shared_ptr<SessionImpl> ss = s.lock();
+ if (!ss) {
+ //channel is free, we can assign it to this session
+ session->setChannel(c);
+ s = session;
+ return;
+ } else if (channel != NEXT_CHANNEL) {
+ //channel is taken and was requested explicitly so don't look for another
+ throw SessionBusyException(QPID_MSG("Channel " << ss->getChannel() << " attached to " << ss->getId()));
+ } //else channel is busy, but we can keep looking for a free one
+ }
+
}
void ConnectionImpl::handle(framing::AMQFrame& frame)
@@ -165,7 +175,6 @@ void ConnectionImpl::open()
} else {
QPID_LOG(debug, "No security layer in place");
}
-
failover.reset(new FailoverListener(shared_from_this(), handler.knownBrokersUrls));
}
@@ -246,7 +255,7 @@ const ConnectionSettings& ConnectionImpl::getNegotiatedSettings()
{
return handler;
}
-
+
std::vector<qpid::Url> ConnectionImpl::getKnownBrokers() {
return failover ? failover->getKnownBrokers() : handler.knownBrokersUrls;
}