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 | 317fb4aec9f7fb4df709c374c2a176cd6c9aed94 (patch) | |
| tree | bf2735af56a2ebe6a059ca645606482eadd621be /qpid/cpp/src | |
| parent | e3c8a3d852dc9ecce5c282022bcfe3166a4a788e (diff) | |
| download | qpid-python-317fb4aec9f7fb4df709c374c2a176cd6c9aed94.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@1405946 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src')
| -rw-r--r-- | qpid/cpp/src/qpid/broker/Link.cpp | 28 | ||||
| -rw-r--r-- | qpid/cpp/src/qpid/broker/Link.h | 1 |
2 files changed, 23 insertions, 6 deletions
diff --git a/qpid/cpp/src/qpid/broker/Link.cpp b/qpid/cpp/src/qpid/broker/Link.cpp index 82389a5e3d..84a3a9ccb1 100644 --- a/qpid/cpp/src/qpid/broker/Link.cpp +++ b/qpid/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/qpid/cpp/src/qpid/broker/Link.h b/qpid/cpp/src/qpid/broker/Link.h index 12bf28423a..97511de08f 100644 --- a/qpid/cpp/src/qpid/broker/Link.h +++ b/qpid/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; |
