From 7ce7d0773c1afaaeb93d7ece9c39e692998f40c0 Mon Sep 17 00:00:00 2001 From: "Charles E. Rolke" Date: Mon, 5 Nov 2012 20:43:48 +0000 Subject: 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 --- cpp/src/qpid/broker/Link.cpp | 28 ++++++++++++++++++++++------ cpp/src/qpid/broker/Link.h | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) (limited to 'cpp/src') 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 freeChannels; Connection* connection; management::ManagementAgent* agent; -- cgit v1.2.1