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.cs230
1 files changed, 167 insertions, 63 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index efa4a7b..e03bb74 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -35,7 +35,7 @@ using System.IO;
35using System.IO.Compression; 35using System.IO.Compression;
36using System.Net; 36using System.Net;
37using System.Net.Sockets; 37using System.Net.Sockets;
38using System.Reflection; 38using System.Reflection;
39using System.Runtime.InteropServices; 39using System.Runtime.InteropServices;
40using System.Runtime.Serialization; 40using System.Runtime.Serialization;
41using System.Runtime.Serialization.Formatters.Binary; 41using System.Runtime.Serialization.Formatters.Binary;
@@ -81,12 +81,15 @@ namespace OpenSim.Framework
81 81
82 private static uint nextXferID = 5000; 82 private static uint nextXferID = 5000;
83 private static Random randomClass = new Random(); 83 private static Random randomClass = new Random();
84
84 // Get a list of invalid file characters (OS dependent) 85 // Get a list of invalid file characters (OS dependent)
85 private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]"; 86 private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
86 private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]"; 87 private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
87 private static object XferLock = new object(); 88 private static object XferLock = new object();
88 /// <summary>Thread pool used for Util.FireAndForget if 89
89 /// FireAndForgetMethod.SmartThreadPool is used</summary> 90 /// <summary>
91 /// Thread pool used for Util.FireAndForget if FireAndForgetMethod.SmartThreadPool is used
92 /// </summary>
90 private static SmartThreadPool m_ThreadPool; 93 private static SmartThreadPool m_ThreadPool;
91 94
92 // 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. 95 // 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.
@@ -144,7 +147,6 @@ namespace OpenSim.Framework
144 return lerp(y, lerp(x, a, b), lerp(x, c, d)); 147 return lerp(y, lerp(x, a, b), lerp(x, c, d));
145 } 148 }
146 149
147
148 public static Encoding UTF8 = Encoding.UTF8; 150 public static Encoding UTF8 = Encoding.UTF8;
149 151
150 /// <value> 152 /// <value>
@@ -376,20 +378,20 @@ namespace OpenSim.Framework
376 } 378 }
377 379
378 return sb.ToString(); 380 return sb.ToString();
379 } 381 }
380 382
381 /// <summary> 383 /// <summary>
382 /// Is the platform Windows? 384 /// Is the platform Windows?
383 /// </summary> 385 /// </summary>
384 /// <returns>true if so, false otherwise</returns> 386 /// <returns>true if so, false otherwise</returns>
385 public static bool IsWindows() 387 public static bool IsWindows()
386 { 388 {
387 PlatformID platformId = Environment.OSVersion.Platform; 389 PlatformID platformId = Environment.OSVersion.Platform;
388 390
389 return (platformId == PlatformID.Win32NT 391 return (platformId == PlatformID.Win32NT
390 || platformId == PlatformID.Win32S 392 || platformId == PlatformID.Win32S
391 || platformId == PlatformID.Win32Windows 393 || platformId == PlatformID.Win32Windows
392 || platformId == PlatformID.WinCE); 394 || platformId == PlatformID.WinCE);
393 } 395 }
394 396
395 public static bool LoadArchSpecificWindowsDll(string libraryName) 397 public static bool LoadArchSpecificWindowsDll(string libraryName)
@@ -1502,27 +1504,27 @@ namespace OpenSim.Framework
1502 } 1504 }
1503 1505
1504 return data; 1506 return data;
1505 } 1507 }
1506 1508
1507 /// <summary> 1509 /// <summary>
1508 /// Used to trigger an early library load on Windows systems. 1510 /// Used to trigger an early library load on Windows systems.
1509 /// </summary> 1511 /// </summary>
1510 /// <remarks> 1512 /// <remarks>
1511 /// Required to get 32-bit and 64-bit processes to automatically use the 1513 /// Required to get 32-bit and 64-bit processes to automatically use the
1512 /// appropriate native library. 1514 /// appropriate native library.
1513 /// </remarks> 1515 /// </remarks>
1514 /// <param name="dllToLoad"></param> 1516 /// <param name="dllToLoad"></param>
1515 /// <returns></returns> 1517 /// <returns></returns>
1516 [DllImport("kernel32.dll")] 1518 [DllImport("kernel32.dll")]
1517 public static extern IntPtr LoadLibrary(string dllToLoad); 1519 public static extern IntPtr LoadLibrary(string dllToLoad);
1518 1520
1519 /// <summary> 1521 /// <summary>
1520 /// Determine whether the current process is 64 bit 1522 /// Determine whether the current process is 64 bit
1521 /// </summary> 1523 /// </summary>
1522 /// <returns>true if so, false if not</returns> 1524 /// <returns>true if so, false if not</returns>
1523 public static bool Is64BitProcess() 1525 public static bool Is64BitProcess()
1524 { 1526 {
1525 return IntPtr.Size == 8; 1527 return IntPtr.Size == 8;
1526 } 1528 }
1527 1529
1528 #region FireAndForget Threading Pattern 1530 #region FireAndForget Threading Pattern
@@ -1671,6 +1673,61 @@ namespace OpenSim.Framework
1671 } 1673 }
1672 } 1674 }
1673 1675
1676 /// <summary>
1677 /// Get a thread pool report.
1678 /// </summary>
1679 /// <returns></returns>
1680 public static string GetThreadPoolReport()
1681 {
1682 string threadPoolUsed = null;
1683 int maxThreads = 0;
1684 int minThreads = 0;
1685 int allocatedThreads = 0;
1686 int inUseThreads = 0;
1687 int waitingCallbacks = 0;
1688 int completionPortThreads = 0;
1689
1690 StringBuilder sb = new StringBuilder();
1691 if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
1692 {
1693 threadPoolUsed = "SmartThreadPool";
1694 maxThreads = m_ThreadPool.MaxThreads;
1695 minThreads = m_ThreadPool.MinThreads;
1696 inUseThreads = m_ThreadPool.InUseThreads;
1697 allocatedThreads = m_ThreadPool.ActiveThreads;
1698 waitingCallbacks = m_ThreadPool.WaitingCallbacks;
1699 }
1700 else if (
1701 FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
1702 || FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem)
1703 {
1704 threadPoolUsed = "BuiltInThreadPool";
1705 ThreadPool.GetMaxThreads(out maxThreads, out completionPortThreads);
1706 ThreadPool.GetMinThreads(out minThreads, out completionPortThreads);
1707 int availableThreads;
1708 ThreadPool.GetAvailableThreads(out availableThreads, out completionPortThreads);
1709 inUseThreads = maxThreads - availableThreads;
1710 allocatedThreads = -1;
1711 waitingCallbacks = -1;
1712 }
1713
1714 if (threadPoolUsed != null)
1715 {
1716 sb.AppendFormat("Thread pool used : {0}\n", threadPoolUsed);
1717 sb.AppendFormat("Max threads : {0}\n", maxThreads);
1718 sb.AppendFormat("Min threads : {0}\n", minThreads);
1719 sb.AppendFormat("Allocated threads : {0}\n", allocatedThreads < 0 ? "not applicable" : allocatedThreads.ToString());
1720 sb.AppendFormat("In use threads : {0}\n", inUseThreads);
1721 sb.AppendFormat("Work items waiting : {0}\n", waitingCallbacks < 0 ? "not available" : waitingCallbacks.ToString());
1722 }
1723 else
1724 {
1725 sb.AppendFormat("Thread pool not used\n");
1726 }
1727
1728 return sb.ToString();
1729 }
1730
1674 private static object SmartThreadPoolCallback(object o) 1731 private static object SmartThreadPoolCallback(object o)
1675 { 1732 {
1676 object[] array = (object[])o; 1733 object[] array = (object[])o;
@@ -1701,13 +1758,26 @@ namespace OpenSim.Framework
1701 /// and negative every 24.9 days. Subtracts the passed value (previously fetched by 1758 /// and negative every 24.9 days. Subtracts the passed value (previously fetched by
1702 /// 'EnvironmentTickCount()') and accounts for any wrapping. 1759 /// 'EnvironmentTickCount()') and accounts for any wrapping.
1703 /// </summary> 1760 /// </summary>
1761 /// <param name="newValue"></param>
1762 /// <param name="prevValue"></param>
1704 /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns> 1763 /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
1705 public static Int32 EnvironmentTickCountSubtract(Int32 prevValue) 1764 public static Int32 EnvironmentTickCountSubtract(Int32 newValue, Int32 prevValue)
1706 { 1765 {
1707 Int32 diff = EnvironmentTickCount() - prevValue; 1766 Int32 diff = newValue - prevValue;
1708 return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); 1767 return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1);
1709 } 1768 }
1710 1769
1770 /// <summary>
1771 /// Environment.TickCount is an int but it counts all 32 bits so it goes positive
1772 /// and negative every 24.9 days. Subtracts the passed value (previously fetched by
1773 /// 'EnvironmentTickCount()') and accounts for any wrapping.
1774 /// </summary>
1775 /// <returns>subtraction of passed prevValue from current Environment.TickCount</returns>
1776 public static Int32 EnvironmentTickCountSubtract(Int32 prevValue)
1777 {
1778 return EnvironmentTickCountSubtract(EnvironmentTickCount(), prevValue);
1779 }
1780
1711 // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount 1781 // Returns value of Tick Count A - TickCount B accounting for wrapping of TickCount
1712 // Assumes both tcA and tcB came from previous calls to Util.EnvironmentTickCount(). 1782 // Assumes both tcA and tcB came from previous calls to Util.EnvironmentTickCount().
1713 // A positive return value indicates A occured later than B 1783 // A positive return value indicates A occured later than B
@@ -1870,11 +1940,12 @@ namespace OpenSim.Framework
1870 #region Universal User Identifiers 1940 #region Universal User Identifiers
1871 /// <summary> 1941 /// <summary>
1872 /// </summary> 1942 /// </summary>
1873 /// <param name="value">uuid[;endpoint[;name]]</param> 1943 /// <param name="value">uuid[;endpoint[;first last[;secret]]]</param>
1874 /// <param name="uuid"></param> 1944 /// <param name="uuid">the uuid part</param>
1875 /// <param name="url"></param> 1945 /// <param name="url">the endpoint part (e.g. http://foo.com)</param>
1876 /// <param name="firstname"></param> 1946 /// <param name="firstname">the first name part (e.g. Test)</param>
1877 /// <param name="lastname"></param> 1947 /// <param name="lastname">the last name part (e.g User)</param>
1948 /// <param name="secret">the secret part</param>
1878 public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret) 1949 public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
1879 { 1950 {
1880 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty; 1951 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
@@ -1903,31 +1974,64 @@ namespace OpenSim.Framework
1903 } 1974 }
1904 1975
1905 /// <summary> 1976 /// <summary>
1906 /// 1977 /// Produces a universal (HG) system-facing identifier given the information
1907 /// </summary> 1978 /// </summary>
1908 /// <param name="acircuit"></param> 1979 /// <param name="acircuit"></param>
1909 /// <returns>uuid[;endpoint[;name]]</returns> 1980 /// <returns>uuid[;homeURI[;first last]]</returns>
1910 public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit) 1981 public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
1911 { 1982 {
1912 if (acircuit.ServiceURLs.ContainsKey("HomeURI")) 1983 if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
1984 return UniversalIdentifier(acircuit.AgentID, acircuit.firstname, acircuit.lastname, acircuit.ServiceURLs["HomeURI"].ToString());
1985 else
1986 return acircuit.AgentID.ToString();
1987 }
1988
1989 /// <summary>
1990 /// Produces a universal (HG) system-facing identifier given the information
1991 /// </summary>
1992 /// <param name="id">UUID of the user</param>
1993 /// <param name="firstName">first name (e.g Test)</param>
1994 /// <param name="lastName">last name (e.g. User)</param>
1995 /// <param name="homeURI">homeURI (e.g. http://foo.com)</param>
1996 /// <returns>a string of the form uuid[;homeURI[;first last]]</returns>
1997 public static string UniversalIdentifier(UUID id, String firstName, String lastName, String homeURI)
1998 {
1999 string agentsURI = homeURI;
2000 if (!agentsURI.EndsWith("/"))
2001 agentsURI += "/";
2002
2003 // This is ugly, but there's no other way, given that the name is changed
2004 // in the agent circuit data for foreigners
2005 if (lastName.Contains("@"))
1913 { 2006 {
1914 string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString(); 2007 string[] parts = firstName.Split(new char[] { '.' });
1915 if (!agentsURI.EndsWith("/")) 2008 if (parts.Length == 2)
1916 agentsURI += "/"; 2009 return id.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
2010 }
2011 return id.ToString() + ";" + agentsURI + ";" + firstName + " " + lastName;
1917 2012
1918 // This is ugly, but there's no other way, given that the name is changed 2013 }
1919 // in the agent circuit data for foreigners 2014
1920 if (acircuit.lastname.Contains("@")) 2015 /// <summary>
1921 { 2016 /// Produces a universal (HG) user-facing name given the information
1922 string[] parts = acircuit.firstname.Split(new char[] { '.' }); 2017 /// </summary>
1923 if (parts.Length == 2) 2018 /// <param name="firstName"></param>
1924 return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1]; 2019 /// <param name="lastName"></param>
1925 } 2020 /// <param name="homeURI"></param>
1926 return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname; 2021 /// <returns>string of the form first.last @foo.com or first last</returns>
2022 public static string UniversalName(String firstName, String lastName, String homeURI)
2023 {
2024 Uri uri = null;
2025 try
2026 {
2027 uri = new Uri(homeURI);
1927 } 2028 }
1928 else 2029 catch (UriFormatException)
1929 return acircuit.AgentID.ToString(); 2030 {
1930 } 2031 return firstName + " " + lastName;
2032 }
2033 return firstName + "." + lastName + " " + "@" + uri.Authority;
2034 }
1931 #endregion 2035 #endregion
1932 } 2036 }
1933} 2037}