From 7f28dd4b3195e020eed51fa1229083123935125b Mon Sep 17 00:00:00 2001
From: Dan Lake
Date: Thu, 21 Apr 2011 15:40:32 -0700
Subject: Refactor UnackedPacketCollection so ProcessQueues will handle Adds,
 Acks, and Removes in that order.

---
 .../Region/ClientStack/LindenUDP/LLUDPServer.cs    |  4 +-
 .../LindenUDP/UnackedPacketCollection.cs           | 56 ++++++++++++----------
 2 files changed, 34 insertions(+), 26 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index bd58ddc..aff90c5 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -672,7 +672,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
             if (packet.Header.AppendedAcks && packet.Header.AckList != null)
             {
                 for (int i = 0; i < packet.Header.AckList.Length; i++)
-                    udpClient.NeedAcks.Remove(packet.Header.AckList[i], now, packet.Header.Resent);
+                    udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent);
             }
 
             // Handle PacketAck packets
@@ -681,7 +681,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                 PacketAckPacket ackPacket = (PacketAckPacket)packet;
 
                 for (int i = 0; i < ackPacket.Packets.Length; i++)
-                    udpClient.NeedAcks.Remove(ackPacket.Packets[i].ID, now, packet.Header.Resent);
+                    udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent);
 
                 // We don't need to do anything else with PacketAck packets
                 return;
diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs
index 90a87fa..793aefe 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs
@@ -65,7 +65,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
         /// <summary>Holds packets that need to be added to the unacknowledged list</summary>
         private LocklessQueue<OutgoingPacket> m_pendingAdds = new LocklessQueue<OutgoingPacket>();
         /// <summary>Holds information about pending acknowledgements</summary>
-        private LocklessQueue<PendingAck> m_pendingRemoves = new LocklessQueue<PendingAck>();
+        private LocklessQueue<PendingAck> m_pendingAcknowledgements = new LocklessQueue<PendingAck>();
+        /// <summary>Holds information about pending removals</summary>
+        private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>();
 
         /// <summary>
         /// Add an unacked packet to the collection
@@ -92,9 +94,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
         /// <param name="currentTime">Current value of Environment.TickCount</param>
         /// <remarks>This does not immediately acknowledge the packet, it only
         /// queues the ack so it can be handled in a thread-safe way later</remarks>
-        public void Remove(uint sequenceNumber, int currentTime, bool fromResend)
+        public void Acknowledge(uint sequenceNumber, int currentTime, bool fromResend)
         {
-            m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend));
+            m_pendingAcknowledgements.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend));
         }
 
         /// <summary>
@@ -105,21 +107,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
         /// </summary>
         /// <param name="sequenceNumber">Sequence number of the packet to
         /// acknowledge</param>
-        /// <remarks>The packet is removed from the collection immediately. 
-        /// This function is not threadsafe. It must be called by the thread calling GetExpiredPackets.</remarks>
+        /// <remarks>The does not immediately remove the packet, it only queues the removal
+        /// so it can be handled in a thread safe way later</remarks>
         public void Remove(uint sequenceNumber)
         {
-            OutgoingPacket removedPacket;
-            if (m_packets.TryGetValue(sequenceNumber, out removedPacket))
-            {
-                if (removedPacket != null)
-                {
-                    m_packets.Remove(sequenceNumber);
-
-                    // Update stats
-                    Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength);
-                }
-            }
+            m_pendingRemoves.Enqueue(sequenceNumber);
         }
 
         /// <summary>
@@ -179,15 +171,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                     m_packets[pendingAdd.SequenceNumber] = pendingAdd;
             
             // Process all the pending removes, including updating statistics and round-trip times
-            PendingAck pendingRemove;
-            OutgoingPacket ackedPacket;
-            while (m_pendingRemoves.TryDequeue(out pendingRemove))
+            PendingAck pendingAcknowledgement;
+            while (m_pendingAcknowledgements.TryDequeue(out pendingAcknowledgement))
             {
-                if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket))
+                OutgoingPacket ackedPacket;
+                if (m_packets.TryGetValue(pendingAcknowledgement.SequenceNumber, out ackedPacket))
                 {
                     if (ackedPacket != null)
                     {
-                        m_packets.Remove(pendingRemove.SequenceNumber);
+                        m_packets.Remove(pendingAcknowledgement.SequenceNumber);
 
                         // As with other network applications, assume that an acknowledged packet is an
                         // indication that the network can handle a little more load, speed up the transmission
@@ -196,16 +188,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
                         // Update stats
                         Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
 
-                        if (!pendingRemove.FromResend)
+                        if (!pendingAcknowledgement.FromResend)
                         {
                             // Calculate the round-trip time for this packet and its ACK
-                            int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount;
+                            int rtt = pendingAcknowledgement.RemoveTime - ackedPacket.TickCount;
                             if (rtt > 0)
                                 ackedPacket.Client.UpdateRoundTrip(rtt);
                         }
                     }
                 }
             }
+
+            uint pendingRemove;
+            while(m_pendingRemoves.TryDequeue(out pendingRemove))
+            {
+                OutgoingPacket removedPacket;
+                if (m_packets.TryGetValue(pendingRemove, out removedPacket))
+                {
+                    if (removedPacket != null)
+                    {
+                        m_packets.Remove(pendingRemove);
+
+                        // Update stats
+                        Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength);
+                    }
+                }
+            }
         }
     }
-}
\ No newline at end of file
+}
-- 
cgit v1.1