aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/Util.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Framework/Util.cs')
-rw-r--r--OpenSim/Framework/Util.cs143
1 files changed, 63 insertions, 80 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 557f38e..7db575b 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
@@ -109,7 +130,7 @@ namespace OpenSim.Framework
109 private static SmartThreadPool m_ThreadPool; 130 private static SmartThreadPool m_ThreadPool;
110 131
111 // 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. 132 // 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.
112 private static readonly DateTime unixEpoch = 133 public static readonly DateTime UnixEpoch =
113 DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime(); 134 DateTime.ParseExact("1970-01-01 00:00:00 +0", "yyyy-MM-dd hh:mm:ss z", DateTimeFormatInfo.InvariantInfo).ToUniversalTime();
114 135
115 private static readonly string rawUUIDPattern 136 private static readonly string rawUUIDPattern
@@ -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
@@ -495,20 +521,18 @@ namespace OpenSim.Framework
495 521
496 public static int ToUnixTime(DateTime stamp) 522 public static int ToUnixTime(DateTime stamp)
497 { 523 {
498 TimeSpan t = stamp.ToUniversalTime() - unixEpoch; 524 TimeSpan t = stamp.ToUniversalTime() - UnixEpoch;
499 return (int) t.TotalSeconds; 525 return (int)t.TotalSeconds;
500 } 526 }
501 527
502 public static DateTime ToDateTime(ulong seconds) 528 public static DateTime ToDateTime(ulong seconds)
503 { 529 {
504 DateTime epoch = unixEpoch; 530 return UnixEpoch.AddSeconds(seconds);
505 return epoch.AddSeconds(seconds);
506 } 531 }
507 532
508 public static DateTime ToDateTime(int seconds) 533 public static DateTime ToDateTime(int seconds)
509 { 534 {
510 DateTime epoch = unixEpoch; 535 return UnixEpoch.AddSeconds(seconds);
511 return epoch.AddSeconds(seconds);
512 } 536 }
513 537
514 /// <summary> 538 /// <summary>
@@ -1233,7 +1257,7 @@ namespace OpenSim.Framework
1233 byte[] bytes = 1257 byte[] bytes =
1234 { 1258 {
1235 (byte)regionHandle, (byte)(regionHandle >> 8), (byte)(regionHandle >> 16), (byte)(regionHandle >> 24), 1259 (byte)regionHandle, (byte)(regionHandle >> 8), (byte)(regionHandle >> 16), (byte)(regionHandle >> 24),
1236 (byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle << 56), 1260 (byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle >> 56),
1237 (byte)x, (byte)(x >> 8), 0, 0, 1261 (byte)x, (byte)(x >> 8), 0, 0,
1238 (byte)y, (byte)(y >> 8), 0, 0 }; 1262 (byte)y, (byte)(y >> 8), 0, 0 };
1239 return new UUID(bytes, 0); 1263 return new UUID(bytes, 0);
@@ -1244,7 +1268,7 @@ namespace OpenSim.Framework
1244 byte[] bytes = 1268 byte[] bytes =
1245 { 1269 {
1246 (byte)regionHandle, (byte)(regionHandle >> 8), (byte)(regionHandle >> 16), (byte)(regionHandle >> 24), 1270 (byte)regionHandle, (byte)(regionHandle >> 8), (byte)(regionHandle >> 16), (byte)(regionHandle >> 24),
1247 (byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle << 56), 1271 (byte)(regionHandle >> 32), (byte)(regionHandle >> 40), (byte)(regionHandle >> 48), (byte)(regionHandle >> 56),
1248 (byte)x, (byte)(x >> 8), (byte)z, (byte)(z >> 8), 1272 (byte)x, (byte)(x >> 8), (byte)z, (byte)(z >> 8),
1249 (byte)y, (byte)(y >> 8), 0, 0 }; 1273 (byte)y, (byte)(y >> 8), 0, 0 };
1250 return new UUID(bytes, 0); 1274 return new UUID(bytes, 0);
@@ -1317,7 +1341,7 @@ namespace OpenSim.Framework
1317 ru = "OSX/Mono"; 1341 ru = "OSX/Mono";
1318 else 1342 else
1319 { 1343 {
1320 if (Type.GetType("Mono.Runtime") != null) 1344 if (IsPlatformMono)
1321 ru = "Win/Mono"; 1345 ru = "Win/Mono";
1322 else 1346 else
1323 ru = "Win/.NET"; 1347 ru = "Win/.NET";
@@ -1765,10 +1789,12 @@ namespace OpenSim.Framework
1765 FireAndForget(callback, null); 1789 FireAndForget(callback, null);
1766 } 1790 }
1767 1791
1768 public static void InitThreadPool(int maxThreads) 1792 public static void InitThreadPool(int minThreads, int maxThreads)
1769 { 1793 {
1770 if (maxThreads < 2) 1794 if (maxThreads < 2)
1771 throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2"); 1795 throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2");
1796 if (minThreads > maxThreads || minThreads < 2)
1797 throw new ArgumentOutOfRangeException("minThreads", "minThreads must be greater than 2 and less than or equal to maxThreads");
1772 if (m_ThreadPool != null) 1798 if (m_ThreadPool != null)
1773 throw new InvalidOperationException("SmartThreadPool is already initialized"); 1799 throw new InvalidOperationException("SmartThreadPool is already initialized");
1774 1800
@@ -1776,7 +1802,7 @@ namespace OpenSim.Framework
1776 startInfo.ThreadPoolName = "Util"; 1802 startInfo.ThreadPoolName = "Util";
1777 startInfo.IdleTimeout = 2000; 1803 startInfo.IdleTimeout = 2000;
1778 startInfo.MaxWorkerThreads = maxThreads; 1804 startInfo.MaxWorkerThreads = maxThreads;
1779 startInfo.MinWorkerThreads = 2; 1805 startInfo.MinWorkerThreads = minThreads;
1780 1806
1781 m_ThreadPool = new SmartThreadPool(startInfo); 1807 m_ThreadPool = new SmartThreadPool(startInfo);
1782 } 1808 }
@@ -1851,8 +1877,8 @@ namespace OpenSim.Framework
1851 break; 1877 break;
1852 case FireAndForgetMethod.SmartThreadPool: 1878 case FireAndForgetMethod.SmartThreadPool:
1853 if (m_ThreadPool == null) 1879 if (m_ThreadPool == null)
1854 InitThreadPool(15); 1880 InitThreadPool(2, 15);
1855 m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { realCallback, obj }); 1881 m_ThreadPool.QueueWorkItem((cb, o) => cb(o), realCallback, obj);
1856 break; 1882 break;
1857 case FireAndForgetMethod.Thread: 1883 case FireAndForgetMethod.Thread:
1858 Thread thread = new Thread(delegate(object o) { realCallback(o); }); 1884 Thread thread = new Thread(delegate(object o) { realCallback(o); });
@@ -1864,72 +1890,29 @@ namespace OpenSim.Framework
1864 } 1890 }
1865 1891
1866 /// <summary> 1892 /// <summary>
1867 /// Get a thread pool report. 1893 /// Get information about the current state of the smart thread pool.
1868 /// </summary> 1894 /// </summary>
1869 /// <returns></returns> 1895 /// <returns>
1870 public static string GetThreadPoolReport() 1896 /// null if this isn't the pool being used for non-scriptengine threads.
1897 /// </returns>
1898 public static STPInfo GetSmartThreadPoolInfo()
1871 { 1899 {
1872 string threadPoolUsed = null; 1900 if (m_ThreadPool == null)
1873 int maxThreads = 0; 1901 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 1902
1925 private static object SmartThreadPoolCallback(object o) 1903 STPInfo stpi = new STPInfo();
1926 { 1904 stpi.Name = m_ThreadPool.Name;
1927 object[] array = (object[])o; 1905 stpi.STPStartInfo = m_ThreadPool.STPStartInfo;
1928 WaitCallback callback = (WaitCallback)array[0]; 1906 stpi.IsIdle = m_ThreadPool.IsIdle;
1929 object obj = array[1]; 1907 stpi.IsShuttingDown = m_ThreadPool.IsShuttingdown;
1908 stpi.MaxThreads = m_ThreadPool.MaxThreads;
1909 stpi.MinThreads = m_ThreadPool.MinThreads;
1910 stpi.InUseThreads = m_ThreadPool.InUseThreads;
1911 stpi.ActiveThreads = m_ThreadPool.ActiveThreads;
1912 stpi.WaitingCallbacks = m_ThreadPool.WaitingCallbacks;
1913 stpi.MaxConcurrentWorkItems = m_ThreadPool.Concurrency;
1930 1914
1931 callback(obj); 1915 return stpi;
1932 return null;
1933 } 1916 }
1934 1917
1935 #endregion FireAndForget Threading Pattern 1918 #endregion FireAndForget Threading Pattern
@@ -2148,7 +2131,7 @@ namespace OpenSim.Framework
2148 /// <param name="secret">the secret part</param> 2131 /// <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) 2132 public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
2150 { 2133 {
2151 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty; 2134 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "UserUPUUI"; secret = string.Empty;
2152 2135
2153 string[] parts = value.Split(';'); 2136 string[] parts = value.Split(';');
2154 if (parts.Length >= 1) 2137 if (parts.Length >= 1)
@@ -2282,7 +2265,7 @@ namespace OpenSim.Framework
2282 { 2265 {
2283 lock (m_syncRoot) 2266 lock (m_syncRoot)
2284 { 2267 {
2285 m_lowQueue.Enqueue(data); 2268 q.Enqueue(data);
2286 m_s.WaitOne(0); 2269 m_s.WaitOne(0);
2287 m_s.Release(); 2270 m_s.Release();
2288 } 2271 }
@@ -2322,7 +2305,7 @@ namespace OpenSim.Framework
2322 { 2305 {
2323 if (m_highQueue.Count > 0) 2306 if (m_highQueue.Count > 0)
2324 res = m_highQueue.Dequeue(); 2307 res = m_highQueue.Dequeue();
2325 else 2308 else if (m_lowQueue.Count > 0)
2326 res = m_lowQueue.Dequeue(); 2309 res = m_lowQueue.Dequeue();
2327 2310
2328 if (m_highQueue.Count == 0 && m_lowQueue.Count == 0) 2311 if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)