Author: chug
Date: Mon Nov  5 20:43:48 2012
New Revision: 1405946

URL: http://svn.apache.org/viewvc?rev=1405946&view=rev
Log:
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. 


Modified:
    qpid/trunk/qpid/cpp/src/qpid/broker/Link.cpp
    qpid/trunk/qpid/cpp/src/qpid/broker/Link.h

Modified: qpid/trunk/qpid/cpp/src/qpid/broker/Link.cpp
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/Link.cpp?rev=1405946&r1=1405945&r2=1405946&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/Link.cpp (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/Link.cpp Mon Nov  5 20:43:48 2012
@@ -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

Modified: qpid/trunk/qpid/cpp/src/qpid/broker/Link.h
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/cpp/src/qpid/broker/Link.h?rev=1405946&r1=1405945&r2=1405946&view=diff
==============================================================================
--- qpid/trunk/qpid/cpp/src/qpid/broker/Link.h (original)
+++ qpid/trunk/qpid/cpp/src/qpid/broker/Link.h Mon Nov  5 20:43:48 2012
@@ -82,6 +82,7 @@ class Link : public PersistableConfig, p
     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;



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to