aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2012-11-23 04:40:49 +0000
committerJustin Clark-Casey (justincc)2012-11-23 04:40:49 +0000
commit999cb4b20cc20a24c7b9fbce4c31b13f8bf36cb5 (patch)
treea73ecf998adad5920e94c570743e6897ae1a87f4
parentMake "force gc" console command available across all servers (diff)
downloadopensim-SC_OLD-999cb4b20cc20a24c7b9fbce4c31b13f8bf36cb5.zip
opensim-SC_OLD-999cb4b20cc20a24c7b9fbce4c31b13f8bf36cb5.tar.gz
opensim-SC_OLD-999cb4b20cc20a24c7b9fbce4c31b13f8bf36cb5.tar.bz2
opensim-SC_OLD-999cb4b20cc20a24c7b9fbce4c31b13f8bf36cb5.tar.xz
Make "show threads" and "thread abort" console commands available on all servers
-rw-r--r--OpenSim/Framework/Servers/BaseOpenSimServer.cs103
-rw-r--r--OpenSim/Framework/Servers/ServerBase.cs92
-rw-r--r--OpenSim/Framework/Util.cs16
3 files changed, 103 insertions, 108 deletions
diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
index 3f66ab5..c0dc907 100644
--- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs
+++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs
@@ -27,7 +27,6 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics;
31using System.IO; 30using System.IO;
32using System.Reflection; 31using System.Reflection;
33using System.Text; 32using System.Text;
@@ -99,19 +98,6 @@ namespace OpenSim.Framework.Servers
99 m_console.Commands.AddCommand("General", false, "shutdown", 98 m_console.Commands.AddCommand("General", false, "shutdown",
100 "shutdown", 99 "shutdown",
101 "Quit the application", HandleQuit); 100 "Quit the application", HandleQuit);
102
103 m_console.Commands.AddCommand("General", false, "show threads",
104 "show threads",
105 "Show thread status", HandleShow);
106
107 m_console.Commands.AddCommand("General", false, "threads abort",
108 "threads abort <thread-id>",
109 "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
110
111 m_console.Commands.AddCommand("General", false, "threads show",
112 "threads show",
113 "Show thread status. Synonym for \"show threads\"",
114 (string module, string[] args) => Notice(GetThreadsReport()));
115 } 101 }
116 102
117 /// <summary> 103 /// <summary>
@@ -144,54 +130,6 @@ namespace OpenSim.Framework.Servers
144 } 130 }
145 131
146 /// <summary> 132 /// <summary>
147 /// Get a report about the registered threads in this server.
148 /// </summary>
149 protected string GetThreadsReport()
150 {
151 // This should be a constant field.
152 string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}";
153
154 StringBuilder sb = new StringBuilder();
155 Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreadsInfo();
156
157 sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine);
158
159 int timeNow = Environment.TickCount & Int32.MaxValue;
160
161 sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "LIFETIME (MS)", "PRIORITY", "STATE");
162 sb.Append(Environment.NewLine);
163
164 foreach (Watchdog.ThreadWatchdogInfo twi in threads)
165 {
166 Thread t = twi.Thread;
167
168 sb.AppendFormat(
169 reportFormat,
170 t.ManagedThreadId,
171 t.Name,
172 timeNow - twi.LastTick,
173 timeNow - twi.FirstTick,
174 t.Priority,
175 t.ThreadState);
176
177 sb.Append("\n");
178 }
179
180 sb.Append("\n");
181
182 // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting
183 // zero active threads.
184 int totalThreads = Process.GetCurrentProcess().Threads.Count;
185 if (totalThreads > 0)
186 sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
187
188 sb.Append("Main threadpool (excluding script engine pools)\n");
189 sb.Append(Util.GetThreadPoolReport());
190
191 return sb.ToString();
192 }
193
194 /// <summary>
195 /// Performs initialisation of the scene, such as loading configuration from disk. 133 /// Performs initialisation of the scene, such as loading configuration from disk.
196 /// </summary> 134 /// </summary>
197 public virtual void Startup() 135 public virtual void Startup()
@@ -231,46 +169,7 @@ namespace OpenSim.Framework.Servers
231 private void HandleQuit(string module, string[] args) 169 private void HandleQuit(string module, string[] args)
232 { 170 {
233 Shutdown(); 171 Shutdown();
234 } 172 }
235
236 public override void HandleShow(string module, string[] cmd)
237 {
238 base.HandleShow(module, cmd);
239
240 List<string> args = new List<string>(cmd);
241
242 args.RemoveAt(0);
243
244 string[] showParams = args.ToArray();
245
246 switch (showParams[0])
247 {
248 case "threads":
249 Notice(GetThreadsReport());
250 break;
251 }
252 }
253
254 public virtual void HandleThreadsAbort(string module, string[] cmd)
255 {
256 if (cmd.Length != 3)
257 {
258 MainConsole.Instance.Output("Usage: threads abort <thread-id>");
259 return;
260 }
261
262 int threadId;
263 if (!int.TryParse(cmd[2], out threadId))
264 {
265 MainConsole.Instance.Output("ERROR: Thread id must be an integer");
266 return;
267 }
268
269 if (Watchdog.AbortThread(threadId))
270 MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId);
271 else
272 MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId);
273 }
274 173
275 public string osSecret { 174 public string osSecret {
276 // Secret uuid for the simulator 175 // Secret uuid for the simulator
diff --git a/OpenSim/Framework/Servers/ServerBase.cs b/OpenSim/Framework/Servers/ServerBase.cs
index b8bc27e..47baac8 100644
--- a/OpenSim/Framework/Servers/ServerBase.cs
+++ b/OpenSim/Framework/Servers/ServerBase.cs
@@ -27,16 +27,19 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics;
30using System.IO; 31using System.IO;
31using System.Reflection; 32using System.Reflection;
32using System.Text; 33using System.Text;
33using System.Text.RegularExpressions; 34using System.Text.RegularExpressions;
35using System.Threading;
34using log4net; 36using log4net;
35using log4net.Appender; 37using log4net.Appender;
36using log4net.Core; 38using log4net.Core;
37using log4net.Repository; 39using log4net.Repository;
38using Nini.Config; 40using Nini.Config;
39using OpenSim.Framework.Console; 41using OpenSim.Framework.Console;
42using OpenSim.Framework.Monitoring;
40 43
41namespace OpenSim.Framework.Servers 44namespace OpenSim.Framework.Servers
42{ 45{
@@ -211,6 +214,22 @@ namespace OpenSim.Framework.Servers
211 "Run a command script from file", HandleScript); 214 "Run a command script from file", HandleScript);
212 215
213 m_console.Commands.AddCommand( 216 m_console.Commands.AddCommand(
217 "General", false, "show threads",
218 "show threads",
219 "Show thread status", HandleShow);
220
221 m_console.Commands.AddCommand(
222 "General", false, "threads abort",
223 "threads abort <thread-id>",
224 "Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
225
226 m_console.Commands.AddCommand(
227 "General", false, "threads show",
228 "threads show",
229 "Show thread status. Synonym for \"show threads\"",
230 (string module, string[] args) => Notice(GetThreadsReport()));
231
232 m_console.Commands.AddCommand(
214 "General", false, "force gc", 233 "General", false, "force gc",
215 "force gc", 234 "force gc",
216 "Manually invoke runtime garbage collection. For debugging purposes", 235 "Manually invoke runtime garbage collection. For debugging purposes",
@@ -244,6 +263,10 @@ namespace OpenSim.Framework.Servers
244 case "uptime": 263 case "uptime":
245 Notice(GetUptimeReport()); 264 Notice(GetUptimeReport());
246 break; 265 break;
266
267 case "threads":
268 Notice(GetThreadsReport());
269 break;
247 } 270 }
248 } 271 }
249 272
@@ -556,6 +579,75 @@ namespace OpenSim.Framework.Servers
556 } 579 }
557 580
558 /// <summary> 581 /// <summary>
582 /// Get a report about the registered threads in this server.
583 /// </summary>
584 protected string GetThreadsReport()
585 {
586 // This should be a constant field.
587 string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}";
588
589 StringBuilder sb = new StringBuilder();
590 Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreadsInfo();
591
592 sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine);
593
594 int timeNow = Environment.TickCount & Int32.MaxValue;
595
596 sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "LIFETIME (MS)", "PRIORITY", "STATE");
597 sb.Append(Environment.NewLine);
598
599 foreach (Watchdog.ThreadWatchdogInfo twi in threads)
600 {
601 Thread t = twi.Thread;
602
603 sb.AppendFormat(
604 reportFormat,
605 t.ManagedThreadId,
606 t.Name,
607 timeNow - twi.LastTick,
608 timeNow - twi.FirstTick,
609 t.Priority,
610 t.ThreadState);
611
612 sb.Append("\n");
613 }
614
615 sb.Append("\n");
616
617 // For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting
618 // zero active threads.
619 int totalThreads = Process.GetCurrentProcess().Threads.Count;
620 if (totalThreads > 0)
621 sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
622
623 sb.Append("Main threadpool (excluding script engine pools)\n");
624 sb.Append(Util.GetThreadPoolReport());
625
626 return sb.ToString();
627 }
628
629 public virtual void HandleThreadsAbort(string module, string[] cmd)
630 {
631 if (cmd.Length != 3)
632 {
633 MainConsole.Instance.Output("Usage: threads abort <thread-id>");
634 return;
635 }
636
637 int threadId;
638 if (!int.TryParse(cmd[2], out threadId))
639 {
640 MainConsole.Instance.Output("ERROR: Thread id must be an integer");
641 return;
642 }
643
644 if (Watchdog.AbortThread(threadId))
645 MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId);
646 else
647 MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId);
648 }
649
650 /// <summary>
559 /// Console output is only possible if a console has been established. 651 /// Console output is only possible if a console has been established.
560 /// That is something that cannot be determined within this class. So 652 /// That is something that cannot be determined within this class. So
561 /// all attempts to use the console MUST be verified. 653 /// all attempts to use the console MUST be verified.
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index c369dbc..a0c54a0 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1741,12 +1741,16 @@ namespace OpenSim.Framework
1741 StringBuilder sb = new StringBuilder(); 1741 StringBuilder sb = new StringBuilder();
1742 if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) 1742 if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
1743 { 1743 {
1744 threadPoolUsed = "SmartThreadPool"; 1744 // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
1745 maxThreads = m_ThreadPool.MaxThreads; 1745 if (m_ThreadPool != null)
1746 minThreads = m_ThreadPool.MinThreads; 1746 {
1747 inUseThreads = m_ThreadPool.InUseThreads; 1747 threadPoolUsed = "SmartThreadPool";
1748 allocatedThreads = m_ThreadPool.ActiveThreads; 1748 maxThreads = m_ThreadPool.MaxThreads;
1749 waitingCallbacks = m_ThreadPool.WaitingCallbacks; 1749 minThreads = m_ThreadPool.MinThreads;
1750 inUseThreads = m_ThreadPool.InUseThreads;
1751 allocatedThreads = m_ThreadPool.ActiveThreads;
1752 waitingCallbacks = m_ThreadPool.WaitingCallbacks;
1753 }
1750 } 1754 }
1751 else if ( 1755 else if (
1752 FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem 1756 FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem