aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Util.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Util.cs127
1 files changed, 56 insertions, 71 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 557f38e..19d40db 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -89,9 +89,30 @@ namespace OpenSim.Framework
89 } 89 }
90 90
91 /// <summary> 91 /// <summary>
92 /// Class for delivering SmartThreadPool statistical information
93 /// </summary>
94 /// <remarks>
95 /// We do it this way so that we do not directly expose STP.
96 /// </remarks>
97 public class STPInfo
98 {
99 public string Name { get; set; }
100 public STPStartInfo STPStartInfo { get; set; }
101 public WIGStartInfo WIGStartInfo { get; set; }
102 public bool IsIdle { get; set; }
103 public bool IsShuttingDown { get; set; }
104 public int MaxThreads { get; set; }
105 public int MinThreads { get; set; }
106 public int InUseThreads { get; set; }
107 public int ActiveThreads { get; set; }
108 public int WaitingCallbacks { get; set; }
109 public int MaxConcurrentWorkItems { get; set; }
110 }
111
112 /// <summary>
92 /// Miscellaneous utility functions 113 /// Miscellaneous utility functions
93 /// </summary> 114 /// </summary>
94 public class Util 115 public static class Util
95 { 116 {
96 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 117 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
97 118
@@ -120,6 +141,11 @@ namespace OpenSim.Framework
120 public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool; 141 public static FireAndForgetMethod DefaultFireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
121 public static FireAndForgetMethod FireAndForgetMethod = DefaultFireAndForgetMethod; 142 public static FireAndForgetMethod FireAndForgetMethod = DefaultFireAndForgetMethod;
122 143
144 public static bool IsPlatformMono
145 {
146 get { return Type.GetType("Mono.Runtime") != null; }
147 }
148
123 /// <summary> 149 /// <summary>
124 /// Gets the name of the directory where the current running executable 150 /// Gets the name of the directory where the current running executable
125 /// is located 151 /// is located
@@ -1317,7 +1343,7 @@ namespace OpenSim.Framework
1317 ru = "OSX/Mono"; 1343 ru = "OSX/Mono";
1318 else 1344 else
1319 { 1345 {
1320 if (Type.GetType("Mono.Runtime") != null) 1346 if (IsPlatformMono)
1321 ru = "Win/Mono"; 1347 ru = "Win/Mono";
1322 else 1348 else
1323 ru = "Win/.NET"; 1349 ru = "Win/.NET";
@@ -1765,10 +1791,12 @@ namespace OpenSim.Framework
1765 FireAndForget(callback, null); 1791 FireAndForget(callback, null);
1766 } 1792 }
1767 1793
1768 public static void InitThreadPool(int maxThreads) 1794 public static void InitThreadPool(int minThreads, int maxThreads)
1769 { 1795 {
1770 if (maxThreads < 2) 1796 if (maxThreads < 2)
1771 throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2"); 1797 throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2");
1798 if (minThreads > maxThreads || minThreads < 2)
1799 throw new ArgumentOutOfRangeException("minThreads", "minThreads must be greater than 2 and less than or equal to maxThreads");
1772 if (m_ThreadPool != null) 1800 if (m_ThreadPool != null)
1773 throw new InvalidOperationException("SmartThreadPool is already initialized"); 1801 throw new InvalidOperationException("SmartThreadPool is already initialized");
1774 1802
@@ -1776,7 +1804,7 @@ namespace OpenSim.Framework
1776 startInfo.ThreadPoolName = "Util"; 1804 startInfo.ThreadPoolName = "Util";
1777 startInfo.IdleTimeout = 2000; 1805 startInfo.IdleTimeout = 2000;
1778 startInfo.MaxWorkerThreads = maxThreads; 1806 startInfo.MaxWorkerThreads = maxThreads;
1779 startInfo.MinWorkerThreads = 2; 1807 startInfo.MinWorkerThreads = minThreads;
1780 1808
1781 m_ThreadPool = new SmartThreadPool(startInfo); 1809 m_ThreadPool = new SmartThreadPool(startInfo);
1782 } 1810 }
@@ -1851,8 +1879,8 @@ namespace OpenSim.Framework
1851 break; 1879 break;
1852 case FireAndForgetMethod.SmartThreadPool: 1880 case FireAndForgetMethod.SmartThreadPool:
1853 if (m_ThreadPool == null) 1881 if (m_ThreadPool == null)
1854 InitThreadPool(15); 1882 InitThreadPool(2, 15);
1855 m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { realCallback, obj }); 1883 m_ThreadPool.QueueWorkItem((cb, o) => cb(o), realCallback, obj);
1856 break; 1884 break;
1857 case FireAndForgetMethod.Thread: 1885 case FireAndForgetMethod.Thread:
1858 Thread thread = new Thread(delegate(object o) { realCallback(o); }); 1886 Thread thread = new Thread(delegate(object o) { realCallback(o); });
@@ -1864,72 +1892,29 @@ namespace OpenSim.Framework
1864 } 1892 }
1865 1893
1866 /// <summary> 1894 /// <summary>
1867 /// Get a thread pool report. 1895 /// Get information about the current state of the smart thread pool.
1868 /// </summary> 1896 /// </summary>
1869 /// <returns></returns> 1897 /// <returns>
1870 public static string GetThreadPoolReport() 1898 /// null if this isn't the pool being used for non-scriptengine threads.
1899 /// </returns>
1900 public static STPInfo GetSmartThreadPoolInfo()
1871 { 1901 {
1872 string threadPoolUsed = null; 1902 if (m_ThreadPool == null)
1873 int maxThreads = 0; 1903 return null;
1874 int minThreads = 0;
1875 int allocatedThreads = 0;
1876 int inUseThreads = 0;
1877 int waitingCallbacks = 0;
1878 int completionPortThreads = 0;
1879
1880 StringBuilder sb = new StringBuilder();
1881 if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
1882 {
1883 // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
1884 if (m_ThreadPool != null)
1885 {
1886 threadPoolUsed = "SmartThreadPool";
1887 maxThreads = m_ThreadPool.MaxThreads;
1888 minThreads = m_ThreadPool.MinThreads;
1889 inUseThreads = m_ThreadPool.InUseThreads;
1890 allocatedThreads = m_ThreadPool.ActiveThreads;
1891 waitingCallbacks = m_ThreadPool.WaitingCallbacks;
1892 }
1893 }
1894 else if (
1895 FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
1896 || FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
1897 {
1898 threadPoolUsed = "BuiltInThreadPool";
1899 ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
1900 ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
1901 int availableThreads;
1902 ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
1903 inUseThreads = maxThreads - availableThreads;
1904 allocatedThreads = -1;
1905 waitingCallbacks = -1;
1906 }
1907
1908 if (threadPoolUsed != null)
1909 {
1910 sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
1911 sb.AppendFormat("Max threads : {0}\n", maxThreads);
1912 sb.AppendFormat("Min threads : {0}\n", minThreads);
1913 sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
1914 sb.AppendFormat("In use threads : {0}\n", inUseThreads);
1915 sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
1916 }
1917 else
1918 {
1919 sb.AppendFormat("Thread pool not used\n");
1920 }
1921
1922 return sb.ToString();
1923 }
1924 1904
1925 private static object SmartThreadPoolCallback(object o) 1905 STPInfo stpi = new STPInfo();
1926 { 1906 stpi.Name = m_ThreadPool.Name;
1927 object[] array = (object[])o; 1907 stpi.STPStartInfo = m_ThreadPool.STPStartInfo;
1928 WaitCallback callback = (WaitCallback)array[0]; 1908 stpi.IsIdle = m_ThreadPool.IsIdle;
1929 object obj = array[1]; 1909 stpi.IsShuttingDown = m_ThreadPool.IsShuttingdown;
1910 stpi.MaxThreads = m_ThreadPool.MaxThreads;
1911 stpi.MinThreads = m_ThreadPool.MinThreads;
1912 stpi.InUseThreads = m_ThreadPool.InUseThreads;
1913 stpi.ActiveThreads = m_ThreadPool.ActiveThreads;
1914 stpi.WaitingCallbacks = m_ThreadPool.WaitingCallbacks;
1915 stpi.MaxConcurrentWorkItems = m_ThreadPool.Concurrency;
1930 1916
1931 callback(obj); 1917 return stpi;
1932 return null;
1933 } 1918 }
1934 1919
1935 #endregion FireAndForget Threading Pattern 1920 #endregion FireAndForget Threading Pattern
@@ -2148,7 +2133,7 @@ namespace OpenSim.Framework
2148 /// <param name="secret">the secret part</param> 2133 /// <param name="secret">the secret part</param>
2149 public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret) 2134 public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
2150 { 2135 {
2151 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty; 2136 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "UserUPUUI"; secret = string.Empty;
2152 2137
2153 string[] parts = value.Split(';'); 2138 string[] parts = value.Split(';');
2154 if (parts.Length >= 1) 2139 if (parts.Length >= 1)
@@ -2282,7 +2267,7 @@ namespace OpenSim.Framework
2282 { 2267 {
2283 lock (m_syncRoot) 2268 lock (m_syncRoot)
2284 { 2269 {
2285 m_lowQueue.Enqueue(data); 2270 q.Enqueue(data);
2286 m_s.WaitOne(0); 2271 m_s.WaitOne(0);
2287 m_s.Release(); 2272 m_s.Release();
2288 } 2273 }
@@ -2322,7 +2307,7 @@ namespace OpenSim.Framework
2322 { 2307 {
2323 if (m_highQueue.Count > 0) 2308 if (m_highQueue.Count > 0)
2324 res = m_highQueue.Dequeue(); 2309 res = m_highQueue.Dequeue();
2325 else 2310 else if (m_lowQueue.Count > 0)
2326 res = m_lowQueue.Dequeue(); 2311 res = m_lowQueue.Dequeue();
2327 2312
2328 if (m_highQueue.Count == 0 && m_lowQueue.Count == 0) 2313 if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)