aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs58
1 files changed, 47 insertions, 11 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs
index b170964..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
65 /// <summary>Holds packets that need to be added to the unacknowledged list</summary> 65 /// <summary>Holds packets that need to be added to the unacknowledged list</summary>
66 private LocklessQueue<OutgoingPacket> m_pendingAdds = new LocklessQueue<OutgoingPacket>(); 66 private LocklessQueue<OutgoingPacket> m_pendingAdds = new LocklessQueue<OutgoingPacket>();
67 /// <summary>Holds information about pending acknowledgements</summary> 67 /// <summary>Holds information about pending acknowledgements</summary>
68 private LocklessQueue<PendingAck> m_pendingRemoves = new LocklessQueue<PendingAck>(); 68 private LocklessQueue<PendingAck> m_pendingAcknowledgements = new LocklessQueue<PendingAck>();
69 /// <summary>Holds information about pending removals</summary>
70 private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>();
69 71
70 /// <summary> 72 /// <summary>
71 /// Add an unacked packet to the collection 73 /// Add an unacked packet to the collection
@@ -83,15 +85,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
83 85
84 /// <summary> 86 /// <summary>
85 /// Marks a packet as acknowledged 87 /// Marks a packet as acknowledged
88 /// This method is used when an acknowledgement is received from the network for a previously
89 /// sent packet. Effects of removal this way are to update unacked byte count, adjust RTT
90 /// and increase throttle to the coresponding client.
86 /// </summary> 91 /// </summary>
87 /// <param name="sequenceNumber">Sequence number of the packet to 92 /// <param name="sequenceNumber">Sequence number of the packet to
88 /// acknowledge</param> 93 /// acknowledge</param>
89 /// <param name="currentTime">Current value of Environment.TickCount</param> 94 /// <param name="currentTime">Current value of Environment.TickCount</param>
90 /// <remarks>This does not immediately acknowledge the packet, it only 95 /// <remarks>This does not immediately acknowledge the packet, it only
91 /// queues the ack so it can be handled in a thread-safe way later</remarks> 96 /// queues the ack so it can be handled in a thread-safe way later</remarks>
92 public void Remove(uint sequenceNumber, int currentTime, bool fromResend) 97 public void Acknowledge(uint sequenceNumber, int currentTime, bool fromResend)
93 { 98 {
94 m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); 99 m_pendingAcknowledgements.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend));
100 }
101
102 /// <summary>
103 /// Marks a packet as no longer needing acknowledgement without a received acknowledgement.
104 /// This method is called when a packet expires and we no longer need an acknowledgement.
105 /// When some reliable packet types expire, they are handled in a way other than simply
106 /// resending them. The only effect of removal this way is to update unacked byte count.
107 /// </summary>
108 /// <param name="sequenceNumber">Sequence number of the packet to
109 /// acknowledge</param>
110 /// <remarks>The does not immediately remove the packet, it only queues the removal
111 /// so it can be handled in a thread safe way later</remarks>
112 public void Remove(uint sequenceNumber)
113 {
114 m_pendingRemoves.Enqueue(sequenceNumber);
95 } 115 }
96 116
97 /// <summary> 117 /// <summary>
@@ -151,15 +171,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
151 m_packets[pendingAdd.SequenceNumber] = pendingAdd; 171 m_packets[pendingAdd.SequenceNumber] = pendingAdd;
152 172
153 // Process all the pending removes, including updating statistics and round-trip times 173 // Process all the pending removes, including updating statistics and round-trip times
154 PendingAck pendingRemove; 174 PendingAck pendingAcknowledgement;
155 OutgoingPacket ackedPacket; 175 while (m_pendingAcknowledgements.TryDequeue(out pendingAcknowledgement))
156 while (m_pendingRemoves.TryDequeue(out pendingRemove))
157 { 176 {
158 if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) 177 OutgoingPacket ackedPacket;
178 if (m_packets.TryGetValue(pendingAcknowledgement.SequenceNumber, out ackedPacket))
159 { 179 {
160 if (ackedPacket != null) 180 if (ackedPacket != null)
161 { 181 {
162 m_packets.Remove(pendingRemove.SequenceNumber); 182 m_packets.Remove(pendingAcknowledgement.SequenceNumber);
163 183
164 // As with other network applications, assume that an acknowledged packet is an 184 // As with other network applications, assume that an acknowledged packet is an
165 // indication that the network can handle a little more load, speed up the transmission 185 // indication that the network can handle a little more load, speed up the transmission
@@ -168,16 +188,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
168 // Update stats 188 // Update stats
169 Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); 189 Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength);
170 190
171 if (!pendingRemove.FromResend) 191 if (!pendingAcknowledgement.FromResend)
172 { 192 {
173 // Calculate the round-trip time for this packet and its ACK 193 // Calculate the round-trip time for this packet and its ACK
174 int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount; 194 int rtt = pendingAcknowledgement.RemoveTime - ackedPacket.TickCount;
175 if (rtt > 0) 195 if (rtt > 0)
176 ackedPacket.Client.UpdateRoundTrip(rtt); 196 ackedPacket.Client.UpdateRoundTrip(rtt);
177 } 197 }
178 } 198 }
179 } 199 }
180 } 200 }
201
202 uint pendingRemove;
203 while(m_pendingRemoves.TryDequeue(out pendingRemove))
204 {
205 OutgoingPacket removedPacket;
206 if (m_packets.TryGetValue(pendingRemove, out removedPacket))
207 {
208 if (removedPacket != null)
209 {
210 m_packets.Remove(pendingRemove);
211
212 // Update stats
213 Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength);
214 }
215 }
216 }
181 } 217 }
182 } 218 }
183} \ No newline at end of file 219}