diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Util.cs | 127 |
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) |