diff options
Diffstat (limited to 'OpenSim/Framework/Util.cs')
-rw-r--r-- | OpenSim/Framework/Util.cs | 230 |
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; | |||
35 | using System.IO.Compression; | 35 | using System.IO.Compression; |
36 | using System.Net; | 36 | using System.Net; |
37 | using System.Net.Sockets; | 37 | using System.Net.Sockets; |
38 | using System.Reflection; | 38 | using System.Reflection; |
39 | using System.Runtime.InteropServices; | 39 | using System.Runtime.InteropServices; |
40 | using System.Runtime.Serialization; | 40 | using System.Runtime.Serialization; |
41 | using System.Runtime.Serialization.Formatters.Binary; | 41 | using 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 | } |