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 ++ bin/OpenSim.ini.example | 3 +++ prebuild.xml | 45 ++++++++++++++++++----------------- 4 files changed, 50 insertions(+), 34 deletions(-) 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 /// </summary> 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<FireAndForgetWrapper>(); - //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"); diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 2d56f4e..92e6d91 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -42,6 +42,9 @@ ; Set this to the DLL containing the client stack to use. clientstack_plugin="OpenSim.Region.ClientStack.LindenUDP.dll" + ; Max threads to allocate on the FireAndForget pool + MaxPoolThreads = 30 + ; ## ; ## REGIONS ; ## diff --git a/prebuild.xml b/prebuild.xml index e17da9a..81f907d 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -117,6 +117,28 @@ </Files> </Project> + <Project frameworkVersion="v3_5" name="SmartThreadPool" path="ThirdParty/SmartThreadPool" type="Library"> + <Configuration name="Debug"> + <Options> + <OutputPath>../../bin/</OutputPath> + </Options> + </Configuration> + <Configuration name="Release"> + <Options> + <OutputPath>../../bin/</OutputPath> + </Options> + </Configuration> + + <ReferencePath>../../bin/</ReferencePath> + <Reference name="System"/> + <Reference name="System.Xml"/> + <Reference name="System.Data"/> + <Reference name="System.Web"/> + <Files> + <Match pattern="*.cs" recurse="false"/> + </Files> + </Project> + <Project frameworkVersion="v3_5" name="OpenSim.Framework" path="OpenSim/Framework" type="Library"> <Configuration name="Debug"> <Options> @@ -145,6 +167,7 @@ <Reference name="Nini.dll" /> <Reference name="log4net.dll"/> <Reference name="Mono.Addins.dll" /> + <Reference name="SmartThreadPool" /> <Files> <Match pattern="*.cs" recurse="false"/> <Match path="Client" pattern="*.cs" recurse="true"/> @@ -2387,28 +2410,6 @@ </Files> </Project> - <Project frameworkVersion="v3_5" name="SmartThreadPool" path="ThirdParty/SmartThreadPool" type="Library"> - <Configuration name="Debug"> - <Options> - <OutputPath>../../bin/</OutputPath> - </Options> - </Configuration> - <Configuration name="Release"> - <Options> - <OutputPath>../../bin/</OutputPath> - </Options> - </Configuration> - - <ReferencePath>../../bin/</ReferencePath> - <Reference name="System"/> - <Reference name="System.Xml"/> - <Reference name="System.Data"/> - <Reference name="System.Web"/> - <Files> - <Match pattern="*.cs" recurse="false"/> - </Files> - </Project> - <Project frameworkVersion="v3_5" name="OpenSim.Region.ScriptEngine.Shared" path="OpenSim/Region/ScriptEngine/Shared" type="Library"> <Configuration name="Debug"> <Options> -- cgit v1.1