diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ClientStack/PacketQueue.cs | 127 |
1 files changed, 52 insertions, 75 deletions
diff --git a/OpenSim/Region/ClientStack/PacketQueue.cs b/OpenSim/Region/ClientStack/PacketQueue.cs index b17249b..3d284e8 100644 --- a/OpenSim/Region/ClientStack/PacketQueue.cs +++ b/OpenSim/Region/ClientStack/PacketQueue.cs | |||
@@ -59,14 +59,6 @@ namespace OpenSim.Region.ClientStack | |||
59 | private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>(); | 59 | private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>(); |
60 | private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>(); | 60 | private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>(); |
61 | 61 | ||
62 | // 1536000 | ||
63 | private int throttleOutboundMax = 1536000; // Number of bytes allowed to go out per second. (256kbps per client) | ||
64 | // TODO: Make this variable. Lower throttle on un-ack. Raise over time? | ||
65 | private int bytesSent = 0; // Number of bytes sent this period | ||
66 | |||
67 | private int throttleOutbound = 162144; // Number of bytes allowed to go out per second. (256kbps per client) | ||
68 | // TODO: Make this variable. Lower throttle on un-ack. Raise over time | ||
69 | |||
70 | // All throttle times and number of bytes are calculated by dividing by this value | 62 | // All throttle times and number of bytes are calculated by dividing by this value |
71 | // This value also determines how many times per throttletimems the timer will run | 63 | // This value also determines how many times per throttletimems the timer will run |
72 | // If throttleimems is 1000 ms, then the timer will fire every 1000/7 milliseconds | 64 | // If throttleimems is 1000 ms, then the timer will fire every 1000/7 milliseconds |
@@ -75,43 +67,17 @@ namespace OpenSim.Region.ClientStack | |||
75 | 67 | ||
76 | private int throttletimems = 1000; | 68 | private int throttletimems = 1000; |
77 | 69 | ||
78 | // Maximum -per type- throttle | 70 | private PacketThrottle ResendThrottle; |
79 | private int ResendthrottleMAX = 100000; | 71 | private PacketThrottle LandThrottle; |
80 | private int LandthrottleMax = 100000; | 72 | private PacketThrottle WindThrottle; |
81 | private int WindthrottleMax = 100000; | 73 | private PacketThrottle CloudThrottle; |
82 | private int CloudthrottleMax = 100000; | 74 | private PacketThrottle TaskThrottle; |
83 | private int TaskthrottleMax = 800000; | 75 | private PacketThrottle AssetThrottle; |
84 | private int AssetthrottleMax = 800000; | 76 | private PacketThrottle TextureThrottle; |
85 | private int TexturethrottleMax = 800000; | 77 | private PacketThrottle TotalThrottle; |
86 | |||
87 | // Minimum -per type- throttle | ||
88 | private int ResendthrottleMin = 5000; // setting resendmin to 0 results in mostly dropped packets | ||
89 | private int LandthrottleMin = 1000; | ||
90 | private int WindthrottleMin = 1000; | ||
91 | private int CloudthrottleMin = 1000; | ||
92 | private int TaskthrottleMin = 1000; | ||
93 | private int AssetthrottleMin = 1000; | ||
94 | private int TexturethrottleMin = 1000; | ||
95 | |||
96 | // Sim default per-client settings. | ||
97 | private int ResendthrottleOutbound = 50000; | ||
98 | private int ResendBytesSent = 0; | ||
99 | private int LandthrottleOutbound = 100000; | ||
100 | private int LandBytesSent = 0; | ||
101 | private int WindthrottleOutbound = 10000; | ||
102 | private int WindBytesSent = 0; | ||
103 | private int CloudthrottleOutbound = 5000; | ||
104 | private int CloudBytesSent = 0; | ||
105 | private int TaskthrottleOutbound = 100000; | ||
106 | private int TaskBytesSent = 0; | ||
107 | private int AssetthrottleOutbound = 80000; | ||
108 | private int AssetBytesSent = 0; | ||
109 | private int TexturethrottleOutbound = 100000; | ||
110 | private int TextureBytesSent = 0; | ||
111 | 78 | ||
112 | private Timer throttleTimer; | 79 | private Timer throttleTimer; |
113 | 80 | ||
114 | |||
115 | public PacketQueue() | 81 | public PacketQueue() |
116 | { | 82 | { |
117 | // While working on this, the BlockingQueue had me fooled for a bit. | 83 | // While working on this, the BlockingQueue had me fooled for a bit. |
@@ -131,9 +97,20 @@ namespace OpenSim.Region.ClientStack | |||
131 | TextureOutgoingPacketQueue = new Queue<QueItem>(); | 97 | TextureOutgoingPacketQueue = new Queue<QueItem>(); |
132 | AssetOutgoingPacketQueue = new Queue<QueItem>(); | 98 | AssetOutgoingPacketQueue = new Queue<QueItem>(); |
133 | 99 | ||
134 | // TIMERS needed for this | 100 | |
135 | ResetCounters(); | 101 | // Set up the throttle classes (min, max, current) in bytes |
102 | ResendThrottle = new PacketThrottle(5000, 100000, 50000); | ||
103 | LandThrottle = new PacketThrottle(1000, 100000, 100000); | ||
104 | WindThrottle = new PacketThrottle(1000, 100000, 10000); | ||
105 | CloudThrottle = new PacketThrottle(1000, 100000, 50000); | ||
106 | TaskThrottle = new PacketThrottle(1000, 800000, 100000); | ||
107 | AssetThrottle = new PacketThrottle(1000, 800000, 80000); | ||
108 | TextureThrottle = new PacketThrottle(1000, 800000, 100000); | ||
109 | // Total Throttle trumps all | ||
110 | // Number of bytes allowed to go out per second. (256kbps per client) | ||
111 | TotalThrottle = new PacketThrottle(0, 162144, 1536000); | ||
136 | 112 | ||
113 | // TIMERS needed for this | ||
137 | throttleTimer = new Timer((int)(throttletimems/throttleTimeDivisor)); | 114 | throttleTimer = new Timer((int)(throttletimems/throttleTimeDivisor)); |
138 | throttleTimer.Elapsed += new ElapsedEventHandler(throttleTimer_Elapsed); | 115 | throttleTimer.Elapsed += new ElapsedEventHandler(throttleTimer_Elapsed); |
139 | throttleTimer.Start(); | 116 | throttleTimer.Start(); |
@@ -141,14 +118,14 @@ namespace OpenSim.Region.ClientStack | |||
141 | 118 | ||
142 | private void ResetCounters() | 119 | private void ResetCounters() |
143 | { | 120 | { |
144 | bytesSent = 0; | 121 | ResendThrottle.Reset(); |
145 | ResendBytesSent = 0; | 122 | LandThrottle.Reset(); |
146 | LandBytesSent = 0; | 123 | WindThrottle.Reset(); |
147 | WindBytesSent = 0; | 124 | CloudThrottle.Reset(); |
148 | CloudBytesSent = 0; | 125 | TaskThrottle.Reset(); |
149 | TaskBytesSent = 0; | 126 | AssetThrottle.Reset(); |
150 | AssetBytesSent = 0; | 127 | TextureThrottle.Reset(); |
151 | TextureBytesSent = 0; | 128 | TotalThrottle.Reset(); |
152 | } | 129 | } |
153 | 130 | ||
154 | private bool PacketsWaiting() | 131 | private bool PacketsWaiting() |
@@ -178,66 +155,66 @@ namespace OpenSim.Region.ClientStack | |||
178 | 155 | ||
179 | // We're going to dequeue all of the saved up packets until | 156 | // We're going to dequeue all of the saved up packets until |
180 | // we've hit the throttle limit or there's no more packets to send | 157 | // we've hit the throttle limit or there's no more packets to send |
181 | while ((bytesSent <= (int)(throttleOutbound/throttleTimeDivisor)) && | 158 | while (TotalThrottle.UnderLimit() && PacketsWaiting() && |
182 | PacketsWaiting() && (throttleLoops <= MaxThrottleLoops)) | 159 | (throttleLoops <= MaxThrottleLoops)) |
183 | { | 160 | { |
184 | throttleLoops++; | 161 | throttleLoops++; |
185 | //Now comes the fun part.. we dump all our elements into PacketQueue that we've saved up. | 162 | //Now comes the fun part.. we dump all our elements into PacketQueue that we've saved up. |
186 | if (ResendBytesSent <= ((int)(ResendthrottleOutbound/throttleTimeDivisor)) && ResendOutgoingPacketQueue.Count > 0) | 163 | if (ResendThrottle.UnderLimit() && ResendOutgoingPacketQueue.Count > 0) |
187 | { | 164 | { |
188 | QueItem qpack = ResendOutgoingPacketQueue.Dequeue(); | 165 | QueItem qpack = ResendOutgoingPacketQueue.Dequeue(); |
189 | 166 | ||
190 | SendQueue.Enqueue(qpack); | 167 | SendQueue.Enqueue(qpack); |
191 | bytesSent += qpack.Packet.ToBytes().Length; | 168 | TotalThrottle.Add(qpack.Packet.ToBytes().Length); |
192 | ResendBytesSent += qpack.Packet.ToBytes().Length; | 169 | ResendThrottle.Add(qpack.Packet.ToBytes().Length); |
193 | } | 170 | } |
194 | if (LandBytesSent <= ((int)(LandthrottleOutbound/throttleTimeDivisor)) && LandOutgoingPacketQueue.Count > 0) | 171 | if (LandThrottle.UnderLimit() && LandOutgoingPacketQueue.Count > 0) |
195 | { | 172 | { |
196 | QueItem qpack = LandOutgoingPacketQueue.Dequeue(); | 173 | QueItem qpack = LandOutgoingPacketQueue.Dequeue(); |
197 | 174 | ||
198 | SendQueue.Enqueue(qpack); | 175 | SendQueue.Enqueue(qpack); |
199 | bytesSent += qpack.Packet.ToBytes().Length; | 176 | TotalThrottle.Add(qpack.Packet.ToBytes().Length); |
200 | LandBytesSent += qpack.Packet.ToBytes().Length; | 177 | LandThrottle.Add(qpack.Packet.ToBytes().Length); |
201 | } | 178 | } |
202 | if (WindBytesSent <= ((int)(WindthrottleOutbound/throttleTimeDivisor)) && WindOutgoingPacketQueue.Count > 0) | 179 | if (WindThrottle.UnderLimit() && WindOutgoingPacketQueue.Count > 0) |
203 | { | 180 | { |
204 | QueItem qpack = WindOutgoingPacketQueue.Dequeue(); | 181 | QueItem qpack = WindOutgoingPacketQueue.Dequeue(); |
205 | 182 | ||
206 | SendQueue.Enqueue(qpack); | 183 | SendQueue.Enqueue(qpack); |
207 | bytesSent += qpack.Packet.ToBytes().Length; | 184 | TotalThrottle.Add(qpack.Packet.ToBytes().Length); |
208 | WindBytesSent += qpack.Packet.ToBytes().Length; | 185 | WindThrottle.Add(qpack.Packet.ToBytes().Length); |
209 | } | 186 | } |
210 | if (CloudBytesSent <= ((int)(CloudthrottleOutbound/throttleTimeDivisor)) && CloudOutgoingPacketQueue.Count > 0) | 187 | if (CloudThrottle.UnderLimit() && CloudOutgoingPacketQueue.Count > 0) |
211 | { | 188 | { |
212 | QueItem qpack = CloudOutgoingPacketQueue.Dequeue(); | 189 | QueItem qpack = CloudOutgoingPacketQueue.Dequeue(); |
213 | 190 | ||
214 | SendQueue.Enqueue(qpack); | 191 | SendQueue.Enqueue(qpack); |
215 | bytesSent += qpack.Packet.ToBytes().Length; | 192 | TotalThrottle.Add(qpack.Packet.ToBytes().Length); |
216 | CloudBytesSent += qpack.Packet.ToBytes().Length; | 193 | CloudThrottle.Add(qpack.Packet.ToBytes().Length); |
217 | } | 194 | } |
218 | if (TaskBytesSent <= ((int)(TaskthrottleOutbound/throttleTimeDivisor)) && TaskOutgoingPacketQueue.Count > 0) | 195 | if (TaskThrottle.UnderLimit() && TaskOutgoingPacketQueue.Count > 0) |
219 | { | 196 | { |
220 | QueItem qpack = TaskOutgoingPacketQueue.Dequeue(); | 197 | QueItem qpack = TaskOutgoingPacketQueue.Dequeue(); |
221 | 198 | ||
222 | SendQueue.Enqueue(qpack); | 199 | SendQueue.Enqueue(qpack); |
223 | bytesSent += qpack.Packet.ToBytes().Length; | 200 | TotalThrottle.Add(qpack.Packet.ToBytes().Length); |
224 | TaskBytesSent += qpack.Packet.ToBytes().Length; | 201 | TaskThrottle.Add(qpack.Packet.ToBytes().Length); |
225 | } | 202 | } |
226 | if (TextureBytesSent <= ((int)(TexturethrottleOutbound/throttleTimeDivisor)) && TextureOutgoingPacketQueue.Count > 0) | 203 | if (TextureThrottle.UnderLimit() && TextureOutgoingPacketQueue.Count > 0) |
227 | { | 204 | { |
228 | QueItem qpack = TextureOutgoingPacketQueue.Dequeue(); | 205 | QueItem qpack = TextureOutgoingPacketQueue.Dequeue(); |
229 | 206 | ||
230 | SendQueue.Enqueue(qpack); | 207 | SendQueue.Enqueue(qpack); |
231 | bytesSent += qpack.Packet.ToBytes().Length; | 208 | TotalThrottle.Add(qpack.Packet.ToBytes().Length); |
232 | TextureBytesSent += qpack.Packet.ToBytes().Length; | 209 | TextureThrottle.Add(qpack.Packet.ToBytes().Length); |
233 | } | 210 | } |
234 | if (AssetBytesSent <= ((int)(AssetthrottleOutbound/throttleTimeDivisor)) && AssetOutgoingPacketQueue.Count > 0) | 211 | if (AssetThrottle.UnderLimit() && AssetOutgoingPacketQueue.Count > 0) |
235 | { | 212 | { |
236 | QueItem qpack = AssetOutgoingPacketQueue.Dequeue(); | 213 | QueItem qpack = AssetOutgoingPacketQueue.Dequeue(); |
237 | 214 | ||
238 | SendQueue.Enqueue(qpack); | 215 | SendQueue.Enqueue(qpack); |
239 | bytesSent += qpack.Packet.ToBytes().Length; | 216 | TotalThrottle.Add(qpack.Packet.ToBytes().Length); |
240 | AssetBytesSent += qpack.Packet.ToBytes().Length; | 217 | AssetThrottle.Add(qpack.Packet.ToBytes().Length); |
241 | } | 218 | } |
242 | 219 | ||
243 | } | 220 | } |