From 8a336c6860d66b9fbba6922c32e7a57fd355c57e Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 22 Oct 2009 02:28:53 +0100 Subject: Add MaxPoolThreads in startup to limit the size of the thread pool used for FireAndForget. This lets us limit concurrency to make OpenSim play nice --- OpenSim/Framework/Util.cs | 34 ++++++++++++++++++++++------------ OpenSim/Region/Application/OpenSim.cs | 2 ++ 2 files changed, 24 insertions(+), 12 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index d5ae3b7..9dfb75e 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -41,12 +41,14 @@ using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Xml; +using System.Threading; using log4net; using Nini.Config; using Nwc.XmlRpc; using BclExtras; using OpenMetaverse; using OpenMetaverse.StructuredData; +using Amib.Threading; namespace OpenSim.Framework { @@ -55,6 +57,8 @@ namespace OpenSim.Framework /// public class Util { + private static SmartThreadPool m_ThreadPool = null; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static uint nextXferID = 5000; @@ -1293,22 +1297,28 @@ namespace OpenSim.Framework System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, null); } - public static void FireAndForget(System.Threading.WaitCallback callback, object obj) + public static void SetMaxThreads(int maxThreads) { - //FireAndForgetWrapper wrapper = Singleton.GetInstance(); - //wrapper.FireAndForget(callback, obj); - System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, obj); - } + STPStartInfo startInfo = new STPStartInfo(); + startInfo.IdleTimeout = 2000; // 2 seconds + startInfo.MaxWorkerThreads = maxThreads; + startInfo.MinWorkerThreads = 5; + startInfo.StackSize = 524288; + startInfo.ThreadPriority = ThreadPriority.Normal; - /*private static void EndFireAndForget(IAsyncResult ar) - { - System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState; + startInfo.StartSuspended = false; - try { callback.EndInvoke(ar); } - catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); } + m_ThreadPool = new SmartThreadPool(startInfo); + } - ar.AsyncWaitHandle.Close(); - }*/ + public static void FireAndForget(System.Threading.WaitCallback callback, object obj) + { + m_ThreadPool.QueueWorkItem(new WorkItemCallback(delegate(object o) + { + callback(o); + return null; + }), obj); + } #endregion FireAndForget Threading Pattern } diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 143dd2a..42e2a1e 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -67,6 +67,8 @@ namespace OpenSim IConfig startupConfig = m_config.Source.Configs["Startup"]; + Util.SetMaxThreads(startupConfig.GetInt("MaxPoolThreads", 30)); + if (startupConfig != null) { m_startupCommandsFile = startupConfig.GetString("startup_console_commands_file", "startup_commands.txt"); -- cgit v1.1