浏览代码

* 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."

John Hurliman 14 年之前
父节点
当前提交
2f394b7e7e

+ 7 - 5
OpenSim/Framework/Util.cs

@@ -69,8 +69,6 @@ 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;
@@ -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();
+        /// <summary>Thread pool used for Util.FireAndForget if
+        /// FireAndForgetMethod.SmartThreadPool is used</summary>
+        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);

+ 6 - 1
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<FireAndForgetMethod>(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);
         }
 

+ 5 - 1
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;

+ 9 - 5
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
     ; ##