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.cs278
1 files changed, 267 insertions, 11 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index e76a37b..557f38e 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -45,6 +45,7 @@ using System.Text.RegularExpressions;
45using System.Xml; 45using System.Xml;
46using System.Threading; 46using System.Threading;
47using log4net; 47using log4net;
48using log4net.Appender;
48using Nini.Config; 49using Nini.Config;
49using Nwc.XmlRpc; 50using Nwc.XmlRpc;
50using OpenMetaverse; 51using OpenMetaverse;
@@ -53,6 +54,21 @@ using Amib.Threading;
53 54
54namespace OpenSim.Framework 55namespace OpenSim.Framework
55{ 56{
57 [Flags]
58 public enum PermissionMask : uint
59 {
60 None = 0,
61 Transfer = 1 << 13,
62 Modify = 1 << 14,
63 Copy = 1 << 15,
64 Export = 1 << 16,
65 Move = 1 << 19,
66 Damage = 1 << 20,
67 // All does not contain Export, which is special and must be
68 // explicitly given
69 All = (1 << 13) | (1 << 14) | (1 << 15) | (1 << 19)
70 }
71
56 /// <summary> 72 /// <summary>
57 /// The method used by Util.FireAndForget for asynchronously firing events 73 /// The method used by Util.FireAndForget for asynchronously firing events
58 /// </summary> 74 /// </summary>
@@ -299,6 +315,25 @@ namespace OpenSim.Framework
299 x; 315 x;
300 } 316 }
301 317
318 // Clamp the maximum magnitude of a vector
319 public static Vector3 ClampV(Vector3 x, float max)
320 {
321 float lenSq = x.LengthSquared();
322 if (lenSq > (max * max))
323 {
324 x = x / x.Length() * max;
325 }
326
327 return x;
328 }
329
330 // Inclusive, within range test (true if equal to the endpoints)
331 public static bool InRange<T>(T x, T min, T max)
332 where T : IComparable<T>
333 {
334 return x.CompareTo(max) <= 0 && x.CompareTo(min) >= 0;
335 }
336
302 public static uint GetNextXferID() 337 public static uint GetNextXferID()
303 { 338 {
304 uint id = 0; 339 uint id = 0;
@@ -809,9 +844,22 @@ namespace OpenSim.Framework
809 return "."; 844 return ".";
810 } 845 }
811 846
847 public static string logFile()
848 {
849 foreach (IAppender appender in LogManager.GetRepository().GetAppenders())
850 {
851 if (appender is FileAppender)
852 {
853 return ((FileAppender)appender).File;
854 }
855 }
856
857 return "./OpenSim.log";
858 }
859
812 public static string logDir() 860 public static string logDir()
813 { 861 {
814 return "."; 862 return Path.GetDirectoryName(logFile());
815 } 863 }
816 864
817 // From: http://coercedcode.blogspot.com/2008/03/c-generate-unique-filenames-within.html 865 // From: http://coercedcode.blogspot.com/2008/03/c-generate-unique-filenames-within.html
@@ -842,7 +890,7 @@ namespace OpenSim.Framework
842 return FileName; 890 return FileName;
843 } 891 }
844 892
845 // Nini (config) related Methods 893 #region Nini (config) related Methods
846 public static IConfigSource ConvertDataRowToXMLConfig(DataRow row, string fileName) 894 public static IConfigSource ConvertDataRowToXMLConfig(DataRow row, string fileName)
847 { 895 {
848 if (!File.Exists(fileName)) 896 if (!File.Exists(fileName))
@@ -865,6 +913,79 @@ namespace OpenSim.Framework
865 } 913 }
866 } 914 }
867 915
916 public static string GetConfigVarWithDefaultSection(IConfigSource config, string varname, string section)
917 {
918 // First, check the Startup section, the default section
919 IConfig cnf = config.Configs["Startup"];
920 if (cnf == null)
921 return string.Empty;
922 string val = cnf.GetString(varname, string.Empty);
923
924 // Then check for an overwrite of the default in the given section
925 if (!string.IsNullOrEmpty(section))
926 {
927 cnf = config.Configs[section];
928 if (cnf != null)
929 val = cnf.GetString(varname, val);
930 }
931
932 return val;
933 }
934
935 /// <summary>
936 /// Gets the value of a configuration variable by looking into
937 /// multiple sections in order. The latter sections overwrite
938 /// any values previously found.
939 /// </summary>
940 /// <typeparam name="T">Type of the variable</typeparam>
941 /// <param name="config">The configuration object</param>
942 /// <param name="varname">The configuration variable</param>
943 /// <param name="sections">Ordered sequence of sections to look at</param>
944 /// <returns></returns>
945 public static T GetConfigVarFromSections<T>(IConfigSource config, string varname, string[] sections)
946 {
947 return GetConfigVarFromSections<T>(config, varname, sections, default(T));
948 }
949
950 /// <summary>
951 /// Gets the value of a configuration variable by looking into
952 /// multiple sections in order. The latter sections overwrite
953 /// any values previously found.
954 /// </summary>
955 /// <remarks>
956 /// If no value is found then the given default value is returned
957 /// </remarks>
958 /// <typeparam name="T">Type of the variable</typeparam>
959 /// <param name="config">The configuration object</param>
960 /// <param name="varname">The configuration variable</param>
961 /// <param name="sections">Ordered sequence of sections to look at</param>
962 /// <param name="val">Default value</param>
963 /// <returns></returns>
964 public static T GetConfigVarFromSections<T>(IConfigSource config, string varname, string[] sections, object val)
965 {
966 foreach (string section in sections)
967 {
968 IConfig cnf = config.Configs[section];
969 if (cnf == null)
970 continue;
971
972 if (typeof(T) == typeof(String))
973 val = cnf.GetString(varname, (string)val);
974 else if (typeof(T) == typeof(Boolean))
975 val = cnf.GetBoolean(varname, (bool)val);
976 else if (typeof(T) == typeof(Int32))
977 val = cnf.GetInt(varname, (int)val);
978 else if (typeof(T) == typeof(float))
979 val = cnf.GetFloat(varname, (int)val);
980 else
981 m_log.ErrorFormat("[UTIL]: Unhandled type {0}", typeof(T));
982 }
983
984 return (T)val;
985 }
986
987 #endregion
988
868 public static float Clip(float x, float min, float max) 989 public static float Clip(float x, float min, float max)
869 { 990 {
870 return Math.Min(Math.Max(x, min), max); 991 return Math.Min(Math.Max(x, min), max);
@@ -1651,7 +1772,13 @@ namespace OpenSim.Framework
1651 if (m_ThreadPool != null) 1772 if (m_ThreadPool != null)
1652 throw new InvalidOperationException("SmartThreadPool is already initialized"); 1773 throw new InvalidOperationException("SmartThreadPool is already initialized");
1653 1774
1654 m_ThreadPool = new SmartThreadPool(2000, maxThreads, 2); 1775 STPStartInfo startInfo = new STPStartInfo();
1776 startInfo.ThreadPoolName = "Util";
1777 startInfo.IdleTimeout = 2000;
1778 startInfo.MaxWorkerThreads = maxThreads;
1779 startInfo.MinWorkerThreads = 2;
1780
1781 m_ThreadPool = new SmartThreadPool(startInfo);
1655 } 1782 }
1656 1783
1657 public static int FireAndForgetCount() 1784 public static int FireAndForgetCount()
@@ -1724,7 +1851,7 @@ namespace OpenSim.Framework
1724 break; 1851 break;
1725 case FireAndForgetMethod.SmartThreadPool: 1852 case FireAndForgetMethod.SmartThreadPool:
1726 if (m_ThreadPool == null) 1853 if (m_ThreadPool == null)
1727 m_ThreadPool = new SmartThreadPool(2000, 15, 2); 1854 InitThreadPool(15);
1728 m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { realCallback, obj }); 1855 m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { realCallback, obj });
1729 break; 1856 break;
1730 case FireAndForgetMethod.Thread: 1857 case FireAndForgetMethod.Thread:
@@ -1753,12 +1880,16 @@ namespace OpenSim.Framework
1753 StringBuilder sb = new StringBuilder(); 1880 StringBuilder sb = new StringBuilder();
1754 if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool) 1881 if (FireAndForgetMethod == FireAndForgetMethod.SmartThreadPool)
1755 { 1882 {
1756 threadPoolUsed = "SmartThreadPool"; 1883 // ROBUST currently leaves this the FireAndForgetMethod but never actually initializes the threadpool.
1757 maxThreads = m_ThreadPool.MaxThreads; 1884 if (m_ThreadPool != null)
1758 minThreads = m_ThreadPool.MinThreads; 1885 {
1759 inUseThreads = m_ThreadPool.InUseThreads; 1886 threadPoolUsed = "SmartThreadPool";
1760 allocatedThreads = m_ThreadPool.ActiveThreads; 1887 maxThreads = m_ThreadPool.MaxThreads;
1761 waitingCallbacks = m_ThreadPool.WaitingCallbacks; 1888 minThreads = m_ThreadPool.MinThreads;
1889 inUseThreads = m_ThreadPool.InUseThreads;
1890 allocatedThreads = m_ThreadPool.ActiveThreads;
1891 waitingCallbacks = m_ThreadPool.WaitingCallbacks;
1892 }
1762 } 1893 }
1763 else if ( 1894 else if (
1764 FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem 1895 FireAndForgetMethod == FireAndForgetMethod.UnsafeQueueUserWorkItem
@@ -1863,6 +1994,12 @@ namespace OpenSim.Framework
1863 /// </summary> 1994 /// </summary>
1864 public static void PrintCallStack() 1995 public static void PrintCallStack()
1865 { 1996 {
1997 PrintCallStack(m_log.DebugFormat);
1998 }
1999
2000 public delegate void DebugPrinter(string msg, params Object[] parm);
2001 public static void PrintCallStack(DebugPrinter printer)
2002 {
1866 StackTrace stackTrace = new StackTrace(true); // get call stack 2003 StackTrace stackTrace = new StackTrace(true); // get call stack
1867 StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) 2004 StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
1868 2005
@@ -1870,7 +2007,7 @@ namespace OpenSim.Framework
1870 foreach (StackFrame stackFrame in stackFrames) 2007 foreach (StackFrame stackFrame in stackFrames)
1871 { 2008 {
1872 MethodBase mb = stackFrame.GetMethod(); 2009 MethodBase mb = stackFrame.GetMethod();
1873 m_log.DebugFormat("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name 2010 printer("{0}.{1}:{2}", mb.DeclaringType, mb.Name, stackFrame.GetFileLineNumber()); // write method name
1874 } 2011 }
1875 } 2012 }
1876 2013
@@ -2096,5 +2233,124 @@ namespace OpenSim.Framework
2096 return firstName + "." + lastName + " " + "@" + uri.Authority; 2233 return firstName + "." + lastName + " " + "@" + uri.Authority;
2097 } 2234 }
2098 #endregion 2235 #endregion
2236
2237 /// <summary>
2238 /// Escapes the special characters used in "LIKE".
2239 /// </summary>
2240 /// <remarks>
2241 /// For example: EscapeForLike("foo_bar%baz") = "foo\_bar\%baz"
2242 /// </remarks>
2243 public static string EscapeForLike(string str)
2244 {
2245 return str.Replace("_", "\\_").Replace("%", "\\%");
2246 }
2247 }
2248
2249 public class DoubleQueue<T> where T:class
2250 {
2251 private Queue<T> m_lowQueue = new Queue<T>();
2252 private Queue<T> m_highQueue = new Queue<T>();
2253
2254 private object m_syncRoot = new object();
2255 private Semaphore m_s = new Semaphore(0, 1);
2256
2257 public DoubleQueue()
2258 {
2259 }
2260
2261 public virtual int Count
2262 {
2263 get { return m_highQueue.Count + m_lowQueue.Count; }
2264 }
2265
2266 public virtual void Enqueue(T data)
2267 {
2268 Enqueue(m_lowQueue, data);
2269 }
2270
2271 public virtual void EnqueueLow(T data)
2272 {
2273 Enqueue(m_lowQueue, data);
2274 }
2275
2276 public virtual void EnqueueHigh(T data)
2277 {
2278 Enqueue(m_highQueue, data);
2279 }
2280
2281 private void Enqueue(Queue<T> q, T data)
2282 {
2283 lock (m_syncRoot)
2284 {
2285 m_lowQueue.Enqueue(data);
2286 m_s.WaitOne(0);
2287 m_s.Release();
2288 }
2289 }
2290
2291 public virtual T Dequeue()
2292 {
2293 return Dequeue(Timeout.Infinite);
2294 }
2295
2296 public virtual T Dequeue(int tmo)
2297 {
2298 return Dequeue(TimeSpan.FromMilliseconds(tmo));
2299 }
2300
2301 public virtual T Dequeue(TimeSpan wait)
2302 {
2303 T res = null;
2304
2305 if (!Dequeue(wait, ref res))
2306 return null;
2307
2308 return res;
2309 }
2310
2311 public bool Dequeue(int timeout, ref T res)
2312 {
2313 return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res);
2314 }
2315
2316 public bool Dequeue(TimeSpan wait, ref T res)
2317 {
2318 if (!m_s.WaitOne(wait))
2319 return false;
2320
2321 lock (m_syncRoot)
2322 {
2323 if (m_highQueue.Count > 0)
2324 res = m_highQueue.Dequeue();
2325 else
2326 res = m_lowQueue.Dequeue();
2327
2328 if (m_highQueue.Count == 0 && m_lowQueue.Count == 0)
2329 return true;
2330
2331 try
2332 {
2333 m_s.Release();
2334 }
2335 catch
2336 {
2337 }
2338
2339 return true;
2340 }
2341 }
2342
2343 public virtual void Clear()
2344 {
2345
2346 lock (m_syncRoot)
2347 {
2348 // Make sure sem count is 0
2349 m_s.WaitOne(0);
2350
2351 m_lowQueue.Clear();
2352 m_highQueue.Clear();
2353 }
2354 }
2099 } 2355 }
2100} 2356}