diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Console/CommandConsole.cs | 114 | ||||
-rw-r--r-- | OpenSim/Framework/Console/MockConsole.cs | 59 | ||||
-rw-r--r-- | OpenSim/Framework/ICommandConsole.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/Servers/BaseOpenSimServer.cs | 22 | ||||
-rw-r--r-- | OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/Servers/VersionInfo.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/Watchdog.cs | 72 | ||||
-rw-r--r-- | OpenSim/Framework/WebUtil.cs | 78 |
8 files changed, 205 insertions, 146 deletions
diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs index 0d6288b..2bb7de1 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,61 @@ 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 | if (m_modulesCommands.ContainsKey(moduleName)) |
171 | { | 192 | { |
172 | result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value)); | 193 | List<CommandInfo> commands = m_modulesCommands[moduleName]; |
194 | var ourHelpText = commands.ConvertAll(c => string.Format("{0} - {1}", c.help_text, c.long_help)); | ||
195 | ourHelpText.Sort(); | ||
196 | helpText.AddRange(ourHelpText); | ||
197 | |||
198 | return true; | ||
173 | } | 199 | } |
174 | else | 200 | else |
175 | { | 201 | { |
176 | if (((CommandInfo)kvp.Value).long_help != String.Empty) | 202 | return false; |
177 | result.Add(((CommandInfo)kvp.Value).help_text+" - "+ | ||
178 | ((CommandInfo)kvp.Value).long_help); | ||
179 | } | 203 | } |
180 | } | 204 | } |
181 | return result; | ||
182 | } | 205 | } |
206 | |||
207 | private List<string> CollectModulesHelp(Dictionary<string, object> dict) | ||
208 | { | ||
209 | lock (m_modulesCommands) | ||
210 | { | ||
211 | List<string> helpText = new List<string>(m_modulesCommands.Keys); | ||
212 | helpText.Sort(); | ||
213 | return helpText; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | // private List<string> CollectHelp(Dictionary<string, object> dict) | ||
218 | // { | ||
219 | // List<string> result = new List<string>(); | ||
220 | // | ||
221 | // foreach (KeyValuePair<string, object> kvp in dict) | ||
222 | // { | ||
223 | // if (kvp.Value is Dictionary<string, Object>) | ||
224 | // { | ||
225 | // result.AddRange(CollectHelp((Dictionary<string, Object>)kvp.Value)); | ||
226 | // } | ||
227 | // else | ||
228 | // { | ||
229 | // if (((CommandInfo)kvp.Value).long_help != String.Empty) | ||
230 | // result.Add(((CommandInfo)kvp.Value).help_text+" - "+ | ||
231 | // ((CommandInfo)kvp.Value).long_help); | ||
232 | // } | ||
233 | // } | ||
234 | // return result; | ||
235 | // } | ||
183 | 236 | ||
184 | /// <summary> | 237 | /// <summary> |
185 | /// Add a command to those which can be invoked from the console. | 238 | /// Add a command to those which can be invoked from the console. |
@@ -212,21 +265,19 @@ namespace OpenSim.Framework.Console | |||
212 | 265 | ||
213 | Dictionary<string, Object> current = tree; | 266 | Dictionary<string, Object> current = tree; |
214 | 267 | ||
215 | foreach (string s in parts) | 268 | foreach (string part in parts) |
216 | { | 269 | { |
217 | if (current.ContainsKey(s)) | 270 | if (current.ContainsKey(part)) |
218 | { | 271 | { |
219 | if (current[s] is Dictionary<string, Object>) | 272 | if (current[part] is Dictionary<string, Object>) |
220 | { | 273 | current = (Dictionary<string, Object>)current[part]; |
221 | current = (Dictionary<string, Object>)current[s]; | ||
222 | } | ||
223 | else | 274 | else |
224 | return; | 275 | return; |
225 | } | 276 | } |
226 | else | 277 | else |
227 | { | 278 | { |
228 | current[s] = new Dictionary<string, Object>(); | 279 | current[part] = new Dictionary<string, Object>(); |
229 | current = (Dictionary<string, Object>)current[s]; | 280 | current = (Dictionary<string, Object>)current[part]; |
230 | } | 281 | } |
231 | } | 282 | } |
232 | 283 | ||
@@ -250,6 +301,24 @@ namespace OpenSim.Framework.Console | |||
250 | info.fn = new List<CommandDelegate>(); | 301 | info.fn = new List<CommandDelegate>(); |
251 | info.fn.Add(fn); | 302 | info.fn.Add(fn); |
252 | current[String.Empty] = info; | 303 | current[String.Empty] = info; |
304 | |||
305 | // Now add command to modules dictionary | ||
306 | lock (m_modulesCommands) | ||
307 | { | ||
308 | List<CommandInfo> commands; | ||
309 | if (m_modulesCommands.ContainsKey(module)) | ||
310 | { | ||
311 | commands = m_modulesCommands[module]; | ||
312 | } | ||
313 | else | ||
314 | { | ||
315 | commands = new List<CommandInfo>(); | ||
316 | m_modulesCommands[module] = commands; | ||
317 | } | ||
318 | |||
319 | // m_log.DebugFormat("[COMMAND CONSOLE]: Adding to category {0} command {1}", module, command); | ||
320 | commands.Add(info); | ||
321 | } | ||
253 | } | 322 | } |
254 | 323 | ||
255 | public string[] FindNextOption(string[] cmd, bool term) | 324 | public string[] FindNextOption(string[] cmd, bool term) |
@@ -607,8 +676,9 @@ namespace OpenSim.Framework.Console | |||
607 | { | 676 | { |
608 | Commands = new Commands(); | 677 | Commands = new Commands(); |
609 | 678 | ||
610 | Commands.AddCommand("console", false, "help", "help [<command>]", | 679 | Commands.AddCommand( |
611 | "Get general command list or more detailed help on a specific command", Help); | 680 | "Help", false, "help", "help [<item>]", |
681 | "Display help on a particular command or on a list of commands in a category", Help); | ||
612 | } | 682 | } |
613 | 683 | ||
614 | private void Help(string module, string[] cmd) | 684 | private void Help(string module, string[] cmd) |
diff --git a/OpenSim/Framework/Console/MockConsole.cs b/OpenSim/Framework/Console/MockConsole.cs index a29b370..4d8751f 100644 --- a/OpenSim/Framework/Console/MockConsole.cs +++ b/OpenSim/Framework/Console/MockConsole.cs | |||
@@ -29,6 +29,7 @@ using System; | |||
29 | using System.Threading; | 29 | using System.Threading; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Text; | 31 | using System.Text; |
32 | using System.Xml; | ||
32 | 33 | ||
33 | namespace OpenSim.Framework.Console | 34 | namespace OpenSim.Framework.Console |
34 | { | 35 | { |
@@ -37,28 +38,42 @@ namespace OpenSim.Framework.Console | |||
37 | /// Don't use this except for Unit Testing or you're in for a world of hurt when the | 38 | /// Don't use this except for Unit Testing or you're in for a world of hurt when the |
38 | /// sim gets to ReadLine | 39 | /// sim gets to ReadLine |
39 | /// </summary> | 40 | /// </summary> |
40 | public class MockConsole : CommandConsole | 41 | public class MockConsole : ICommandConsole |
41 | { | 42 | { |
42 | public MockConsole(string defaultPrompt) : base(defaultPrompt) | 43 | private MockCommands m_commands = new MockCommands(); |
43 | { | ||
44 | } | ||
45 | public override void Output(string text) | ||
46 | { | ||
47 | } | ||
48 | public override void Output(string text, string level) | ||
49 | { | ||
50 | } | ||
51 | 44 | ||
52 | public override string ReadLine(string p, bool isCommand, bool e) | 45 | public ICommands Commands { get { return m_commands; } } |
53 | { | 46 | |
54 | //Thread.CurrentThread.Join(1000); | 47 | public void Prompt() {} |
55 | return string.Empty; | 48 | |
56 | } | 49 | public void RunCommand(string cmd) {} |
57 | public override void UnlockOutput() | 50 | |
58 | { | 51 | public string ReadLine(string p, bool isCommand, bool e) { return ""; } |
59 | } | 52 | |
60 | public override void LockOutput() | 53 | public object ConsoleScene { get { return null; } } |
61 | { | 54 | |
62 | } | 55 | public void Output(string text, string level) {} |
56 | public void Output(string text) {} | ||
57 | public void OutputFormat(string format, params object[] components) {} | ||
58 | |||
59 | public string CmdPrompt(string p) { return ""; } | ||
60 | public string CmdPrompt(string p, string def) { return ""; } | ||
61 | public string CmdPrompt(string p, List<char> excludedCharacters) { return ""; } | ||
62 | public string CmdPrompt(string p, string def, List<char> excludedCharacters) { return ""; } | ||
63 | |||
64 | public string CmdPrompt(string prompt, string defaultresponse, List<string> options) { return ""; } | ||
65 | |||
66 | public string PasswdPrompt(string p) { return ""; } | ||
67 | } | ||
68 | |||
69 | public class MockCommands : ICommands | ||
70 | { | ||
71 | public void FromXml(XmlElement root, CommandDelegate fn) {} | ||
72 | public List<string> GetHelp(string[] cmd) { return null; } | ||
73 | public void AddCommand(string module, bool shared, string command, string help, string longhelp, CommandDelegate fn) {} | ||
74 | public void AddCommand(string module, bool shared, string command, string help, string longhelp, string descriptivehelp, CommandDelegate fn) {} | ||
75 | public string[] FindNextOption(string[] cmd, bool term) { return null; } | ||
76 | public string[] Resolve(string[] cmd) { return null; } | ||
77 | public XmlElement GetXml(XmlDocument doc) { return null; } | ||
63 | } | 78 | } |
64 | } | 79 | } \ No newline at end of file |
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/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 586cde6..f4d541e 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())); |
@@ -247,7 +247,7 @@ namespace OpenSim.Framework.Servers | |||
247 | string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}"; | 247 | string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}"; |
248 | 248 | ||
249 | StringBuilder sb = new StringBuilder(); | 249 | StringBuilder sb = new StringBuilder(); |
250 | Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreads(); | 250 | Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreadsInfo(); |
251 | 251 | ||
252 | sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine); | 252 | sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine); |
253 | 253 | ||
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 2206feb..0062d4e 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs | |||
@@ -65,6 +65,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
65 | String.Format("PollServiceWorkerThread{0}", i), | 65 | String.Format("PollServiceWorkerThread{0}", i), |
66 | ThreadPriority.Normal, | 66 | ThreadPriority.Normal, |
67 | false, | 67 | false, |
68 | true, | ||
68 | int.MaxValue); | 69 | int.MaxValue); |
69 | } | 70 | } |
70 | 71 | ||
@@ -73,6 +74,7 @@ namespace OpenSim.Framework.Servers.HttpServer | |||
73 | "PollServiceWatcherThread", | 74 | "PollServiceWatcherThread", |
74 | ThreadPriority.Normal, | 75 | ThreadPriority.Normal, |
75 | false, | 76 | false, |
77 | true, | ||
76 | 1000 * 60 * 10); | 78 | 1000 * 60 * 10); |
77 | } | 79 | } |
78 | 80 | ||
diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index b2bb962..63ec257 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs | |||
@@ -29,7 +29,7 @@ namespace OpenSim | |||
29 | { | 29 | { |
30 | public class VersionInfo | 30 | public class VersionInfo |
31 | { | 31 | { |
32 | private const string VERSION_NUMBER = "0.7.3CM"; | 32 | private const string VERSION_NUMBER = "0.7.4CM"; |
33 | private const Flavour VERSION_FLAVOUR = Flavour.Dev; | 33 | private const Flavour VERSION_FLAVOUR = Flavour.Dev; |
34 | 34 | ||
35 | public enum Flavour | 35 | public enum Flavour |
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs index fa94109..881b6aa 100644 --- a/OpenSim/Framework/Watchdog.cs +++ b/OpenSim/Framework/Watchdog.cs | |||
@@ -72,6 +72,11 @@ namespace OpenSim.Framework | |||
72 | /// </summary> | 72 | /// </summary> |
73 | public bool IsTimedOut { get; set; } | 73 | public bool IsTimedOut { get; set; } |
74 | 74 | ||
75 | /// <summary> | ||
76 | /// Will this thread trigger the alarm function if it has timed out? | ||
77 | /// </summary> | ||
78 | public bool AlarmIfTimeout { get; set; } | ||
79 | |||
75 | public ThreadWatchdogInfo(Thread thread, int timeout) | 80 | public ThreadWatchdogInfo(Thread thread, int timeout) |
76 | { | 81 | { |
77 | Thread = thread; | 82 | Thread = thread; |
@@ -112,12 +117,13 @@ namespace OpenSim.Framework | |||
112 | /// <param name="start">The method that will be executed in a new thread</param> | 117 | /// <param name="start">The method that will be executed in a new thread</param> |
113 | /// <param name="name">A name to give to the new thread</param> | 118 | /// <param name="name">A name to give to the new thread</param> |
114 | /// <param name="priority">Priority to run the thread at</param> | 119 | /// <param name="priority">Priority to run the thread at</param> |
115 | /// <param name="isBackground">True to run this thread as a background | 120 | /// <param name="isBackground">True to run this thread as a background thread, otherwise false</param> |
116 | /// thread, otherwise false</param> | 121 | /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> |
117 | /// <returns>The newly created Thread object</returns> | 122 | /// <returns>The newly created Thread object</returns> |
118 | public static Thread StartThread(ThreadStart start, string name, ThreadPriority priority, bool isBackground) | 123 | public static Thread StartThread( |
124 | ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout) | ||
119 | { | 125 | { |
120 | return StartThread(start, name, priority, isBackground, WATCHDOG_TIMEOUT_MS); | 126 | return StartThread(start, name, priority, isBackground, alarmIfTimeout, WATCHDOG_TIMEOUT_MS); |
121 | } | 127 | } |
122 | 128 | ||
123 | /// <summary> | 129 | /// <summary> |
@@ -128,21 +134,21 @@ namespace OpenSim.Framework | |||
128 | /// <param name="priority">Priority to run the thread at</param> | 134 | /// <param name="priority">Priority to run the thread at</param> |
129 | /// <param name="isBackground">True to run this thread as a background | 135 | /// <param name="isBackground">True to run this thread as a background |
130 | /// thread, otherwise false</param> | 136 | /// thread, otherwise false</param> |
131 | /// <param name="timeout"> | 137 | /// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param> |
132 | /// Number of milliseconds to wait until we issue a warning about timeout. | 138 | /// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param> |
133 | /// </para> | ||
134 | /// <returns>The newly created Thread object</returns> | 139 | /// <returns>The newly created Thread object</returns> |
135 | public static Thread StartThread( | 140 | public static Thread StartThread( |
136 | ThreadStart start, string name, ThreadPriority priority, bool isBackground, int timeout) | 141 | ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, int timeout) |
137 | { | 142 | { |
138 | Thread thread = new Thread(start); | 143 | Thread thread = new Thread(start); |
139 | thread.Name = name; | 144 | thread.Name = name; |
140 | thread.Priority = priority; | 145 | thread.Priority = priority; |
141 | thread.IsBackground = isBackground; | 146 | thread.IsBackground = isBackground; |
142 | 147 | ||
143 | ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout); | 148 | ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout) { AlarmIfTimeout = alarmIfTimeout }; |
144 | 149 | ||
145 | m_log.Debug("[WATCHDOG]: Started tracking thread \"" + twi.Thread.Name + "\" (ID " + twi.Thread.ManagedThreadId + ")"); | 150 | m_log.DebugFormat( |
151 | "[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId); | ||
146 | 152 | ||
147 | lock (m_threads) | 153 | lock (m_threads) |
148 | m_threads.Add(twi.Thread.ManagedThreadId, twi); | 154 | m_threads.Add(twi.Thread.ManagedThreadId, twi); |
@@ -224,19 +230,39 @@ namespace OpenSim.Framework | |||
224 | /// Get currently watched threads for diagnostic purposes | 230 | /// Get currently watched threads for diagnostic purposes |
225 | /// </summary> | 231 | /// </summary> |
226 | /// <returns></returns> | 232 | /// <returns></returns> |
227 | public static ThreadWatchdogInfo[] GetThreads() | 233 | public static ThreadWatchdogInfo[] GetThreadsInfo() |
228 | { | 234 | { |
229 | lock (m_threads) | 235 | lock (m_threads) |
230 | return m_threads.Values.ToArray(); | 236 | return m_threads.Values.ToArray(); |
231 | } | 237 | } |
232 | 238 | ||
239 | /// <summary> | ||
240 | /// Return the current thread's watchdog info. | ||
241 | /// </summary> | ||
242 | /// <returns>The watchdog info. null if the thread isn't being monitored.</returns> | ||
243 | public static ThreadWatchdogInfo GetCurrentThreadInfo() | ||
244 | { | ||
245 | lock (m_threads) | ||
246 | { | ||
247 | if (m_threads.ContainsKey(Thread.CurrentThread.ManagedThreadId)) | ||
248 | return m_threads[Thread.CurrentThread.ManagedThreadId]; | ||
249 | } | ||
250 | |||
251 | return null; | ||
252 | } | ||
253 | |||
254 | /// <summary> | ||
255 | /// Check watched threads. Fire alarm if appropriate. | ||
256 | /// </summary> | ||
257 | /// <param name="sender"></param> | ||
258 | /// <param name="e"></param> | ||
233 | private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) | 259 | private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) |
234 | { | 260 | { |
235 | WatchdogTimeout callback = OnWatchdogTimeout; | 261 | WatchdogTimeout callback = OnWatchdogTimeout; |
236 | 262 | ||
237 | if (callback != null) | 263 | if (callback != null) |
238 | { | 264 | { |
239 | ThreadWatchdogInfo timedOut = null; | 265 | List<ThreadWatchdogInfo> callbackInfos = null; |
240 | 266 | ||
241 | lock (m_threads) | 267 | lock (m_threads) |
242 | { | 268 | { |
@@ -246,21 +272,31 @@ namespace OpenSim.Framework | |||
246 | { | 272 | { |
247 | if (threadInfo.Thread.ThreadState == ThreadState.Stopped) | 273 | if (threadInfo.Thread.ThreadState == ThreadState.Stopped) |
248 | { | 274 | { |
249 | timedOut = threadInfo; | ||
250 | RemoveThread(threadInfo.Thread.ManagedThreadId); | 275 | RemoveThread(threadInfo.Thread.ManagedThreadId); |
251 | break; | 276 | |
277 | if (callbackInfos == null) | ||
278 | callbackInfos = new List<ThreadWatchdogInfo>(); | ||
279 | |||
280 | callbackInfos.Add(threadInfo); | ||
252 | } | 281 | } |
253 | else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout) | 282 | else if (!threadInfo.IsTimedOut && now - threadInfo.LastTick >= threadInfo.Timeout) |
254 | { | 283 | { |
255 | threadInfo.IsTimedOut = true; | 284 | threadInfo.IsTimedOut = true; |
256 | timedOut = threadInfo; | 285 | |
257 | break; | 286 | if (threadInfo.AlarmIfTimeout) |
287 | { | ||
288 | if (callbackInfos == null) | ||
289 | callbackInfos = new List<ThreadWatchdogInfo>(); | ||
290 | |||
291 | callbackInfos.Add(threadInfo); | ||
292 | } | ||
258 | } | 293 | } |
259 | } | 294 | } |
260 | } | 295 | } |
261 | 296 | ||
262 | if (timedOut != null) | 297 | if (callbackInfos != null) |
263 | callback(timedOut.Thread, timedOut.LastTick); | 298 | foreach (ThreadWatchdogInfo callbackInfo in callbackInfos) |
299 | callback(callbackInfo.Thread, callbackInfo.LastTick); | ||
264 | } | 300 | } |
265 | 301 | ||
266 | m_watchdogTimer.Start(); | 302 | m_watchdogTimer.Start(); |
diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs index 854f310..f90df12 100644 --- a/OpenSim/Framework/WebUtil.cs +++ b/OpenSim/Framework/WebUtil.cs | |||
@@ -63,77 +63,7 @@ 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 | // /// <summary> | 66 | #region JSONRequest |
67 | // /// Send LLSD to an HTTP client in application/llsd+json form | ||
68 | // /// </summary> | ||
69 | // /// <param name="response">HTTP response to send the data in</param> | ||
70 | // /// <param name="body">LLSD to send to the client</param> | ||
71 | // public static void SendJSONResponse(OSHttpResponse response, OSDMap body) | ||
72 | // { | ||
73 | // byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body)); | ||
74 | // | ||
75 | // response.ContentEncoding = Encoding.UTF8; | ||
76 | // response.ContentLength = responseData.Length; | ||
77 | // response.ContentType = "application/llsd+json"; | ||
78 | // response.Body.Write(responseData, 0, responseData.Length); | ||
79 | // } | ||
80 | // | ||
81 | // /// <summary> | ||
82 | // /// Send LLSD to an HTTP client in application/llsd+xml form | ||
83 | // /// </summary> | ||
84 | // /// <param name="response">HTTP response to send the data in</param> | ||
85 | // /// <param name="body">LLSD to send to the client</param> | ||
86 | // public static void SendXMLResponse(OSHttpResponse response, OSDMap body) | ||
87 | // { | ||
88 | // byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body); | ||
89 | // | ||
90 | // response.ContentEncoding = Encoding.UTF8; | ||
91 | // response.ContentLength = responseData.Length; | ||
92 | // response.ContentType = "application/llsd+xml"; | ||
93 | // response.Body.Write(responseData, 0, responseData.Length); | ||
94 | // } | ||
95 | |||
96 | /// <summary> | ||
97 | /// Make a GET or GET-like request to a web service that returns LLSD | ||
98 | /// or JSON data | ||
99 | /// </summary> | ||
100 | public static OSDMap ServiceRequest(string url, string httpVerb) | ||
101 | { | ||
102 | string errorMessage; | ||
103 | |||
104 | try | ||
105 | { | ||
106 | HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); | ||
107 | request.Method = httpVerb; | ||
108 | |||
109 | using (WebResponse response = request.GetResponse()) | ||
110 | { | ||
111 | using (Stream responseStream = response.GetResponseStream()) | ||
112 | { | ||
113 | try | ||
114 | { | ||
115 | string responseStr = responseStream.GetStreamString(); | ||
116 | OSD responseOSD = OSDParser.Deserialize(responseStr); | ||
117 | if (responseOSD.Type == OSDType.Map) | ||
118 | return (OSDMap)responseOSD; | ||
119 | else | ||
120 | errorMessage = "Response format was invalid."; | ||
121 | } | ||
122 | catch | ||
123 | { | ||
124 | errorMessage = "Failed to parse the response."; | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | catch (Exception ex) | ||
130 | { | ||
131 | m_log.Warn(httpVerb + " on URL " + url + " failed: " + ex.Message); | ||
132 | errorMessage = ex.Message; | ||
133 | } | ||
134 | |||
135 | return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } }; | ||
136 | } | ||
137 | 67 | ||
138 | /// <summary> | 68 | /// <summary> |
139 | /// PUT JSON-encoded data to a web service that returns LLSD or | 69 | /// PUT JSON-encoded data to a web service that returns LLSD or |
@@ -304,6 +234,10 @@ namespace OpenSim.Framework | |||
304 | return result; | 234 | return result; |
305 | } | 235 | } |
306 | 236 | ||
237 | #endregion JSONRequest | ||
238 | |||
239 | #region FormRequest | ||
240 | |||
307 | /// <summary> | 241 | /// <summary> |
308 | /// POST URL-encoded form data to a web service that returns LLSD or | 242 | /// POST URL-encoded form data to a web service that returns LLSD or |
309 | /// JSON data | 243 | /// JSON data |
@@ -398,6 +332,8 @@ namespace OpenSim.Framework | |||
398 | result["Message"] = OSD.FromString("Service request failed: " + msg); | 332 | result["Message"] = OSD.FromString("Service request failed: " + msg); |
399 | return result; | 333 | return result; |
400 | } | 334 | } |
335 | |||
336 | #endregion FormRequest | ||
401 | 337 | ||
402 | #region Uri | 338 | #region Uri |
403 | 339 | ||