diff options
author | Charles E. Rolke <chug@apache.org> | 2012-11-05 20:43:48 +0000 |
---|---|---|
committer | Charles E. Rolke <chug@apache.org> | 2012-11-05 20:43:48 +0000 |
commit | 7ce7d0773c1afaaeb93d7ece9c39e692998f40c0 (patch) | |
tree | 8afc9883f5a6c60ec51e0882aa8e103a71474cfe | |
parent | c125061215f025f21109954b94538d68ef893f97 (diff) | |
download | qpid-python-7ce7d0773c1afaaeb93d7ece9c39e692998f40c0.tar.gz |
QPID-4421 Issue with reusing link channel Id number too soon.
Cycle through the entire pool of (32K) channel Id numbers to defer problem of references which are held for a little too long.
This problem was exposed by QPID-4392 where a channel number wrap problem was repaired.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1405946 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | cpp/src/qpid/broker/Link.cpp | 28 | ||||
-rw-r--r-- | cpp/src/qpid/broker/Link.h | 1 |
2 files changed, 23 insertions, 6 deletions
diff --git a/cpp/src/qpid/broker/Link.cpp b/cpp/src/qpid/broker/Link.cpp index 82389a5e3d..84a3a9ccb1 100644 --- a/cpp/src/qpid/broker/Link.cpp +++ b/cpp/src/qpid/broker/Link.cpp @@ -149,6 +149,7 @@ Link::Link(const string& _name, currentInterval(1), closing(false), reconnectNext(0), // Index of next address for reconnecting in url. + nextFreeChannel(1), freeChannels(1, framing::CHANNEL_MAX), connection(0), agent(0), @@ -548,13 +549,28 @@ framing::ChannelId Link::nextChannel() { Mutex::ScopedLock mutex(lock); if (!freeChannels.empty()) { - framing::ChannelId c = freeChannels.front(); - freeChannels -= c; - QPID_LOG(debug, "Link " << name << " allocates channel: " << c); - return c; - } else { - throw Exception(Msg() << "Link " << name << " channel pool is empty"); + // A free channel exists. + for (framing::ChannelId i = 1; i <= framing::CHANNEL_MAX; i++) + { + // extract proposed free channel + framing::ChannelId c = nextFreeChannel; + // calculate next free channel + if (framing::CHANNEL_MAX == nextFreeChannel) + nextFreeChannel = 1; + else + nextFreeChannel += 1; + // if proposed channel is free, use it + if (freeChannels.contains(c)) + { + freeChannels -= c; + QPID_LOG(debug, "Link " << name << " allocates channel: " << c); + return c; + } + } + assert (false); } + + throw Exception(Msg() << "Link " << name << " channel pool is empty"); } // Return channel to link free pool diff --git a/cpp/src/qpid/broker/Link.h b/cpp/src/qpid/broker/Link.h index 12bf28423a..97511de08f 100644 --- a/cpp/src/qpid/broker/Link.h +++ b/cpp/src/qpid/broker/Link.h @@ -82,6 +82,7 @@ class Link : public PersistableConfig, public management::Manageable { Bridges created; // Bridges pending creation Bridges active; // Bridges active Bridges cancellations; // Bridges pending cancellation + framing::ChannelId nextFreeChannel; RangeSet<framing::ChannelId> freeChannels; Connection* connection; management::ManagementAgent* agent; |