aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs25
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs7
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs48
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs65
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs12
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs15
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs36
-rw-r--r--OpenSim/Services/AssetService/AssetService.cs17
-rw-r--r--bin/OpenSim.ini.example62
9 files changed, 189 insertions, 98 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
index bb98f24..b53a2fb 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
@@ -75,14 +75,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
75 m_imageManager = imageManager; 75 m_imageManager = imageManager;
76 } 76 }
77 77
78 public bool SendPackets(LLClientView client, int maxpack) 78 /// <summary>
79 /// Sends packets for this texture to a client until packetsToSend is
80 /// hit or the transfer completes
81 /// </summary>
82 /// <param name="client">Reference to the client that the packets are destined for</param>
83 /// <param name="packetsToSend">Maximum number of packets to send during this call</param>
84 /// <param name="packetsSent">Number of packets sent during this call</param>
85 /// <returns>True if the transfer completes at the current discard level, otherwise false</returns>
86 public bool SendPackets(LLClientView client, int packetsToSend, out int packetsSent)
79 { 87 {
80 if (client == null) 88 packetsSent = 0;
81 return false;
82 89
83 if (m_currentPacket <= m_stopPacket) 90 if (m_currentPacket <= m_stopPacket)
84 { 91 {
85 int count = 0;
86 bool sendMore = true; 92 bool sendMore = true;
87 93
88 if (!m_sentInfo || (m_currentPacket == 0)) 94 if (!m_sentInfo || (m_currentPacket == 0))
@@ -91,25 +97,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
91 97
92 m_sentInfo = true; 98 m_sentInfo = true;
93 ++m_currentPacket; 99 ++m_currentPacket;
94 ++count; 100 ++packetsSent;
95 } 101 }
96 if (m_currentPacket < 2) 102 if (m_currentPacket < 2)
97 { 103 {
98 m_currentPacket = 2; 104 m_currentPacket = 2;
99 } 105 }
100 106
101 while (sendMore && count < maxpack && m_currentPacket <= m_stopPacket) 107 while (sendMore && packetsSent < packetsToSend && m_currentPacket <= m_stopPacket)
102 { 108 {
103 sendMore = SendPacket(client); 109 sendMore = SendPacket(client);
104 ++m_currentPacket; 110 ++m_currentPacket;
105 ++count; 111 ++packetsSent;
106 } 112 }
107
108 if (m_currentPacket > m_stopPacket)
109 return true;
110 } 113 }
111 114
112 return false; 115 return (m_currentPacket > m_stopPacket);
113 } 116 }
114 117
115 public void RunUpdate() 118 public void RunUpdate()
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index cfc1ebc..8487adc 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -314,10 +314,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
314 protected int m_primFullUpdatesPerPacket = 14; 314 protected int m_primFullUpdatesPerPacket = 14;
315 protected int m_primTerseUpdateRate = 10; 315 protected int m_primTerseUpdateRate = 10;
316 protected int m_primFullUpdateRate = 14; 316 protected int m_primFullUpdateRate = 14;
317 protected int m_textureSendLimit = 20;
318 protected int m_textureDataLimit = 10;
319 protected int m_avatarTerseUpdateRate = 50; 317 protected int m_avatarTerseUpdateRate = 50;
320 protected int m_avatarTerseUpdatesPerPacket = 5; 318 protected int m_avatarTerseUpdatesPerPacket = 5;
319 /// <summary>Number of texture packets to put on the queue each time the
320 /// OnQueueEmpty event is triggered for the texture category</summary>
321 protected int m_textureSendLimit = 20;
321 protected IAssetService m_assetService; 322 protected IAssetService m_assetService;
322 private IHyperAssetService m_hyperAssets; 323 private IHyperAssetService m_hyperAssets;
323 324
@@ -3457,7 +3458,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3457 void ProcessTextureRequests() 3458 void ProcessTextureRequests()
3458 { 3459 {
3459 if (m_imageManager != null) 3460 if (m_imageManager != null)
3460 m_imageManager.ProcessImageQueue(m_textureSendLimit, m_textureDataLimit); 3461 m_imageManager.ProcessImageQueue(m_textureSendLimit);
3461 } 3462 }
3462 3463
3463 void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) 3464 void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
index 681562b..25542ab 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
@@ -167,32 +167,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP
167 } 167 }
168 } 168 }
169 169
170 public bool ProcessImageQueue(int count, int maxpack) 170 public bool ProcessImageQueue(int packetsToSend)
171 { 171 {
172 J2KImage imagereq;
173 int numCollected = 0;
174
175 m_lastloopprocessed = DateTime.Now.Ticks; 172 m_lastloopprocessed = DateTime.Now.Ticks;
173 int packetsSent = 0;
176 174
177 // This can happen during Close() 175 while (packetsSent < packetsToSend)
178 if (m_client == null)
179 return false;
180
181 while ((imagereq = GetHighestPriorityImage()) != null)
182 { 176 {
183 if (imagereq.IsDecoded == true) 177 J2KImage image = GetHighestPriorityImage();
178
179 // If null was returned, the texture priority queue is currently empty
180 if (image == null)
181 return false;
182
183 if (image.IsDecoded)
184 { 184 {
185 ++numCollected; 185 int sent;
186 bool imageDone = image.SendPackets(m_client, packetsToSend - packetsSent, out sent);
186 187
187 if (imagereq.SendPackets(m_client, maxpack)) 188 packetsSent += sent;
188 {
189 // Send complete. Destroy any knowledge of this transfer
190 RemoveImageFromQueue(imagereq);
191 }
192 }
193 189
194 if (numCollected == count) 190 // If the send is complete, destroy any knowledge of this transfer
195 break; 191 if (imageDone)
192 RemoveImageFromQueue(image);
193 }
194 else
195 {
196 // TODO: This is a limitation of how LLImageManager is currently
197 // written. Undecoded textures should not be going into the priority
198 // queue, because a high priority undecoded texture will clog up the
199 // pipeline for a client
200 return true;
201 }
196 } 202 }
197 203
198 return m_priorityQueue.Count > 0; 204 return m_priorityQueue.Count > 0;
@@ -204,10 +210,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
204 public void Close() 210 public void Close()
205 { 211 {
206 m_shuttingdown = true; 212 m_shuttingdown = true;
207 m_priorityQueue = null;
208 m_j2kDecodeModule = null;
209 m_assetCache = null;
210 m_client = null;
211 } 213 }
212 214
213 #region Priority Queue Helpers 215 #region Priority Queue Helpers
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index e7707a9..39472cb 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Net; 30using System.Net;
31using log4net;
31using OpenSim.Framework; 32using OpenSim.Framework;
32using OpenMetaverse; 33using OpenMetaverse;
33 34
@@ -59,6 +60,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
59 /// </summary> 60 /// </summary>
60 public sealed class LLUDPClient 61 public sealed class LLUDPClient
61 { 62 {
63 private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
64
62 // FIXME: Make this a config setting 65 // FIXME: Make this a config setting
63 /// <summary>Percentage of the task throttle category that is allocated to avatar and prim 66 /// <summary>Percentage of the task throttle category that is allocated to avatar and prim
64 /// state updates</summary> 67 /// state updates</summary>
@@ -136,9 +139,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
136 /// <summary>A container that can hold one packet for each outbox, used to store 139 /// <summary>A container that can hold one packet for each outbox, used to store
137 /// dequeued packets that are being held for throttling</summary> 140 /// dequeued packets that are being held for throttling</summary>
138 private readonly OutgoingPacket[] nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; 141 private readonly OutgoingPacket[] nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
139 /// <summary>An optimization to store the length of dequeued packets being held 142 /// <summary>Flags to prevent queue empty callbacks from stacking up on
140 /// for throttling. This avoids expensive calls to Packet.Length</summary> 143 /// top of each other</summary>
141 private readonly int[] nextPacketLengths = new int[THROTTLE_CATEGORY_COUNT]; 144 private readonly bool[] onQueueEmptyRunning = new bool[THROTTLE_CATEGORY_COUNT];
142 /// <summary>A reference to the LLUDPServer that is managing this client</summary> 145 /// <summary>A reference to the LLUDPServer that is managing this client</summary>
143 private readonly LLUDPServer udpServer; 146 private readonly LLUDPServer udpServer;
144 147
@@ -163,7 +166,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
163 for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) 166 for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
164 packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); 167 packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
165 168
166 throttle = new TokenBucket(parentThrottle, 0, 0); 169 throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total);
167 throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT]; 170 throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];
168 throttleCategories[(int)ThrottleOutPacketType.Resend] = new TokenBucket(throttle, rates.ResendLimit, rates.Resend); 171 throttleCategories[(int)ThrottleOutPacketType.Resend] = new TokenBucket(throttle, rates.ResendLimit, rates.Resend);
169 throttleCategories[(int)ThrottleOutPacketType.Land] = new TokenBucket(throttle, rates.LandLimit, rates.Land); 172 throttleCategories[(int)ThrottleOutPacketType.Land] = new TokenBucket(throttle, rates.LandLimit, rates.Land);
@@ -401,10 +404,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
401 // This bucket was empty the last time we tried to send a packet, 404 // This bucket was empty the last time we tried to send a packet,
402 // leaving a dequeued packet still waiting to be sent out. Try to 405 // leaving a dequeued packet still waiting to be sent out. Try to
403 // send it again 406 // send it again
404 if (bucket.RemoveTokens(nextPacketLengths[i])) 407 OutgoingPacket nextPacket = nextPackets[i];
408 if (bucket.RemoveTokens(nextPacket.Buffer.DataLength))
405 { 409 {
406 // Send the packet 410 // Send the packet
407 udpServer.SendPacketFinal(nextPackets[i]); 411 udpServer.SendPacketFinal(nextPacket);
408 nextPackets[i] = null; 412 nextPackets[i] = null;
409 packetSent = true; 413 packetSent = true;
410 } 414 }
@@ -426,23 +430,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
426 } 430 }
427 else 431 else
428 { 432 {
429 // Save the dequeued packet and the length calculation for 433 // Save the dequeued packet for the next iteration
430 // the next iteration
431 nextPackets[i] = packet; 434 nextPackets[i] = packet;
432 nextPacketLengths[i] = packet.Buffer.DataLength;
433 } 435 }
434 436
435 // If the queue is empty after this dequeue, fire the queue 437 // If the queue is empty after this dequeue, fire the queue
436 // empty callback now so it has a chance to fill before we 438 // empty callback now so it has a chance to fill before we
437 // get back here 439 // get back here
438 if (queue.Count == 0) 440 if (queue.Count == 0)
439 FireQueueEmpty(i); 441 BeginFireQueueEmpty(i);
440 } 442 }
441 else 443 else
442 { 444 {
443 // No packets in this queue. Fire the queue empty callback 445 // No packets in this queue. Fire the queue empty callback
444 // if it has not been called recently 446 // if it has not been called recently
445 FireQueueEmpty(i); 447 BeginFireQueueEmpty(i);
446 } 448 }
447 } 449 }
448 } 450 }
@@ -450,6 +452,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
450 return packetSent; 452 return packetSent;
451 } 453 }
452 454
455 /// <summary>
456 /// Called when an ACK packet is received and a round-trip time for a
457 /// packet is calculated. This is used to calculate the smoothed
458 /// round-trip time, round trip time variance, and finally the
459 /// retransmission timeout
460 /// </summary>
461 /// <param name="r">Round-trip time of a single packet and its
462 /// acknowledgement</param>
453 public void UpdateRoundTrip(float r) 463 public void UpdateRoundTrip(float r)
454 { 464 {
455 const float ALPHA = 0.125f; 465 const float ALPHA = 0.125f;
@@ -475,11 +485,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP
475 // RTTVAR + " based on new RTT of " + r + "ms"); 485 // RTTVAR + " based on new RTT of " + r + "ms");
476 } 486 }
477 487
478 private void FireQueueEmpty(int queueIndex) 488 /// <summary>
489 /// Does an early check to see if this queue empty callback is already
490 /// running, then asynchronously firing the event
491 /// </summary>
492 /// <param name="throttleIndex">Throttle category to fire the callback
493 /// for</param>
494 private void BeginFireQueueEmpty(int throttleIndex)
479 { 495 {
496 if (!onQueueEmptyRunning[throttleIndex])
497 Util.FireAndForget(FireQueueEmpty, throttleIndex);
498 }
499
500 /// <summary>
501 /// Checks to see if this queue empty callback is already running,
502 /// then firing the event
503 /// </summary>
504 /// <param name="o">Throttle category to fire the callback for, stored
505 /// as an object to match the WaitCallback delegate signature</param>
506 private void FireQueueEmpty(object o)
507 {
508 int i = (int)o;
509 ThrottleOutPacketType type = (ThrottleOutPacketType)i;
480 QueueEmpty callback = OnQueueEmpty; 510 QueueEmpty callback = OnQueueEmpty;
511
481 if (callback != null) 512 if (callback != null)
482 Util.FireAndForget(delegate(object o) { callback((ThrottleOutPacketType)(int)o); }, queueIndex); 513 {
514 if (!onQueueEmptyRunning[i])
515 {
516 onQueueEmptyRunning[i] = true;
517 try { callback(type); }
518 catch (Exception e) { m_log.Error("[LLUDPCLIENT]: OnQueueEmpty(" + type + ") threw an exception: " + e.Message, e); }
519 onQueueEmptyRunning[i] = false;
520 }
521 }
483 } 522 }
484 } 523 }
485} 524}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 57fee59..1cfde91 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -109,6 +109,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
109 private Location m_location; 109 private Location m_location;
110 /// <summary>The measured resolution of Environment.TickCount</summary> 110 /// <summary>The measured resolution of Environment.TickCount</summary>
111 private float m_tickCountResolution; 111 private float m_tickCountResolution;
112 /// <summary>The size of the receive buffer for the UDP socket. This value
113 /// is passed up to the operating system and used in the system networking
114 /// stack. Use zero to leave this value as the default</summary>
115 private int m_recvBufferSize;
112 116
113 /// <summary>The measured resolution of Environment.TickCount</summary> 117 /// <summary>The measured resolution of Environment.TickCount</summary>
114 public float TickCountResolution { get { return m_tickCountResolution; } } 118 public float TickCountResolution { get { return m_tickCountResolution; } }
@@ -135,6 +139,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
135 139
136 m_circuitManager = circuitManager; 140 m_circuitManager = circuitManager;
137 141
142 IConfig config = configSource.Configs["ClientStack.LindenUDP"];
143 if (config != null)
144 {
145 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
146 }
147
138 // TODO: Config support for throttling the entire connection 148 // TODO: Config support for throttling the entire connection
139 m_throttle = new TokenBucket(null, 0, 0); 149 m_throttle = new TokenBucket(null, 0, 0);
140 m_throttleRates = new ThrottleRates(configSource); 150 m_throttleRates = new ThrottleRates(configSource);
@@ -145,7 +155,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
145 if (m_scene == null) 155 if (m_scene == null)
146 throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); 156 throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
147 157
148 base.Start(); 158 base.Start(m_recvBufferSize);
149 159
150 // Start the incoming packet processing thread 160 // Start the incoming packet processing thread
151 Thread incomingThread = new Thread(IncomingPacketHandler); 161 Thread incomingThread = new Thread(IncomingPacketHandler);
diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
index fad2ea8..44a6ed6 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs
@@ -73,6 +73,7 @@ namespace OpenMetaverse
73 /// </summary> 73 /// </summary>
74 /// <param name="bindAddress">Local IP address to bind the server to</param> 74 /// <param name="bindAddress">Local IP address to bind the server to</param>
75 /// <param name="port">Port to listening for incoming UDP packets on</param> 75 /// <param name="port">Port to listening for incoming UDP packets on</param>
76 ///
76 public OpenSimUDPBase(IPAddress bindAddress, int port) 77 public OpenSimUDPBase(IPAddress bindAddress, int port)
77 { 78 {
78 m_localBindAddress = bindAddress; 79 m_localBindAddress = bindAddress;
@@ -82,25 +83,31 @@ namespace OpenMetaverse
82 /// <summary> 83 /// <summary>
83 /// Start the UDP server 84 /// Start the UDP server
84 /// </summary> 85 /// </summary>
86 /// <param name="recvBufferSize">The size of the receive buffer for
87 /// the UDP socket. This value is passed up to the operating system
88 /// and used in the system networking stack. Use zero to leave this
89 /// value as the default</param>
85 /// <remarks>This method will attempt to set the SIO_UDP_CONNRESET flag 90 /// <remarks>This method will attempt to set the SIO_UDP_CONNRESET flag
86 /// on the socket to get newer versions of Windows to behave in a sane 91 /// on the socket to get newer versions of Windows to behave in a sane
87 /// manner (not throwing an exception when the remote side resets the 92 /// manner (not throwing an exception when the remote side resets the
88 /// connection). This call is ignored on Mono where the flag is not 93 /// connection). This call is ignored on Mono where the flag is not
89 /// necessary</remarks> 94 /// necessary</remarks>
90 public void Start() 95 public void Start(int recvBufferSize)
91 { 96 {
92 if (m_shutdownFlag) 97 if (m_shutdownFlag)
93 { 98 {
94 const int SIO_UDP_CONNRESET = -1744830452; 99 const int SIO_UDP_CONNRESET = -1744830452;
95 100
96 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort); 101 IPEndPoint ipep = new IPEndPoint(m_localBindAddress, m_udpPort);
102
97 m_udpSocket = new Socket( 103 m_udpSocket = new Socket(
98 AddressFamily.InterNetwork, 104 AddressFamily.InterNetwork,
99 SocketType.Dgram, 105 SocketType.Dgram,
100 ProtocolType.Udp); 106 ProtocolType.Udp);
107
101 try 108 try
102 { 109 {
103 // this udp socket flag is not supported under mono, 110 // This udp socket flag is not supported under mono,
104 // so we'll catch the exception and continue 111 // so we'll catch the exception and continue
105 m_udpSocket.IOControl(SIO_UDP_CONNRESET, new byte[] { 0 }, null); 112 m_udpSocket.IOControl(SIO_UDP_CONNRESET, new byte[] { 0 }, null);
106 m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag set"); 113 m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag set");
@@ -109,6 +116,10 @@ namespace OpenMetaverse
109 { 116 {
110 m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring"); 117 m_log.Debug("[UDPBASE]: SIO_UDP_CONNRESET flag not supported on this platform, ignoring");
111 } 118 }
119
120 if (recvBufferSize != 0)
121 m_udpSocket.ReceiveBufferSize = recvBufferSize;
122
112 m_udpSocket.Bind(ipep); 123 m_udpSocket.Bind(ipep);
113 124
114 // we're not shutting down, we're starting up 125 // we're not shutting down, we're starting up
diff --git a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs
index 858a03c..adad4c3 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/ThrottleRates.cs
@@ -51,6 +51,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
51 public int Texture; 51 public int Texture;
52 /// <summary>Drip rate for asset packets</summary> 52 /// <summary>Drip rate for asset packets</summary>
53 public int Asset; 53 public int Asset;
54 /// <summary>Drip rate for the parent token bucket</summary>
55 public int Total;
54 56
55 /// <summary>Maximum burst rate for resent packets</summary> 57 /// <summary>Maximum burst rate for resent packets</summary>
56 public int ResendLimit; 58 public int ResendLimit;
@@ -66,6 +68,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
66 public int TextureLimit; 68 public int TextureLimit;
67 /// <summary>Maximum burst rate for asset packets</summary> 69 /// <summary>Maximum burst rate for asset packets</summary>
68 public int AssetLimit; 70 public int AssetLimit;
71 /// <summary>Burst rate for the parent token bucket</summary>
72 public int TotalLimit;
69 73
70 /// <summary> 74 /// <summary>
71 /// Default constructor 75 /// Default constructor
@@ -77,21 +81,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
77 { 81 {
78 IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"]; 82 IConfig throttleConfig = config.Configs["ClientStack.LindenUDP"];
79 83
80 Resend = throttleConfig.GetInt("ResendDefault", 12500); 84 Resend = throttleConfig.GetInt("resend_default", 12500);
81 Land = throttleConfig.GetInt("LandDefault", 500); 85 Land = throttleConfig.GetInt("land_default", 500);
82 Wind = throttleConfig.GetInt("WindDefault", 500); 86 Wind = throttleConfig.GetInt("wind_default", 500);
83 Cloud = throttleConfig.GetInt("CloudDefault", 500); 87 Cloud = throttleConfig.GetInt("cloud_default", 500);
84 Task = throttleConfig.GetInt("TaskDefault", 500); 88 Task = throttleConfig.GetInt("task_default", 500);
85 Texture = throttleConfig.GetInt("TextureDefault", 500); 89 Texture = throttleConfig.GetInt("texture_default", 500);
86 Asset = throttleConfig.GetInt("AssetDefault", 500); 90 Asset = throttleConfig.GetInt("asset_default", 500);
87 91
88 ResendLimit = throttleConfig.GetInt("ResendLimit", 18750); 92 Total = throttleConfig.GetInt("client_throttle_max_bps", 0);
89 LandLimit = throttleConfig.GetInt("LandLimit", 29750); 93
90 WindLimit = throttleConfig.GetInt("WindLimit", 18750); 94 ResendLimit = throttleConfig.GetInt("resend_limit", 18750);
91 CloudLimit = throttleConfig.GetInt("CloudLimit", 18750); 95 LandLimit = throttleConfig.GetInt("land_limit", 29750);
92 TaskLimit = throttleConfig.GetInt("TaskLimit", 55750); 96 WindLimit = throttleConfig.GetInt("wind_limit", 18750);
93 TextureLimit = throttleConfig.GetInt("TextureLimit", 55750); 97 CloudLimit = throttleConfig.GetInt("cloud_limit", 18750);
94 AssetLimit = throttleConfig.GetInt("AssetLimit", 27500); 98 TaskLimit = throttleConfig.GetInt("task_limit", 55750);
99 TextureLimit = throttleConfig.GetInt("texture_limit", 55750);
100 AssetLimit = throttleConfig.GetInt("asset_limit", 27500);
101
102 TotalLimit = throttleConfig.GetInt("client_throttle_max_bps", 0);
95 } 103 }
96 catch (Exception) { } 104 catch (Exception) { }
97 } 105 }
diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs
index ebfd47a..df33db2 100644
--- a/OpenSim/Services/AssetService/AssetService.cs
+++ b/OpenSim/Services/AssetService/AssetService.cs
@@ -64,12 +64,17 @@ namespace OpenSim.Services.AssetService
64 string loaderArgs = assetConfig.GetString("AssetLoaderArgs", 64 string loaderArgs = assetConfig.GetString("AssetLoaderArgs",
65 String.Empty); 65 String.Empty);
66 66
67 m_log.InfoFormat("[ASSET]: Loading default asset set from {0}", loaderArgs); 67 bool assetLoaderEnabled = assetConfig.GetBoolean("AssetLoaderEnabled", true);
68 m_AssetLoader.ForEachDefaultXmlAsset(loaderArgs, 68
69 delegate(AssetBase a) 69 if (assetLoaderEnabled)
70 { 70 {
71 Store(a); 71 m_log.InfoFormat("[ASSET]: Loading default asset set from {0}", loaderArgs);
72 }); 72 m_AssetLoader.ForEachDefaultXmlAsset(loaderArgs,
73 delegate(AssetBase a)
74 {
75 Store(a);
76 });
77 }
73 78
74 m_log.Info("[ASSET CONNECTOR]: Local asset service enabled"); 79 m_log.Info("[ASSET CONNECTOR]: Local asset service enabled");
75 } 80 }
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 5cb51b2..0ab6257 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -341,25 +341,6 @@
341 341
342 342
343[ClientStack.LindenUDP] 343[ClientStack.LindenUDP]
344 ; This is the multiplier applied to all client throttles for outgoing UDP network data
345 ; If it is set to 1, then we obey the throttle settings as given to us by the client. If it is set to 3, for example, then we
346 ; multiply that setting by 3 (e.g. if the client gives us a setting of 250 kilobits per second then we
347 ; will actually push down data at a maximum rate of 750 kilobits per second).
348 ;
349 ; In principle, setting a multiplier greater than 1 will allow data to be pushed down to a client much faster
350 ; than its UI allows the setting to go. This may be okay in some situations, such as standalone OpenSim
351 ; applications on a LAN. However, the greater the multipler, the higher the risk of packet drop, resulting
352 ; in symptoms such as missing terrain or objects. A much better solution is to change the client UI to allow
353 ; higher network bandwidth settings directly, though this isn't always possible.
354 ;
355 ; Currently this setting is 2 by default because we currently send much more texture data than is strictly
356 ; necessary. A setting of 1 could result in slow texture transfer. This will be fixed when the transfer
357 ; of textures at different levels of quality is improved.
358 ;
359 ; Pre r7113, this setting was not exposed but was effectively 8. You may want to try this if you encounter
360 ; unexpected difficulties
361 client_throttle_multiplier = 2;
362
363 ; the client socket receive buffer size determines how many 344 ; the client socket receive buffer size determines how many
364 ; incoming requests we can process; the default on .NET is 8192 345 ; incoming requests we can process; the default on .NET is 8192
365 ; which is about 2 4k-sized UDP datagrams. On mono this is 346 ; which is about 2 4k-sized UDP datagrams. On mono this is
@@ -374,12 +355,39 @@
374 ; by the system's settings for the maximum client receive buffer 355 ; by the system's settings for the maximum client receive buffer
375 ; size (on linux systems you can set that with "sysctl -w 356 ; size (on linux systems you can set that with "sysctl -w
376 ; net.core.rmem_max=X") 357 ; net.core.rmem_max=X")
377 ; 358 ;client_socket_rcvbuf_size = 8388608
378 ; client_socket_rcvbuf_size = 8388608 359
379 360 ; Maximum outbound bits per second for a single scene. This can be used to
380 ; Maximum bits per second to send to any single client. This will override the user's viewer preference settings. 361 ; throttle total outbound UDP traffic for a simulator. The default value is
381 362 ; 0, meaning no throttling at the scene level. The example given here is
382 ; client_throttle_max_bps = 1500000 363 ; 20 megabits
364 ;scene_throttle_max_bps = 20971520
365
366 ; Maximum bits per second to send to any single client. This will override
367 ; the user's viewer preference settings. The default value is 0, meaning no
368 ; aggregate throttling on clients (only per-category throttling). The
369 ; example given here is 1.5 megabits
370 ;client_throttle_max_bps = 1572864
371
372 ; Per-client bits per second rates for the various throttle categories.
373 ; These are default values that will be overriden by clients
374 ;resend_default = 12500
375 ;land_default = 500
376 ;wind_default = 500
377 ;cloud_default = 50
378 ;task_default = 500
379 ;texture_default = 500
380 ;asset_default = 500
381
382 ; Per-client maximum burst rates in bits per second for the various throttle
383 ; categories. These are default values that will be overriden by clients
384 ;resend_limit = 18750
385 ;land_limit = 29750
386 ;wind_limit = 18750
387 ;cloud_limit = 18750
388 ;task_limit = 55750
389 ;texture_limit = 55750
390 ;asset_limit = 27500
383 391
384[Chat] 392[Chat]
385 ; Controls whether the chat module is enabled. Default is true. 393 ; Controls whether the chat module is enabled. Default is true.
@@ -1381,6 +1389,10 @@
1381[AssetService] 1389[AssetService]
1382 DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll" 1390 DefaultAssetLoader = "OpenSim.Framework.AssetLoader.Filesystem.dll"
1383 AssetLoaderArgs = "assets/AssetSets.xml" 1391 AssetLoaderArgs = "assets/AssetSets.xml"
1392
1393 ; Disable this to prevent the default asset set from being inserted into the
1394 ; asset store each time the region starts
1395 AssetLoaderEnabled = true
1384 1396
1385[GridService] 1397[GridService]
1386 ;; default standalone, overridable in StandaloneCommon.ini 1398 ;; default standalone, overridable in StandaloneCommon.ini