mirror of
https://github.com/opensim/opensim.git
synced 2026-08-10 03:06:05 +08:00
Make "show threads" and "thread abort" console commands available on all servers
This commit is contained in:
@@ -27,16 +27,19 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using log4net.Appender;
|
||||
using log4net.Core;
|
||||
using log4net.Repository;
|
||||
using Nini.Config;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Framework.Monitoring;
|
||||
|
||||
namespace OpenSim.Framework.Servers
|
||||
{
|
||||
@@ -210,6 +213,22 @@ namespace OpenSim.Framework.Servers
|
||||
"command-script <script>",
|
||||
"Run a command script from file", HandleScript);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"General", false, "show threads",
|
||||
"show threads",
|
||||
"Show thread status", HandleShow);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"General", false, "threads abort",
|
||||
"threads abort <thread-id>",
|
||||
"Abort a managed thread. Use \"show threads\" to find possible threads.", HandleThreadsAbort);
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"General", false, "threads show",
|
||||
"threads show",
|
||||
"Show thread status. Synonym for \"show threads\"",
|
||||
(string module, string[] args) => Notice(GetThreadsReport()));
|
||||
|
||||
m_console.Commands.AddCommand(
|
||||
"General", false, "force gc",
|
||||
"force gc",
|
||||
@@ -244,6 +263,10 @@ namespace OpenSim.Framework.Servers
|
||||
case "uptime":
|
||||
Notice(GetUptimeReport());
|
||||
break;
|
||||
|
||||
case "threads":
|
||||
Notice(GetThreadsReport());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,6 +578,75 @@ namespace OpenSim.Framework.Servers
|
||||
return String.Format("Version: {0} (interface version {1})", m_version, VersionInfo.MajorInterfaceVersion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a report about the registered threads in this server.
|
||||
/// </summary>
|
||||
protected string GetThreadsReport()
|
||||
{
|
||||
// This should be a constant field.
|
||||
string reportFormat = "{0,6} {1,35} {2,16} {3,13} {4,10} {5,30}";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Watchdog.ThreadWatchdogInfo[] threads = Watchdog.GetThreadsInfo();
|
||||
|
||||
sb.Append(threads.Length + " threads are being tracked:" + Environment.NewLine);
|
||||
|
||||
int timeNow = Environment.TickCount & Int32.MaxValue;
|
||||
|
||||
sb.AppendFormat(reportFormat, "ID", "NAME", "LAST UPDATE (MS)", "LIFETIME (MS)", "PRIORITY", "STATE");
|
||||
sb.Append(Environment.NewLine);
|
||||
|
||||
foreach (Watchdog.ThreadWatchdogInfo twi in threads)
|
||||
{
|
||||
Thread t = twi.Thread;
|
||||
|
||||
sb.AppendFormat(
|
||||
reportFormat,
|
||||
t.ManagedThreadId,
|
||||
t.Name,
|
||||
timeNow - twi.LastTick,
|
||||
timeNow - twi.FirstTick,
|
||||
t.Priority,
|
||||
t.ThreadState);
|
||||
|
||||
sb.Append("\n");
|
||||
}
|
||||
|
||||
sb.Append("\n");
|
||||
|
||||
// For some reason mono 2.6.7 returns an empty threads set! Not going to confuse people by reporting
|
||||
// zero active threads.
|
||||
int totalThreads = Process.GetCurrentProcess().Threads.Count;
|
||||
if (totalThreads > 0)
|
||||
sb.AppendFormat("Total threads active: {0}\n\n", totalThreads);
|
||||
|
||||
sb.Append("Main threadpool (excluding script engine pools)\n");
|
||||
sb.Append(Util.GetThreadPoolReport());
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public virtual void HandleThreadsAbort(string module, string[] cmd)
|
||||
{
|
||||
if (cmd.Length != 3)
|
||||
{
|
||||
MainConsole.Instance.Output("Usage: threads abort <thread-id>");
|
||||
return;
|
||||
}
|
||||
|
||||
int threadId;
|
||||
if (!int.TryParse(cmd[2], out threadId))
|
||||
{
|
||||
MainConsole.Instance.Output("ERROR: Thread id must be an integer");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Watchdog.AbortThread(threadId))
|
||||
MainConsole.Instance.OutputFormat("Aborted thread with id {0}", threadId);
|
||||
else
|
||||
MainConsole.Instance.OutputFormat("ERROR - Thread with id {0} not found in managed threads", threadId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Console output is only possible if a console has been established.
|
||||
/// That is something that cannot be determined within this class. So
|
||||
|
||||
Reference in New Issue
Block a user