diff options
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r-- | OpenSim/Framework/Console/CommandConsole.cs | 122 | ||||
-rw-r--r-- | OpenSim/Framework/GcNotify.cs | 62 | ||||
-rw-r--r-- | OpenSim/Framework/IClientAPI.cs | 3 | ||||
-rw-r--r-- | OpenSim/Framework/ICommandConsole.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/ILandObject.cs | 1 | ||||
-rw-r--r-- | OpenSim/Framework/MultipartForm.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/RegionInfo.cs | 6 | ||||
-rw-r--r-- | OpenSim/Framework/SLUtil.cs | 4 | ||||
-rw-r--r-- | OpenSim/Framework/Servers/BaseOpenSimServer.cs | 36 | ||||
-rw-r--r-- | OpenSim/Framework/Statistics/BaseStatsCollector.cs | 8 | ||||
-rw-r--r-- | OpenSim/Framework/Util.cs | 230 | ||||
-rw-r--r-- | OpenSim/Framework/WebUtil.cs | 48 |
12 files changed, 412 insertions, 112 deletions
diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index 0d6288b..c5d6b78 100644 --- a/OpenSim/Framework/Console/CommandConsole.cs +++ b/OpenSim/Framework/Console/CommandConsole.cs | |||
@@ -29,6 +29,7 @@ using System; | |||
29 | using System.Xml; | 29 | using System.Xml; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Diagnostics; | 31 | using System.Diagnostics; |
32 | using System.Linq; | ||
32 | using System.Reflection; | 33 | using System.Reflection; |
33 | using System.Text; | 34 | using System.Text; |
34 | using System.Text.RegularExpressions; | 35 | using System.Text.RegularExpressions; |
@@ -40,6 +41,8 @@ namespace OpenSim.Framework.Console | |||
40 | { | 41 | { |
41 | public class Commands : ICommands | 42 | public class Commands : ICommands |
42 | { | 43 | { |
44 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
45 | |||
43 | /// <summary> | 46 | /// <summary> |
44 | /// Encapsulates a command that can be invoked from the console | 47 | /// Encapsulates a command that can be invoked from the console |
45 | /// </summary> | 48 | /// </summary> |
@@ -76,6 +79,8 @@ namespace OpenSim.Framework.Console | |||
76 | public List<CommandDelegate> fn; | 79 | public List<CommandDelegate> fn; |
77 | } | 80 | } |
78 | 81 | ||
82 | public const string GeneralHelpText = "For more information, type 'help <item>' where <item> is one of the following categories:"; | ||
83 | |||
79 | /// <value> | 84 | /// <value> |
80 | /// Commands organized by keyword in a tree | 85 | /// Commands organized by keyword in a tree |
81 | /// </value> | 86 | /// </value> |
@@ -83,6 +88,11 @@ namespace OpenSim.Framework.Console | |||
83 | new Dictionary<string, object>(); | 88 | new Dictionary<string, object>(); |
84 | 89 | ||
85 | /// <summary> | 90 | /// <summary> |
91 | /// Commands organized by module | ||
92 | /// </summary> | ||
93 | private Dictionary<string, List<CommandInfo>> m_modulesCommands = new Dictionary<string, List<CommandInfo>>(); | ||
94 | |||
95 | /// <summary> | ||
86 | /// Get help for the given help string | 96 | /// Get help for the given help string |
87 | /// </summary> | 97 | /// </summary> |
88 | /// <param name="helpParts">Parsed parts of the help string. If empty then general help is returned.</param> | 98 | /// <param name="helpParts">Parsed parts of the help string. If empty then general help is returned.</param> |
@@ -98,8 +108,8 @@ namespace OpenSim.Framework.Console | |||
98 | // General help | 108 | // General help |
99 | if (helpParts.Count == 0) | 109 | if (helpParts.Count == 0) |
100 | { | 110 | { |
101 | help.AddRange(CollectHelp(tree)); | 111 | help.Add(GeneralHelpText); |
102 | help.Sort(); | 112 | help.AddRange(CollectModulesHelp(tree)); |
103 | } | 113 | } |
104 | else | 114 | else |
105 | { | 115 | { |
@@ -118,6 +128,13 @@ namespace OpenSim.Framework.Console | |||
118 | { | 128 | { |
119 | string originalHelpRequest = string.Join(" ", helpParts.ToArray()); | 129 | string originalHelpRequest = string.Join(" ", helpParts.ToArray()); |
120 | List<string> help = new List<string>(); | 130 | List<string> help = new List<string>(); |
131 | |||
132 | // Check modules first to see if we just need to display a list of those commands | ||
133 | if (TryCollectModuleHelp(originalHelpRequest, help)) | ||
134 | { | ||
135 | help.Insert(0, GeneralHelpText); | ||
136 | return help; | ||
137 | } | ||
121 | 138 | ||
122 | Dictionary<string, object> dict = tree; | 139 | Dictionary<string, object> dict = tree; |
123 | while (helpParts.Count > 0) | 140 | while (helpParts.Count > 0) |
@@ -161,25 +178,63 @@ namespace OpenSim.Framework.Console | |||
161 | return help; | 178 | return help; |
162 | } | 179 | } |
163 | 180 | ||
164 | private List<string> CollectHelp(Dictionary<string, object> dict) | 181 | /// <summary> |
182 | /// Try to collect help for the given module if that module exists. | ||
183 | /// </summary> | ||
184 | /// <param name="moduleName"></param> | ||
185 | /// <param name="helpText">/param> | ||
186 | /// <returns>true if there was the module existed, false otherwise.</returns> | ||
187 | private bool TryCollectModuleHelp(string moduleName, List<string> helpText) | ||
165 | { | 188 | { |
166 | List<string> result = new List<string>(); | 189 | lock (m_modulesCommands) |
167 | |||
168 | foreach (KeyValuePair<string, object> kvp in dict) | ||
169 | { | 190 | { |
170 | if (kvp.Value is Dictionary<string, Object>) | 191 | foreach (string key in m_modulesCommands.Keys) |
171 | { | 192 | { |
172 | result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value)); | 193 | // Allow topic help requests to succeed whether they are upper or lowercase. |
173 | } | 194 | if (moduleName.ToLower() == key.ToLower()) |
174 | else | 195 | { |
175 | { | 196 | List<CommandInfo> commands = m_modulesCommands[key]; |
176 | if (((CommandInfo)kvp.Value).long_help != String.Empty) | 197 | var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help)); |
177 | result.Add(((CommandInfo)kvp.Value).help_text+" - "+ | 198 | ourHelpText.Sort(); |
178 | ((CommandInfo)kvp.Value).long_help); | 199 | helpText.AddRange(ourHelpText); |
200 | |||
201 | return true; | ||
202 | } | ||
179 | } | 203 | } |
204 | |||
205 | return false; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | private List<string> CollectModulesHelp(Dictionary<string, object> dict) | ||
210 | { | ||
211 | lock (m_modulesCommands) | ||
212 | { | ||
213 | List<string> helpText = new List<string>(m_modulesCommands.Keys); | ||
214 | helpText.Sort(); | ||
215 | return helpText; | ||
180 | } | 216 | } |
181 | return result; | ||
182 | } | 217 | } |
218 | |||
219 | // private List<string> CollectHelp(Dictionary<string, object> dict) | ||
220 | // { | ||
221 | // List<string> result = new List<string>(); | ||
222 | // | ||
223 | // foreach (KeyValuePair<string, object> kvp in dict) | ||
224 | // { | ||
225 | // if (kvp.Value is Dictionary<string, Object>) | ||
226 | // { | ||
227 | // result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value)); | ||
228 | // } | ||
229 | // else | ||
230 | // { | ||
231 | // if (((CommandInfo)kvp.Value).long_help != String.Empty) | ||
232 | // result.Add(((CommandInfo)kvp.Value).help_text+" - "+ | ||
233 | // ((CommandInfo)kvp.Value).long_help); | ||
234 | // } | ||
235 | // } | ||
236 | // return result; | ||
237 | // } | ||
183 | 238 | ||
184 | /// <summary> | 239 | /// <summary> |
185 | /// Add a command to those which can be invoked from the console. | 240 | /// Add a command to those which can be invoked from the console. |
@@ -212,21 +267,19 @@ namespace OpenSim.Framework.Console | |||
212 | 267 | ||
213 | Dictionary<string, Object> current = tree; | 268 | Dictionary<string, Object> current = tree; |
214 | 269 | ||
215 | foreach (string s in parts) | 270 | foreach (string part in parts) |
216 | { | 271 | { |
217 | if (current.ContainsKey(s)) | 272 | if (current.ContainsKey(part)) |
218 | { | 273 | { |
219 | if (current[s] is Dictionary<string, Object>) | 274 | if (current[part] is Dictionary<string, Object>) |
220 | { | 275 | current = (Dictionary<string, Object>)current[part]; |
221 | current = (Dictionary<string, Object>)current[s]; | ||
222 | } | ||
223 | else | 276 | else |
224 | return; | 277 | return; |
225 | } | 278 | } |
226 | else | 279 | else |
227 | { | 280 | { |
228 | current[s] = new Dictionary<string, Object>(); | 281 | current[part] = new Dictionary<string, Object>(); |
229 | current = (Dictionary<string, Object>)current[s]; | 282 | current = (Dictionary<string, Object>)current[part]; |
230 | } | 283 | } |
231 | } | 284 | } |
232 | 285 | ||
@@ -250,6 +303,24 @@ namespace OpenSim.Framework.Console | |||
250 | info.fn = new List<CommandDelegate>(); | 303 | info.fn = new List<CommandDelegate>(); |
251 | info.fn.Add(fn); | 304 | info.fn.Add(fn); |
252 | current[String.Empty] = info; | 305 | current[String.Empty] = info; |
306 | |||
307 | // Now add command to modules dictionary | ||
308 | lock (m_modulesCommands) | ||
309 | { | ||
310 | List<CommandInfo> commands; | ||
311 | if (m_modulesCommands.ContainsKey(module)) | ||
312 | { | ||
313 | commands = m_modulesCommands[module]; | ||
314 | } | ||
315 | else | ||
316 | { | ||
317 | commands = new List<CommandInfo>(); | ||
318 | m_modulesCommands[module] = commands; | ||
319 | } | ||
320 | |||
321 | // m_log.DebugFormat("[COMMAND CONSOLE]: Adding to category {0} command {1}", module, command); | ||
322 | commands.Add(info); | ||
323 | } | ||
253 | } | 324 | } |
254 | 325 | ||
255 | public string[] FindNextOption(string[] cmd, bool term) | 326 | public string[] FindNextOption(string[] cmd, bool term) |
@@ -607,8 +678,9 @@ namespace OpenSim.Framework.Console | |||
607 | { | 678 | { |
608 | Commands = new Commands(); | 679 | Commands = new Commands(); |
609 | 680 | ||
610 | Commands.AddCommand("console", false, "help", "help [<command>]", | 681 | Commands.AddCommand( |
611 | "Get general command list or more detailed help on a specific command", Help); | 682 | "Help", false, "help", "help [<item>]", |
683 | "Display help on a particular command or on a list of commands in a category", Help); | ||
612 | } | 684 | } |
613 | 685 | ||
614 | private void Help(string module, string[] cmd) | 686 | private void Help(string module, string[] cmd) |
diff --git a/OpenSim/Framework/GcNotify.cs b/OpenSim/Framework/GcNotify.cs new file mode 100644 index 0000000..14a22a6 --- /dev/null +++ b/OpenSim/Framework/GcNotify.cs | |||
@@ -0,0 +1,62 @@ | |||
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 | |||
28 | using System; | ||
29 | using System.Reflection; | ||
30 | using log4net; | ||
31 | |||
32 | public class GcNotify | ||
33 | { | ||
34 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
35 | |||
36 | public static bool Enabled | ||
37 | { | ||
38 | get { return s_initialized; } | ||
39 | set | ||
40 | { | ||
41 | if (!s_initialized && value) | ||
42 | new GcNotify(); | ||
43 | |||
44 | s_initialized = value; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | private static bool s_initialized = false; | ||
49 | |||
50 | private GcNotify() {} | ||
51 | |||
52 | ~GcNotify() | ||
53 | { | ||
54 | if (!Environment.HasShutdownStarted && !AppDomain.CurrentDomain.IsFinalizingForUnload()) | ||
55 | { | ||
56 | m_log.DebugFormat("[GC NOTIFY]: Garbage collection triggered."); | ||
57 | |||
58 | if (Enabled) | ||
59 | new GcNotify(); | ||
60 | } | ||
61 | } | ||
62 | } \ No newline at end of file | ||
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index c85e599..3f560d0 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -1215,10 +1215,9 @@ namespace OpenSim.Framework | |||
1215 | /// <param name="OrbitalPosition">The orbital position is given in radians, and must be "adjusted" for the linden client, see LLClientView</param> | 1215 | /// <param name="OrbitalPosition">The orbital position is given in radians, and must be "adjusted" for the linden client, see LLClientView</param> |
1216 | void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, | 1216 | void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, |
1217 | float OrbitalPosition); | 1217 | float OrbitalPosition); |
1218 | 1218 | ||
1219 | void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks); | 1219 | void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks); |
1220 | void SendViewerTime(int phase); | 1220 | void SendViewerTime(int phase); |
1221 | UUID GetDefaultAnimation(string name); | ||
1222 | 1221 | ||
1223 | void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, string flAbout, | 1222 | void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, Byte[] charterMember, string flAbout, |
1224 | uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID); | 1223 | uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID); |
diff --git a/OpenSim/Framework/ICommandConsole.cs b/OpenSim/Framework/ICommandConsole.cs index d33b9b5..ca0ff93 100644 --- a/OpenSim/Framework/ICommandConsole.cs +++ b/OpenSim/Framework/ICommandConsole.cs | |||
@@ -40,7 +40,7 @@ namespace OpenSim.Framework | |||
40 | /// <summary> | 40 | /// <summary> |
41 | /// Get help for the given help string | 41 | /// Get help for the given help string |
42 | /// </summary> | 42 | /// </summary> |
43 | /// <param name="helpParts">Parsed parts of the help string. If empty then general help is returned.</param> | 43 | /// <param name="cmd">Parsed parts of the help string. If empty then general help is returned.</param> |
44 | /// <returns></returns> | 44 | /// <returns></returns> |
45 | List<string> GetHelp(string[] cmd); | 45 | List<string> GetHelp(string[] cmd); |
46 | 46 | ||
diff --git a/OpenSim/Framework/ILandObject.cs b/OpenSim/Framework/ILandObject.cs index dd73b3f..4f98d7b 100644 --- a/OpenSim/Framework/ILandObject.cs +++ b/OpenSim/Framework/ILandObject.cs | |||
@@ -71,6 +71,7 @@ namespace OpenSim.Framework | |||
71 | bool IsEitherBannedOrRestricted(UUID avatar); | 71 | bool IsEitherBannedOrRestricted(UUID avatar); |
72 | bool IsBannedFromLand(UUID avatar); | 72 | bool IsBannedFromLand(UUID avatar); |
73 | bool IsRestrictedFromLand(UUID avatar); | 73 | bool IsRestrictedFromLand(UUID avatar); |
74 | bool IsInLandAccessList(UUID avatar); | ||
74 | void SendLandUpdateToClient(IClientAPI remote_client); | 75 | void SendLandUpdateToClient(IClientAPI remote_client); |
75 | void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client); | 76 | void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client); |
76 | List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag); | 77 | List<LandAccessEntry> CreateAccessListArrayByFlag(AccessList flag); |
diff --git a/OpenSim/Framework/MultipartForm.cs b/OpenSim/Framework/MultipartForm.cs index 90c4007..7a13e8b 100644 --- a/OpenSim/Framework/MultipartForm.cs +++ b/OpenSim/Framework/MultipartForm.cs | |||
@@ -119,7 +119,7 @@ namespace OpenSim.Framework | |||
119 | // Copy the temporary stream to the network stream | 119 | // Copy the temporary stream to the network stream |
120 | formDataStream.Seek(0, SeekOrigin.Begin); | 120 | formDataStream.Seek(0, SeekOrigin.Begin); |
121 | using (Stream requestStream = request.GetRequestStream()) | 121 | using (Stream requestStream = request.GetRequestStream()) |
122 | formDataStream.CopyTo(requestStream, (int)formDataStream.Length); | 122 | formDataStream.CopyStream(requestStream, (int)formDataStream.Length); |
123 | } | 123 | } |
124 | 124 | ||
125 | #endregion Stream Writing | 125 | #endregion Stream Writing |
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 5ba3863..a505524 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs | |||
@@ -421,12 +421,18 @@ namespace OpenSim.Framework | |||
421 | set { m_internalEndPoint = value; } | 421 | set { m_internalEndPoint = value; } |
422 | } | 422 | } |
423 | 423 | ||
424 | /// <summary> | ||
425 | /// The x co-ordinate of this region in map tiles (e.g. 1000). | ||
426 | /// </summary> | ||
424 | public uint RegionLocX | 427 | public uint RegionLocX |
425 | { | 428 | { |
426 | get { return m_regionLocX.Value; } | 429 | get { return m_regionLocX.Value; } |
427 | set { m_regionLocX = value; } | 430 | set { m_regionLocX = value; } |
428 | } | 431 | } |
429 | 432 | ||
433 | /// <summary> | ||
434 | /// The y co-ordinate of this region in map tiles (e.g. 1000). | ||
435 | /// </summary> | ||
430 | public uint RegionLocY | 436 | public uint RegionLocY |
431 | { | 437 | { |
432 | get { return m_regionLocY.Value; } | 438 | get { return m_regionLocY.Value; } |
diff --git a/OpenSim/Framework/SLUtil.cs b/OpenSim/Framework/SLUtil.cs index b337e03..db4541e 100644 --- a/OpenSim/Framework/SLUtil.cs +++ b/OpenSim/Framework/SLUtil.cs | |||
@@ -27,7 +27,9 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | ||
30 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Xml; | ||
31 | using log4net; | 33 | using log4net; |
32 | using OpenMetaverse; | 34 | using OpenMetaverse; |
33 | 35 | ||
@@ -375,4 +377,4 @@ namespace OpenSim.Framework | |||
375 | return output; | 377 | return output; |
376 | } | 378 | } |
377 | } | 379 | } |
378 | } | 380 | } \ No newline at end of file |
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 6a3135e..06a8021 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs | |||
@@ -161,43 +161,43 @@ namespace OpenSim.Framework.Servers | |||
161 | Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); | 161 | Notice(String.Format("Console log level is {0}", m_consoleAppender.Threshold)); |
162 | } | 162 | } |
163 | 163 | ||
164 | m_console.Commands.AddCommand("base", false, "quit", | 164 | m_console.Commands.AddCommand("General", false, "quit", |
165 | "quit", | 165 | "quit", |
166 | "Quit the application", HandleQuit); | 166 | "Quit the application", HandleQuit); |
167 | 167 | ||
168 | m_console.Commands.AddCommand("base", false, "shutdown", | 168 | m_console.Commands.AddCommand("General", false, "shutdown", |
169 | "shutdown", | 169 | "shutdown", |
170 | "Quit the application", HandleQuit); | 170 | "Quit the application", HandleQuit); |
171 | 171 | ||
172 | m_console.Commands.AddCommand("base", false, "set log level", | 172 | m_console.Commands.AddCommand("General", false, "set log level", |
173 | "set log level <level>", | 173 | "set log level <level>", |
174 | "Set the console logging level", HandleLogLevel); | 174 | "Set the console logging level", HandleLogLevel); |
175 | 175 | ||
176 | m_console.Commands.AddCommand("base", false, "show info", | 176 | m_console.Commands.AddCommand("General", false, "show info", |
177 | "show info", | 177 | "show info", |
178 | "Show general information about the server", HandleShow); | 178 | "Show general information about the server", HandleShow); |
179 | 179 | ||
180 | m_console.Commands.AddCommand("base", false, "show stats", | 180 | m_console.Commands.AddCommand("General", false, "show stats", |
181 | "show stats", | 181 | "show stats", |
182 | "Show statistics", HandleShow); | 182 | "Show statistics", HandleShow); |
183 | 183 | ||
184 | m_console.Commands.AddCommand("base", false, "show threads", | 184 | m_console.Commands.AddCommand("General", false, "show threads", |
185 | "show threads", | 185 | "show threads", |
186 | "Show thread status", HandleShow); | 186 | "Show thread status", HandleShow); |
187 | 187 | ||
188 | m_console.Commands.AddCommand("base", false, "show uptime", | 188 | m_console.Commands.AddCommand("General", false, "show uptime", |
189 | "show uptime", | 189 | "show uptime", |
190 | "Show server uptime", HandleShow); | 190 | "Show server uptime", HandleShow); |
191 | 191 | ||
192 | m_console.Commands.AddCommand("base", false, "show version", | 192 | m_console.Commands.AddCommand("General", false, "show version", |
193 | "show version", | 193 | "show version", |
194 | "Show server version", HandleShow); | 194 | "Show server version", HandleShow); |
195 | 195 | ||
196 | m_console.Commands.AddCommand("base", false, "threads abort", | 196 | m_console.Commands.AddCommand("General", false, "threads abort", |
197 | "threads abort <thread-id>", | 197 | "threads abort <thread-id>", |
198 | "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort); | 198 | "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort); |
199 | 199 | ||
200 | m_console.Commands.AddCommand("base", false, "threads show", | 200 | m_console.Commands.AddCommand("General", false, "threads show", |
201 | "threads show", | 201 | "threads show", |
202 | "Show thread status. Synonym for \"show threads\"", | 202 | "Show thread status. Synonym for \"show threads\"", |
203 | (string module, string[] args) => Notice(GetThreadsReport())); | 203 | (string module, string[] args) => Notice(GetThreadsReport())); |
@@ -269,15 +269,19 @@ namespace OpenSim.Framework.Servers | |||
269 | t.Priority, | 269 | t.Priority, |
270 | t.ThreadState); | 270 | t.ThreadState); |
271 | 271 | ||
272 | sb.Append(Environment.NewLine); | 272 | sb.Append("\n"); |
273 | } | 273 | } |
274 | 274 | ||
275 | int workers = 0, ports = 0, maxWorkers = 0, maxPorts = 0; | 275 | sb.Append("\n"); |
276 | ThreadPool.GetAvailableThreads(out workers, out ports); | ||
277 | ThreadPool.GetMaxThreads(out maxWorkers, out maxPorts); | ||
278 | 276 | ||
279 | sb.Append(Environment.NewLine + "*** ThreadPool threads ***" + Environment.NewLine); | 277 | // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting |
280 | sb.Append("workers: " + (maxWorkers - workers) + " (" + maxWorkers + "); ports: " + (maxPorts - ports) + " (" + maxPorts + ")" + Environment.NewLine); | 278 | // zero active threads. |
279 | int totalThreads = Process.GetCurrentProcess().Threads.Count; | ||
280 | if (totalThreads > 0) | ||
281 | sb.AppendFormat("Total threads active: {0}\n\n", totalThreads); | ||
282 | |||
283 | sb.Append("Main threadpool (excluding script engine pools)\n"); | ||
284 | sb.Append(Util.GetThreadPoolReport()); | ||
281 | 285 | ||
282 | return sb.ToString(); | 286 | return sb.ToString(); |
283 | } | 287 | } |
diff --git a/OpenSim/Framework/Statistics/BaseStatsCollector.cs b/OpenSim/Framework/Statistics/BaseStatsCollector.cs index a1841c5..c9e57ce 100644 --- a/OpenSim/Framework/Statistics/BaseStatsCollector.cs +++ b/OpenSim/Framework/Statistics/BaseStatsCollector.cs | |||
@@ -26,8 +26,8 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Diagnostics; | ||
29 | using System.Text; | 30 | using System.Text; |
30 | |||
31 | using OpenMetaverse; | 31 | using OpenMetaverse; |
32 | using OpenMetaverse.StructuredData; | 32 | using OpenMetaverse.StructuredData; |
33 | 33 | ||
@@ -46,8 +46,12 @@ namespace OpenSim.Framework.Statistics | |||
46 | sb.Append(Environment.NewLine); | 46 | sb.Append(Environment.NewLine); |
47 | sb.Append( | 47 | sb.Append( |
48 | string.Format( | 48 | string.Format( |
49 | "Allocated to OpenSim : {0} MB" + Environment.NewLine, | 49 | "Allocated to OpenSim objects: {0} MB\n", |
50 | Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0))); | 50 | Math.Round(GC.GetTotalMemory(false) / 1024.0 / 1024.0))); |
51 | sb.Append( | ||
52 | string.Format( | ||
53 | "Process memory : {0} MB\n", | ||
54 | Math.Round(Process.GetCurrentProcess().WorkingSet64 / 1024.0 / 1024.0))); | ||
51 | 55 | ||
52 | return sb.ToString(); | 56 | return sb.ToString(); |
53 | } | 57 | } |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index efa4a7b..e03bb74 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -35,7 +35,7 @@ using System.IO; | |||
35 | using System.IO.Compression; | 35 | using System.IO.Compression; |
36 | using System.Net; | 36 | using System.Net; |
37 | using System.Net.Sockets; | 37 | using System.Net.Sockets; |
38 | using System.Reflection; | 38 | using System.Reflection; |
39 | using System.Runtime.InteropServices; | 39 | using System.Runtime.InteropServices; |
40 | using System.Runtime.Serialization; | 40 | using System.Runtime.Serialization; |
41 | using System.Runtime.Serialization.Formatters.Binary; | 41 | using System.Runtime.Serialization.Formatters.Binary; |
@@ -81,12 +81,15 @@ namespace OpenSim.Framework | |||
81 | 81 | ||
82 | private static uint nextXferID = 5000; | 82 | private static uint nextXferID = 5000; |
83 | private static Random randomClass = new Random(); | 83 | private static Random randomClass = new Random(); |
84 | |||
84 | // Get a list of invalid file characters (OS dependent) | 85 | // Get a list of invalid file characters (OS dependent) |
85 | private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]"; | 86 | private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]"; |
86 | private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]"; | 87 | private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]"; |
87 | private static object XferLock = new object(); | 88 | private static object XferLock = new object(); |
88 | /// <summary>Thread pool used for Util.FireAndForget if | 89 | |
89 | /// FireAndForgetMethod.SmartThreadPool is used</summary> | 90 | /// <summary> |
91 | /// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used | ||
92 | /// </summary> | ||
90 | private static SmartThreadPool m_ThreadPool; | 93 | private static SmartThreadPool m_ThreadPool; |
91 | 94 | ||
92 | // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC. | 95 | // Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC. |
@@ -144,7 +147,6 @@ namespace OpenSim.Framework | |||
144 | return lerp(y, lerp(x, a, b), lerp(x, c, d)); | 147 | return lerp(y, lerp(x, a, b), lerp(x, c, d)); |
145 | } | 148 | } |
146 | 149 | ||
147 | |||
148 | public static Encoding UTF8 = Encoding.UTF8; | 150 | public static Encoding UTF8 = Encoding.UTF8; |
149 | 151 | ||
150 | /// <value> | 152 | /// <value> |
@@ -376,20 +378,20 @@ namespace OpenSim.Framework | |||
376 | } | 378 | } |
377 | 379 | ||
378 | return sb.ToString(); | 380 | return sb.ToString(); |
379 | } | 381 | } |
380 | 382 | ||
381 | /// <summary> | 383 | /// <summary> |
382 | /// Is the platform Windows? | 384 | /// Is the platform Windows? |
383 | /// </summary> | 385 | /// </summary> |
384 | /// <returns>true if so, false otherwise</returns> | 386 | /// <returns>true if so, false otherwise</returns> |
385 | public static bool IsWindows() | 387 | public static bool IsWindows() |
386 | { | 388 | { |
387 | PlatformID platformId = Environment.OSVersion.Platform; | 389 | PlatformID platformId = Environment.OSVersion.Platform; |
388 | 390 | ||
389 | return (platformId == PlatformID.Win32NT | 391 | return (platformId == PlatformID.Win32NT |
390 | || platformId == PlatformID.Win32S | 392 | || platformId == PlatformID.Win32S |
391 | || platformId == PlatformID.Win32Windows | 393 | || platformId == PlatformID.Win32Windows |
392 | || platformId == PlatformID.WinCE); | 394 | || platformId == PlatformID.WinCE); |
393 | } | 395 | } |
394 | 396 | ||
395 | public static bool LoadArchSpecificWindowsDll(string libraryName) | 397 | public static bool LoadArchSpecificWindowsDll(string libraryName) |
@@ -1502,27 +1504,27 @@ namespace OpenSim.Framework | |||
1502 | } | 1504 | } |
1503 | 1505 | ||
1504 | return data; | 1506 | return data; |
1505 | } | 1507 | } |
1506 | 1508 | ||
1507 | /// <summary> | 1509 | /// <summary> |
1508 | /// Used to trigger an early library load on Windows systems. | 1510 | /// Used to trigger an early library load on Windows systems. |
1509 | /// </summary> | 1511 | /// </summary> |
1510 | /// <remarks> | 1512 | /// <remarks> |
1511 | /// Required to get 32-bit and 64-bit processes to automatically use the | 1513 | /// Required to get 32-bit and 64-bit processes to automatically use the |
1512 | /// appropriate native library. | 1514 | /// appropriate native library. |
1513 | /// </remarks> | 1515 | /// </remarks> |
1514 | /// <param name="dllToLoad"></param> | 1516 | /// <param name="dllToLoad"></param> |
1515 | /// <returns></returns> | 1517 | /// <returns></returns> |
1516 | [DllImport("kernel32.dll")] | 1518 | [DllImport("kernel32.dll")] |
1517 | public static extern IntPtr LoadLibrary(string dllToLoad); | 1519 | public static extern IntPtr LoadLibrary(string dllToLoad); |
1518 | 1520 | ||
1519 | /// <summary> | 1521 | /// <summary> |
1520 | /// Determine whether the current process is 64 bit | 1522 | /// Determine whether the current process is 64 bit |
1521 | /// </summary> | 1523 | /// </summary> |
1522 | /// <returns>true if so, false if not</returns> | 1524 | /// <returns>true if so, false if not</returns> |
1523 | public static bool Is64BitProcess() | 1525 | public static bool Is64BitProcess() |
1524 | { | 1526 | { |
1525 | return IntPtr.Size == 8; | 1527 | return IntPtr.Size == 8; |
1526 | } | 1528 | } |
1527 | 1529 | ||
1528 | #region FireAndForget Threading Pattern | 1530 | #region FireAndForget Threading Pattern |
@@ -1671,6 +1673,61 @@ namespace OpenSim.Framework | |||
1671 | } | 1673 | } |
1672 | } | 1674 | } |
1673 | 1675 | ||
1676 | /// <summary> | ||
1677 | /// Get a thread pool report. | ||
1678 | /// </summary> | ||
1679 | /// <returns></returns> | ||
1680 | public static string GetThreadPoolReport() | ||
1681 | { | ||
1682 | string threadPoolUsed = null; | ||
1683 | int maxThreads = 0; | ||
1684 | int minThreads = 0; | ||
1685 | int allocatedThreads = 0; | ||
1686 | int inUseThreads = 0; | ||
1687 | int waitingCallbacks = 0; | ||
1688 | int completionPortThreads = 0; | ||
1689 | |||
1690 | StringBuilder sb = new StringBuilder(); | ||
1691 | if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) | ||
1692 | { | ||
1693 | threadPoolUsed = "SmartThreadPool"; | ||
1694 | maxThreads = m_ThreadPool.MaxThreads; | ||
1695 | minThreads = m_ThreadPool.MinThreads; | ||
1696 | inUseThreads = m_ThreadPool.InUseThreads; | ||
1697 | allocatedThreads = m_ThreadPool.ActiveThreads; | ||
1698 | waitingCallbacks = m_ThreadPool.WaitingCallbacks; | ||
1699 | } | ||
1700 | else if ( | ||
1701 | FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem | ||
1702 | || FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem) | ||
1703 | { | ||
1704 | threadPoolUsed = "BuiltInThreadPool"; | ||
1705 | ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads); | ||
1706 | ThreadPool.GetMinThreads(out minThreads, out completionPortThreads); | ||
1707 | int availableThreads; | ||
1708 | ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads); | ||
1709 | inUseThreads = maxThreads - availableThreads; | ||
1710 | allocatedThreads = -1; | ||
1711 | waitingCallbacks = -1; | ||
1712 | } | ||
1713 | |||
1714 | if (threadPoolUsed != null) | ||
1715 | { | ||
1716 | sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed); | ||
1717 | sb.AppendFormat("Max threads : {0}\n", maxThreads); | ||
1718 | sb.AppendFormat("Min threads : {0}\n", minThreads); | ||
1719 | sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString()); | ||
1720 | sb.AppendFormat("In use threads : {0}\n", inUseThreads); | ||
1721 | sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString()); | ||
1722 | } | ||
1723 | else | ||
1724 | { | ||
1725 | sb.AppendFormat("Thread pool not used\n"); | ||
1726 | } | ||
1727 | |||
1728 | return sb.ToString(); | ||
1729 | } | ||
1730 | |||
1674 | private static object SmartThreadPoolCallback(object o) | 1731 | private static object SmartThreadPoolCallback(object o) |
1675 | { | 1732 | { |
1676 | object[] array = (object[])o; | 1733 | object[] array = (object[])o; |
@@ -1701,13 +1758,26 @@ namespace OpenSim.Framework | |||
1701 | /// and negative every 24.9 days. Subtracts the passed value (previously fetched by | 1758 | /// and negative every 24.9 days. Subtracts the passed value (previously fetched by |
1702 | /// 'EnvironmentTickCount()') and accounts for any wrapping. | 1759 | /// 'EnvironmentTickCount()') and accounts for any wrapping. |
1703 | /// </summary> | 1760 | /// </summary> |
1761 | /// <param name="newValue"></param> | ||
1762 | /// <param name="prevValue"></param> | ||
1704 | /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns> | 1763 | /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns> |
1705 | public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) | 1764 | public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue) |
1706 | { | 1765 | { |
1707 | Int32 diff = EnvironmentTickCount() - prevValue; | 1766 | Int32 diff = newValue - prevValue; |
1708 | return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); | 1767 | return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); |
1709 | } | 1768 | } |
1710 | 1769 | ||
1770 | /// <summary> | ||
1771 | /// Environment.TickCount is an int but it counts all 32 bits so it goes positive | ||
1772 | /// and negative every 24.9 days. Subtracts the passed value (previously fetched by | ||
1773 | /// 'EnvironmentTickCount()') and accounts for any wrapping. | ||
1774 | /// </summary> | ||
1775 | /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns> | ||
1776 | public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) | ||
1777 | { | ||
1778 | return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue); | ||
1779 | } | ||
1780 | |||
1711 | // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount | 1781 | // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount |
1712 | // Assumes both tcA and tcB came from previous calls to Util.EnvironmentTickCount(). | 1782 | // Assumes both tcA and tcB came from previous calls to Util.EnvironmentTickCount(). |
1713 | // A positive return value indicates A occured later than B | 1783 | // A positive return value indicates A occured later than B |
@@ -1870,11 +1940,12 @@ namespace OpenSim.Framework | |||
1870 | #region Universal User Identifiers | 1940 | #region Universal User Identifiers |
1871 | /// <summary> | 1941 | /// <summary> |
1872 | /// </summary> | 1942 | /// </summary> |
1873 | /// <param name="value">uuid[;endpoint[;name]]</param> | 1943 | /// <param name="value">uuid[;endpoint[;first last[;secret]]]</param> |
1874 | /// <param name="uuid"></param> | 1944 | /// <param name="uuid">the uuid part</param> |
1875 | /// <param name="url"></param> | 1945 | /// <param name="url">the endpoint part (e.g. http://foo.com)</param> |
1876 | /// <param name="firstname"></param> | 1946 | /// <param name="firstname">the first name part (e.g. Test)</param> |
1877 | /// <param name="lastname"></param> | 1947 | /// <param name="lastname">the last name part (e.g User)</param> |
1948 | /// <param name="secret">the secret part</param> | ||
1878 | public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret) | 1949 | public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret) |
1879 | { | 1950 | { |
1880 | uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty; | 1951 | uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty; |
@@ -1903,31 +1974,64 @@ namespace OpenSim.Framework | |||
1903 | } | 1974 | } |
1904 | 1975 | ||
1905 | /// <summary> | 1976 | /// <summary> |
1906 | /// | 1977 | /// Produces a universal (HG) system-facing identifier given the information |
1907 | /// </summary> | 1978 | /// </summary> |
1908 | /// <param name="acircuit"></param> | 1979 | /// <param name="acircuit"></param> |
1909 | /// <returns>uuid[;endpoint[;name]]</returns> | 1980 | /// <returns>uuid[;homeURI[;first last]]</returns> |
1910 | public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit) | 1981 | public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit) |
1911 | { | 1982 | { |
1912 | if (acircuit.ServiceURLs.ContainsKey("HomeURI")) | 1983 | if (acircuit.ServiceURLs.ContainsKey("HomeURI")) |
1984 | return UniversalIdentifier(acircuit.AgentID, acircuit.firstname, acircuit.lastname, acircuit.ServiceURLs["HomeURI"].ToString()); | ||
1985 | else | ||
1986 | return acircuit.AgentID.ToString(); | ||
1987 | } | ||
1988 | |||
1989 | /// <summary> | ||
1990 | /// Produces a universal (HG) system-facing identifier given the information | ||
1991 | /// </summary> | ||
1992 | /// <param name="id">UUID of the user</param> | ||
1993 | /// <param name="firstName">first name (e.g Test)</param> | ||
1994 | /// <param name="lastName">last name (e.g. User)</param> | ||
1995 | /// <param name="homeURI">homeURI (e.g. http://foo.com)</param> | ||
1996 | /// <returns>a string of the form uuid[;homeURI[;first last]]</returns> | ||
1997 | public static string UniversalIdentifier(UUID id, String firstName, String lastName, String homeURI) | ||
1998 | { | ||
1999 | string agentsURI = homeURI; | ||
2000 | if (!agentsURI.EndsWith("/")) | ||
2001 | agentsURI += "/"; | ||
2002 | |||
2003 | // This is ugly, but there's no other way, given that the name is changed | ||
2004 | // in the agent circuit data for foreigners | ||
2005 | if (lastName.Contains("@")) | ||
1913 | { | 2006 | { |
1914 | string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString(); | 2007 | string[] parts = firstName.Split(new char[] { '.' }); |
1915 | if (!agentsURI.EndsWith("/")) | 2008 | if (parts.Length == 2) |
1916 | agentsURI += "/"; | 2009 | return id.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1]; |
2010 | } | ||
2011 | return id.ToString() + ";" + agentsURI + ";" + firstName + " " + lastName; | ||
1917 | 2012 | ||
1918 | // This is ugly, but there's no other way, given that the name is changed | 2013 | } |
1919 | // in the agent circuit data for foreigners | 2014 | |
1920 | if (acircuit.lastname.Contains("@")) | 2015 | /// <summary> |
1921 | { | 2016 | /// Produces a universal (HG) user-facing name given the information |
1922 | string[] parts = acircuit.firstname.Split(new char[] { '.' }); | 2017 | /// </summary> |
1923 | if (parts.Length == 2) | 2018 | /// <param name="firstName"></param> |
1924 | return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1]; | 2019 | /// <param name="lastName"></param> |
1925 | } | 2020 | /// <param name="homeURI"></param> |
1926 | return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname; | 2021 | /// <returns>string of the form first.last @foo.com or first last</returns> |
2022 | public static string UniversalName(String firstName, String lastName, String homeURI) | ||
2023 | { | ||
2024 | Uri uri = null; | ||
2025 | try | ||
2026 | { | ||
2027 | uri = new Uri(homeURI); | ||
1927 | } | 2028 | } |
1928 | else | 2029 | catch (UriFormatException) |
1929 | return acircuit.AgentID.ToString(); | 2030 | { |
1930 | } | 2031 | return firstName + " " + lastName; |
2032 | } | ||
2033 | return firstName + "." + lastName + " " + "@" + uri.Authority; | ||
2034 | } | ||
1931 | #endregion | 2035 | #endregion |
1932 | } | 2036 | } |
1933 | } | 2037 | } |
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index af25da9..ead8f46 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs | |||
@@ -63,6 +63,31 @@ namespace OpenSim.Framework | |||
63 | // a "long" call for warning & debugging purposes | 63 | // a "long" call for warning & debugging purposes |
64 | public const int LongCallTime = 500; | 64 | public const int LongCallTime = 500; |
65 | 65 | ||
66 | // dictionary of end points | ||
67 | private static Dictionary<string,object> m_endpointSerializer = new Dictionary<string,object>(); | ||
68 | |||
69 | |||
70 | private static object EndPointLock(string url) | ||
71 | { | ||
72 | System.Uri uri = new System.Uri(url); | ||
73 | string endpoint = string.Format("{0}:{1}",uri.Host,uri.Port); | ||
74 | |||
75 | lock (m_endpointSerializer) | ||
76 | { | ||
77 | object eplock = null; | ||
78 | |||
79 | if (! m_endpointSerializer.TryGetValue(endpoint,out eplock)) | ||
80 | { | ||
81 | eplock = new object(); | ||
82 | m_endpointSerializer.Add(endpoint,eplock); | ||
83 | // m_log.WarnFormat("[WEB UTIL] add a new host to end point serializer {0}",endpoint); | ||
84 | } | ||
85 | |||
86 | return eplock; | ||
87 | } | ||
88 | } | ||
89 | |||
90 | |||
66 | #region JSONRequest | 91 | #region JSONRequest |
67 | 92 | ||
68 | /// <summary> | 93 | /// <summary> |
@@ -96,6 +121,14 @@ namespace OpenSim.Framework | |||
96 | 121 | ||
97 | public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed) | 122 | public static OSDMap ServiceOSDRequest(string url, OSDMap data, string method, int timeout, bool compressed) |
98 | { | 123 | { |
124 | lock (EndPointLock(url)) | ||
125 | { | ||
126 | return ServiceOSDRequestWorker(url,data,method,timeout,compressed); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | private static OSDMap ServiceOSDRequestWorker(string url, OSDMap data, string method, int timeout, bool compressed) | ||
131 | { | ||
99 | int reqnum = m_requestNumber++; | 132 | int reqnum = m_requestNumber++; |
100 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); | 133 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start osd request for {1}, method {2}",reqnum,url,method); |
101 | 134 | ||
@@ -248,6 +281,14 @@ namespace OpenSim.Framework | |||
248 | 281 | ||
249 | public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout) | 282 | public static OSDMap ServiceFormRequest(string url, NameValueCollection data, int timeout) |
250 | { | 283 | { |
284 | lock (EndPointLock(url)) | ||
285 | { | ||
286 | return ServiceFormRequestWorker(url,data,timeout); | ||
287 | } | ||
288 | } | ||
289 | |||
290 | private static OSDMap ServiceFormRequestWorker(string url, NameValueCollection data, int timeout) | ||
291 | { | ||
251 | int reqnum = m_requestNumber++; | 292 | int reqnum = m_requestNumber++; |
252 | string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; | 293 | string method = (data != null && data["RequestMethod"] != null) ? data["RequestMethod"] : "unknown"; |
253 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method); | 294 | // m_log.DebugFormat("[WEB UTIL]: <{0}> start form request for {1}, method {2}",reqnum,url,method); |
@@ -469,8 +510,13 @@ namespace OpenSim.Framework | |||
469 | /// <remarks> | 510 | /// <remarks> |
470 | /// Copying begins at the streams' current positions. The positions are | 511 | /// Copying begins at the streams' current positions. The positions are |
471 | /// NOT reset after copying is complete. | 512 | /// NOT reset after copying is complete. |
513 | /// NOTE!! .NET 4.0 adds the method 'Stream.CopyTo(stream, bufferSize)'. | ||
514 | /// This function could be replaced with that method once we move | ||
515 | /// totally to .NET 4.0. For versions before, this routine exists. | ||
516 | /// This routine used to be named 'CopyTo' but the int parameter has | ||
517 | /// a different meaning so this method was renamed to avoid any confusion. | ||
472 | /// </remarks> | 518 | /// </remarks> |
473 | public static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) | 519 | public static int CopyStream(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) |
474 | { | 520 | { |
475 | byte[] buffer = new byte[4096]; | 521 | byte[] buffer = new byte[4096]; |
476 | int readBytes; | 522 | int readBytes; |