From 2f394b7e7ebf991c7a70f93bf251d26d8043aaa2 Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Thu, 22 Oct 2009 01:30:12 -0700
Subject: * Allow SmartThreadPool to be initialized without setting max stack
size (like the original implementation) * Only initialize Util's
SmartThreadPool if it is actually being used * No longer initializing Util's
SmartThreadPool with a custom max stack size. From MSDN: "Avoid using this
constructor overload. The default stack size used by the Thread(ThreadStart)
constructor overload is the recommended stack size for threads."
---
OpenSim/Framework/Util.cs | 12 +++++++-----
OpenSim/Region/Application/OpenSim.cs | 7 ++++++-
ThirdParty/SmartThreadPool/SmartThreadPool.cs | 6 +++++-
bin/OpenSim.ini.example | 14 +++++++++-----
4 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index d09bd6d..167e34d 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -69,8 +69,6 @@ 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;
@@ -79,6 +77,9 @@ namespace OpenSim.Framework
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
private static object XferLock = new object();
+ /// Thread pool used for Util.FireAndForget if
+ /// FireAndForgetMethod.SmartThreadPool is used
+ private static SmartThreadPool m_ThreadPool;
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
private static readonly DateTime unixEpoch =
@@ -1319,8 +1320,11 @@ namespace OpenSim.Framework
FireAndForget(callback, null);
}
- public static void SetMaxThreads(int maxThreads)
+ public static void InitThreadPool(int maxThreads)
{
+ if (maxThreads < 2)
+ throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2");
+
if (m_ThreadPool != null)
return;
@@ -1328,9 +1332,7 @@ namespace OpenSim.Framework
startInfo.IdleTimeout = 2000; // 2 seconds
startInfo.MaxWorkerThreads = maxThreads;
startInfo.MinWorkerThreads = 2;
- startInfo.StackSize = 524288;
startInfo.ThreadPriority = ThreadPriority.Normal;
-
startInfo.StartSuspended = false;
m_ThreadPool = new SmartThreadPool(startInfo);
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index c04b8c2..26298e7 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -67,7 +67,7 @@ namespace OpenSim
IConfig startupConfig = m_config.Source.Configs["Startup"];
- Util.SetMaxThreads(startupConfig.GetInt("MaxPoolThreads", 15));
+ int stpMaxThreads = 15;
if (startupConfig != null)
{
@@ -100,8 +100,13 @@ namespace OpenSim
FireAndForgetMethod asyncCallMethod;
if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse(asyncCallMethodStr, out asyncCallMethod))
Util.FireAndForgetMethod = asyncCallMethod;
+
+ stpMaxThreads = startupConfig.GetInt("MaxPoolThreads", 15);
}
+ if (Util.FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
+ Util.InitThreadPool(stpMaxThreads);
+
m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod);
}
diff --git a/ThirdParty/SmartThreadPool/SmartThreadPool.cs b/ThirdParty/SmartThreadPool/SmartThreadPool.cs
index c21984e..bd52f62 100644
--- a/ThirdParty/SmartThreadPool/SmartThreadPool.cs
+++ b/ThirdParty/SmartThreadPool/SmartThreadPool.cs
@@ -499,7 +499,11 @@ namespace Amib.Threading
}
// Create a new thread
- Thread workerThread = new Thread(new ThreadStart(ProcessQueuedItems), _stpStartInfo.StackSize);
+ Thread workerThread;
+ if (_stpStartInfo.StackSize > 0)
+ workerThread = new Thread(ProcessQueuedItems, _stpStartInfo.StackSize);
+ else
+ workerThread = new Thread(ProcessQueuedItems);
// Configure the new thread and start it
workerThread.Name = "STP " + Name + " Thread #" + _threadCounter;
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 79d57d2..08f87d6 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -38,8 +38,15 @@
; Sets the method that OpenSim will use to fire asynchronous
; events. Valid values are UnsafeQueueUserWorkItem,
- ; QueueUserWorkItem, BeginInvoke, SmartThreadPool, and Thread
- ; async_call_method = SmartThreadPool
+ ; QueueUserWorkItem, BeginInvoke, SmartThreadPool, and Thread.
+ ; SmartThreadPool is reported to work well on Mono/Linux, but
+ ; UnsafeQueueUserWorkItem has been benchmarked with better
+ ; performance on .NET/Windows
+ ;async_call_method = SmartThreadPool
+
+ ; Max threads to allocate on the FireAndForget thread pool
+ ; when running with the SmartThreadPool option above
+ MaxPoolThreads = 15
; ##
; ## CLIENTS
@@ -51,9 +58,6 @@
; 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 = 15
-
; ##
; ## REGIONS
; ##
--
cgit v1.1