From 7102ac77698f4bfd7406d6e8871db7b006c2cae2 Mon Sep 17 00:00:00 2001 From: Tedd Hansen Date: Thu, 21 Feb 2008 10:43:24 +0000 Subject: "threads" command now works. I've added manual tracking of threads (only if compiled in DEBUG mode)... Its ugly and even requires a separate thread to track the treads, but it will be very valuable in debugging. --- .../Framework/Communications/Cache/AssetCache.cs | 1 + .../Communications/Cache/AssetServerBase.cs | 1 + OpenSim/Framework/Servers/BaseHttpServer.cs | 1 + OpenSim/Framework/ThreadTracker.cs | 106 +++++++++++++++++++++ .../ScriptServer/ScriptServer/RegionCommManager.cs | 1 + OpenSim/Region/Application/OpenSimMain.cs | 25 ++++- OpenSim/Region/ClientStack/ClientView.cs | 1 + OpenSim/Region/Environment/Modules/ChatModule.cs | 12 ++- .../Environment/Modules/ScriptsHttpRequests.cs | 1 + .../Environment/Modules/TextureDownloadModule.cs | 1 + OpenSim/Region/Environment/Modules/XMLRPCModule.cs | 1 + .../ScriptEngineBase/AsyncLSLCommandManager.cs | 1 + .../ScriptEngineBase/EventQueueThreadClass.cs | 1 + .../Common/ScriptEngineBase/MaintenanceThread.cs | 1 + .../Common/ScriptEngineBase/ScriptManager.cs | 1 + OpenSim/Tools/pCampBot/BotManager.cs | 1 + 16 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 OpenSim/Framework/ThreadTracker.cs (limited to 'OpenSim') diff --git a/OpenSim/Framework/Communications/Cache/AssetCache.cs b/OpenSim/Framework/Communications/Cache/AssetCache.cs index 8f8e362..15b52b0 100644 --- a/OpenSim/Framework/Communications/Cache/AssetCache.cs +++ b/OpenSim/Framework/Communications/Cache/AssetCache.cs @@ -171,6 +171,7 @@ namespace OpenSim.Framework.Communications.Cache m_assetCacheThread.Name = "AssetCacheThread"; m_assetCacheThread.IsBackground = true; m_assetCacheThread.Start(); + OpenSim.Framework.ThreadTracker.Add(m_assetCacheThread); } /// diff --git a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs index a3530bd..cae4231 100644 --- a/OpenSim/Framework/Communications/Cache/AssetServerBase.cs +++ b/OpenSim/Framework/Communications/Cache/AssetServerBase.cs @@ -101,6 +101,7 @@ namespace OpenSim.Framework.Communications.Cache m_localAssetServerThread.Name = "LocalAssetServerThread"; m_localAssetServerThread.IsBackground = true; m_localAssetServerThread.Start(); + OpenSim.Framework.ThreadTracker.Add(m_localAssetServerThread); } private void RunRequests() diff --git a/OpenSim/Framework/Servers/BaseHttpServer.cs b/OpenSim/Framework/Servers/BaseHttpServer.cs index 662eefd..dc540f9 100644 --- a/OpenSim/Framework/Servers/BaseHttpServer.cs +++ b/OpenSim/Framework/Servers/BaseHttpServer.cs @@ -550,6 +550,7 @@ namespace OpenSim.Framework.Servers m_workerThread.Name = "HttpThread"; m_workerThread.IsBackground = true; m_workerThread.Start(); + OpenSim.Framework.ThreadTracker.Add(m_workerThread); } private void StartHTTP() diff --git a/OpenSim/Framework/ThreadTracker.cs b/OpenSim/Framework/ThreadTracker.cs new file mode 100644 index 0000000..42e3879 --- /dev/null +++ b/OpenSim/Framework/ThreadTracker.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace OpenSim.Framework +{ + public static class ThreadTracker + { + public static List m_Threads; + public static System.Threading.Thread ThreadTrackerThread; + private static readonly long ThreadTimeout = 30 * 10000000; + + static ThreadTracker() + { +#if DEBUG + m_Threads = new List(); + ThreadTrackerThread = new Thread(ThreadTrackerThreadLoop); + ThreadTrackerThread.Name = "ThreadTrackerThread"; + ThreadTrackerThread.IsBackground = true; + ThreadTrackerThread.Priority = System.Threading.ThreadPriority.BelowNormal; + ThreadTrackerThread.Start(); +#endif + } + + private static void ThreadTrackerThreadLoop() + { + while (true) + { + Thread.Sleep(5000); + CleanUp(); + } + } + + public static void Add(System.Threading.Thread thread) + { +#if DEBUG + lock (m_Threads) + { + ThreadTrackerItem tti = new ThreadTrackerItem(); + tti.Thread = thread; + tti.LastSeenActive = DateTime.Now.Ticks; + m_Threads.Add(tti); + } +#endif + } + + public static void Remove(System.Threading.Thread thread) + { +#if DEBUG + lock (m_Threads) + { + foreach (ThreadTrackerItem tti in new ArrayList(m_Threads)) + { + if (tti.Thread == thread) + m_Threads.Remove(tti); + } + } +#endif + } + + public static void CleanUp() + { + lock (m_Threads) + { + foreach (ThreadTrackerItem tti in new ArrayList(m_Threads)) + { + if (tti.Thread.IsAlive) + { + // Its active + tti.LastSeenActive = DateTime.Now.Ticks; + } + else + { + // Its not active -- if its expired then remove it + if (tti.LastSeenActive + ThreadTimeout < DateTime.Now.Ticks) + m_Threads.Remove(tti); + } + } + } + } + + public static List GetThreads() + { + if (m_Threads == null) + return null; + + List threads = new List(); + lock (m_Threads) + { + foreach (ThreadTrackerItem tti in new ArrayList(m_Threads)) + { + threads.Add(tti.Thread); + } + } + return threads; + } + + public class ThreadTrackerItem + { + public System.Threading.Thread Thread; + public long LastSeenActive; + } + } +} diff --git a/OpenSim/Grid/ScriptServer/ScriptServer/RegionCommManager.cs b/OpenSim/Grid/ScriptServer/ScriptServer/RegionCommManager.cs index cdddcc2..f37d289 100644 --- a/OpenSim/Grid/ScriptServer/ScriptServer/RegionCommManager.cs +++ b/OpenSim/Grid/ScriptServer/ScriptServer/RegionCommManager.cs @@ -61,6 +61,7 @@ namespace OpenSim.Grid.ScriptServer listenThread.Name = "ListenThread"; listenThread.IsBackground = true; listenThread.Start(); + OpenSim.Framework.ThreadTracker.Add(listenThread); } /// diff --git a/OpenSim/Region/Application/OpenSimMain.cs b/OpenSim/Region/Application/OpenSimMain.cs index fc739d9..59f7c63 100644 --- a/OpenSim/Region/Application/OpenSimMain.cs +++ b/OpenSim/Region/Application/OpenSimMain.cs @@ -754,15 +754,30 @@ namespace OpenSim break; case "threads": - m_console.Notice("THREAD", Process.GetCurrentProcess().Threads.Count + " threads running:"); - int _tc = 0; + //m_console.Notice("THREAD", Process.GetCurrentProcess().Threads.Count + " threads running:"); + //int _tc = 0; - foreach (ProcessThread pt in Process.GetCurrentProcess().Threads) + //foreach (ProcessThread pt in Process.GetCurrentProcess().Threads) + //{ + // _tc++; + // m_console.Notice("THREAD", _tc + ": ID: " + pt.Id + ", Started: " + pt.StartTime.ToString() + ", CPU time: " + pt.TotalProcessorTime + ", Pri: " + pt.BasePriority.ToString() + ", State: " + pt.ThreadState.ToString()); + + //} + List threads = OpenSim.Framework.ThreadTracker.GetThreads(); + if (threads == null) + { + m_console.Notice("THREAD", "Thread tracking is only enabled in DEBUG mode."); + } + else + { + int _tc = 0; + m_console.Notice("THREAD", threads.Count + " threads are being tracked:"); + foreach (Thread t in threads) { _tc++; - m_console.Notice("THREAD", _tc + ": ID: " + pt.Id + ", Started: " + pt.StartTime.ToString() + ", CPU time: " + pt.TotalProcessorTime + ", Pri: " + pt.BasePriority.ToString() + ", State: " + pt.ThreadState.ToString()); - + m_console.Notice("THREAD", _tc + ": ID: " + t.ManagedThreadId.ToString() + ", Name: " + t.Name + ", Alive: " + t.IsAlive.ToString() + ", Pri: " + t.Priority.ToString() + ", State: " + t.ThreadState.ToString()); } + } break; diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 47cb582..848a08d 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -228,6 +228,7 @@ namespace OpenSim.Region.ClientStack m_clientThread.Name = "ClientThread"; m_clientThread.IsBackground = true; m_clientThread.Start(); + OpenSim.Framework.ThreadTracker.Add(m_clientThread); } public void SetDebug(int newDebug) diff --git a/OpenSim/Region/Environment/Modules/ChatModule.cs b/OpenSim/Region/Environment/Modules/ChatModule.cs index 0510ad6..c146941 100644 --- a/OpenSim/Region/Environment/Modules/ChatModule.cs +++ b/OpenSim/Region/Environment/Modules/ChatModule.cs @@ -113,7 +113,10 @@ namespace OpenSim.Region.Environment.Modules m_irc_connector.Name = "IRCConnectorThread"; m_irc_connector.IsBackground = true; } - if (!m_irc_connector.IsAlive) { m_irc_connector.Start(); } + if (!m_irc_connector.IsAlive) { + m_irc_connector.Start(); + OpenSim.Framework.ThreadTracker.Add(m_irc_connector); + } } catch (Exception ex) { @@ -260,7 +263,10 @@ namespace OpenSim.Region.Environment.Modules m_irc_connector.Name = "IRCConnectorThread"; m_irc_connector.IsBackground = true; } - if (!m_irc_connector.IsAlive) { m_irc_connector.Start(); } + if (!m_irc_connector.IsAlive) { + m_irc_connector.Start(); + OpenSim.Framework.ThreadTracker.Add(m_irc_connector); + } } catch (Exception ex) { @@ -421,11 +427,13 @@ namespace OpenSim.Region.Environment.Modules pingSender.Name = "PingSenderThread"; pingSender.IsBackground = true; pingSender.Start(); + OpenSim.Framework.ThreadTracker.Add(pingSender); listener = new Thread(new ThreadStart(ListenerRun)); listener.Name = "IRCChatModuleListenerThread"; listener.IsBackground = true; listener.Start(); + OpenSim.Framework.ThreadTracker.Add(listener); m_writer.WriteLine(m_user); m_writer.Flush(); diff --git a/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs b/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs index 47dd250..54a3bc0 100644 --- a/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs +++ b/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs @@ -287,6 +287,7 @@ namespace OpenSim.Region.Environment.Modules httpThread.IsBackground = true; finished = false; httpThread.Start(); + OpenSim.Framework.ThreadTracker.Add(httpThread); } /* diff --git a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs index ecf44a6..c773f9e 100644 --- a/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs +++ b/OpenSim/Region/Environment/Modules/TextureDownloadModule.cs @@ -75,6 +75,7 @@ namespace OpenSim.Region.Environment.Modules m_thread.Name = "ProcessTextureSenderThread"; m_thread.IsBackground = true; m_thread.Start(); + OpenSim.Framework.ThreadTracker.Add(m_thread); } if (!m_scenes.Contains(scene)) diff --git a/OpenSim/Region/Environment/Modules/XMLRPCModule.cs b/OpenSim/Region/Environment/Modules/XMLRPCModule.cs index 3cdb576..6294a49 100644 --- a/OpenSim/Region/Environment/Modules/XMLRPCModule.cs +++ b/OpenSim/Region/Environment/Modules/XMLRPCModule.cs @@ -584,6 +584,7 @@ namespace OpenSim.Region.Environment.Modules httpThread.IsBackground = true; finished = false; httpThread.Start(); + OpenSim.Framework.ThreadTracker.Add(httpThread); return reqID; diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs index 222b8f2..81e3438 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs @@ -57,6 +57,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase cmdHandlerThread.Priority = ThreadPriority.BelowNormal; cmdHandlerThread.IsBackground = true; cmdHandlerThread.Start(); + OpenSim.Framework.ThreadTracker.Add(cmdHandlerThread); } public void ReadConfig() diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs index d4db935..6f96654 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueThreadClass.cs @@ -117,6 +117,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase EventQueueThread.Priority = MyThreadPriority; EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount; EventQueueThread.Start(); + OpenSim.Framework.ThreadTracker.Add(EventQueueThread); // Look at this... Don't you wish everyone did that solid coding everywhere? :P if (ThreadCount == int.MaxValue) diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs index 47446a3..4776ffe 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs @@ -78,6 +78,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase MaintenanceThreadThread.Name = "ScriptMaintenanceThread"; MaintenanceThreadThread.IsBackground = true; MaintenanceThreadThread.Start(); + OpenSim.Framework.ThreadTracker.Add(MaintenanceThreadThread); } } diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs index 43ff4ac..684d133 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs @@ -160,6 +160,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase t.IsBackground = true; t.Priority = ThreadPriority.Normal; t.Start(); + OpenSim.Framework.ThreadTracker.Add(t); return t; } diff --git a/OpenSim/Tools/pCampBot/BotManager.cs b/OpenSim/Tools/pCampBot/BotManager.cs index 1dc1dc1..36f3d7f 100644 --- a/OpenSim/Tools/pCampBot/BotManager.cs +++ b/OpenSim/Tools/pCampBot/BotManager.cs @@ -118,6 +118,7 @@ namespace pCampBot m_td[pos].IsBackground = true; m_td[pos].Start(); m_lBot.Add(pb); + OpenSim.Framework.ThreadTracker.Add(m_td[pos]); } /// -- cgit v1.1