aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJohn Hurliman2009-10-20 18:19:17 -0700
committerJohn Hurliman2009-10-20 18:19:17 -0700
commit45dc4e0a5442d1d03f7387164070145386a9b4e1 (patch)
tree59d7ee9829ae7a1a5909d6b7b4f51304fa54e0c4
parent* Removed the unused m_agentUpdates collection and some extra work that was b... (diff)
downloadopensim-SC-45dc4e0a5442d1d03f7387164070145386a9b4e1.zip
opensim-SC-45dc4e0a5442d1d03f7387164070145386a9b4e1.tar.gz
opensim-SC-45dc4e0a5442d1d03f7387164070145386a9b4e1.tar.bz2
opensim-SC-45dc4e0a5442d1d03f7387164070145386a9b4e1.tar.xz
* Added a sanity check to GetScriptAssemblies() and GetScriptStates() for the case where no scripting engine is enabled
* Added TokenBucket.cs to OpenSim, with some fixes for setting a more accurate MaxBurst value and getting a more accurate Content value (by Drip()ing each get)
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs2
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs2
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs213
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs26
5 files changed, 235 insertions, 10 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index bf0fda3..134cfe5 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -33,6 +33,8 @@ using OpenSim.Framework;
33using OpenMetaverse; 33using OpenMetaverse;
34using OpenMetaverse.Packets; 34using OpenMetaverse.Packets;
35 35
36using TokenBucket = OpenSim.Region.ClientStack.LindenUDP.TokenBucket;
37
36namespace OpenSim.Region.ClientStack.LindenUDP 38namespace OpenSim.Region.ClientStack.LindenUDP
37{ 39{
38 #region Delegates 40 #region Delegates
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 80ef95e..952d147 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -39,6 +39,8 @@ using OpenSim.Framework.Statistics;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenMetaverse; 40using OpenMetaverse;
41 41
42using TokenBucket = OpenSim.Region.ClientStack.LindenUDP.TokenBucket;
43
42namespace OpenSim.Region.ClientStack.LindenUDP 44namespace OpenSim.Region.ClientStack.LindenUDP
43{ 45{
44 /// <summary> 46 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs
new file mode 100644
index 0000000..0a64095
--- /dev/null
+++ b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs
@@ -0,0 +1,213 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29
30namespace OpenSim.Region.ClientStack.LindenUDP
31{
32 /// <summary>
33 /// A hierarchical token bucket for bandwidth throttling. See
34 /// http://en.wikipedia.org/wiki/Token_bucket for more information
35 /// </summary>
36 public class TokenBucket
37 {
38 /// <summary>Parent bucket to this bucket, or null if this is a root
39 /// bucket</summary>
40 TokenBucket parent;
41 /// <summary>Size of the bucket in bytes. If zero, the bucket has
42 /// infinite capacity</summary>
43 int maxBurst;
44 /// <summary>Rate that the bucket fills, in bytes per millisecond. If
45 /// zero, the bucket always remains full</summary>
46 int tokensPerMS;
47 /// <summary>Number of tokens currently in the bucket</summary>
48 int content;
49 /// <summary>Time of the last drip, in system ticks</summary>
50 int lastDrip;
51
52 #region Properties
53
54 /// <summary>
55 /// The parent bucket of this bucket, or null if this bucket has no
56 /// parent. The parent bucket will limit the aggregate bandwidth of all
57 /// of its children buckets
58 /// </summary>
59 public TokenBucket Parent
60 {
61 get { return parent; }
62 }
63
64 /// <summary>
65 /// Maximum burst rate in bytes per second. This is the maximum number
66 /// of tokens that can accumulate in the bucket at any one time
67 /// </summary>
68 public int MaxBurst
69 {
70 get { return maxBurst; }
71 set { maxBurst = (value >= 0 ? value : 0); }
72 }
73
74 /// <summary>
75 /// The speed limit of this bucket in bytes per second. This is the
76 /// number of tokens that are added to the bucket per second
77 /// </summary>
78 /// <remarks>Tokens are added to the bucket any time
79 /// <seealso cref="RemoveTokens"/> is called, at the granularity of
80 /// the system tick interval (typically around 15-22ms)</remarks>
81 public int DripRate
82 {
83 get { return tokensPerMS * 1000; }
84 set
85 {
86 if (value == 0)
87 tokensPerMS = 0;
88 else
89 {
90 int bpms = (int)((float)value / 1000.0f);
91
92 if (bpms <= 0)
93 tokensPerMS = 1; // 1 byte/ms is the minimum granularity
94 else
95 tokensPerMS = bpms;
96 }
97 }
98 }
99
100 /// <summary>
101 /// The number of bytes that can be sent at this moment. This is the
102 /// current number of tokens in the bucket
103 /// <remarks>If this bucket has a parent bucket that does not have
104 /// enough tokens for a request, <seealso cref="RemoveTokens"/> will
105 /// return false regardless of the content of this bucket</remarks>
106 /// </summary>
107 public int Content
108 {
109 get
110 {
111 Drip();
112 return content;
113 }
114 }
115
116 #endregion Properties
117
118 /// <summary>
119 /// Default constructor
120 /// </summary>
121 /// <param name="parent">Parent bucket if this is a child bucket, or
122 /// null if this is a root bucket</param>
123 /// <param name="maxBurst">Maximum size of the bucket in bytes, or
124 /// zero if this bucket has no maximum capacity</param>
125 /// <param name="dripRate">Rate that the bucket fills, in bytes per
126 /// second. If zero, the bucket always remains full</param>
127 public TokenBucket(TokenBucket parent, int maxBurst, int dripRate)
128 {
129 this.parent = parent;
130 MaxBurst = maxBurst;
131 DripRate = dripRate;
132 lastDrip = Environment.TickCount & Int32.MaxValue;
133 }
134
135 /// <summary>
136 /// Remove a given number of tokens from the bucket
137 /// </summary>
138 /// <param name="amount">Number of tokens to remove from the bucket</param>
139 /// <returns>True if the requested number of tokens were removed from
140 /// the bucket, otherwise false</returns>
141 public bool RemoveTokens(int amount)
142 {
143 bool dummy;
144 return RemoveTokens(amount, out dummy);
145 }
146
147 /// <summary>
148 /// Remove a given number of tokens from the bucket
149 /// </summary>
150 /// <param name="amount">Number of tokens to remove from the bucket</param>
151 /// <param name="dripSucceeded">True if tokens were added to the bucket
152 /// during this call, otherwise false</param>
153 /// <returns>True if the requested number of tokens were removed from
154 /// the bucket, otherwise false</returns>
155 public bool RemoveTokens(int amount, out bool dripSucceeded)
156 {
157 if (maxBurst == 0)
158 {
159 dripSucceeded = true;
160 return true;
161 }
162
163 dripSucceeded = Drip();
164
165 if (content - amount >= 0)
166 {
167 if (parent != null && !parent.RemoveTokens(amount))
168 return false;
169
170 content -= amount;
171 return true;
172 }
173 else
174 {
175 return false;
176 }
177 }
178
179 /// <summary>
180 /// Add tokens to the bucket over time. The number of tokens added each
181 /// call depends on the length of time that has passed since the last
182 /// call to Drip
183 /// </summary>
184 /// <returns>True if tokens were added to the bucket, otherwise false</returns>
185 private bool Drip()
186 {
187 if (tokensPerMS == 0)
188 {
189 content = maxBurst;
190 return true;
191 }
192 else
193 {
194 int now = Environment.TickCount & Int32.MaxValue;
195 int deltaMS = now - lastDrip;
196
197 if (deltaMS <= 0)
198 {
199 if (deltaMS < 0)
200 lastDrip = now;
201 return false;
202 }
203
204 int dripAmount = deltaMS * tokensPerMS;
205
206 content = Math.Min(content + dripAmount, maxBurst);
207 lastDrip = now;
208
209 return true;
210 }
211 }
212 }
213}
diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs
index f3242c1..87c7df4 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs
@@ -147,6 +147,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
147 int now = Environment.TickCount; 147 int now = Environment.TickCount;
148 foreach (OutgoingPacket packet in packets.Values) 148 foreach (OutgoingPacket packet in packets.Values)
149 { 149 {
150 // TickCount of zero means a packet is in the resend queue
151 // but hasn't actually been sent over the wire yet
150 if (packet.TickCount == 0) 152 if (packet.TickCount == 0)
151 continue; 153 continue;
152 154
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 098e010..f4ca877 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -871,12 +871,15 @@ namespace OpenSim.Region.Framework.Scenes
871 { 871 {
872 foreach (IScriptModule e in engines) 872 foreach (IScriptModule e in engines)
873 { 873 {
874 string n = e.GetAssemblyName(item.ItemID); 874 if (e != null)
875 if (n != "")
876 { 875 {
877 if (!ret.Contains(n)) 876 string n = e.GetAssemblyName(item.ItemID);
878 ret.Add(n); 877 if (n != String.Empty)
879 break; 878 {
879 if (!ret.Contains(n))
880 ret.Add(n);
881 break;
882 }
880 } 883 }
881 } 884 }
882 } 885 }
@@ -898,12 +901,15 @@ namespace OpenSim.Region.Framework.Scenes
898 { 901 {
899 foreach (IScriptModule e in engines) 902 foreach (IScriptModule e in engines)
900 { 903 {
901 string n = e.GetXMLState(item.ItemID); 904 if (e != null)
902 if (n != "")
903 { 905 {
904 if (!ret.ContainsKey(item.ItemID)) 906 string n = e.GetXMLState(item.ItemID);
905 ret[item.ItemID] = n; 907 if (n != String.Empty)
906 break; 908 {
909 if (!ret.ContainsKey(item.ItemID))
910 ret[item.ItemID] = n;
911 break;
912 }
907 } 913 }
908 } 914 }
909 } 915 }