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.cs93
1 files changed, 83 insertions, 10 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 38729c6..d09bd6d 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -41,19 +41,36 @@ using System.Security.Cryptography;
41using System.Text; 41using System.Text;
42using System.Text.RegularExpressions; 42using System.Text.RegularExpressions;
43using System.Xml; 43using System.Xml;
44using System.Threading;
44using log4net; 45using log4net;
45using Nini.Config; 46using Nini.Config;
46using Nwc.XmlRpc; 47using Nwc.XmlRpc;
48using BclExtras;
47using OpenMetaverse; 49using OpenMetaverse;
48using OpenMetaverse.StructuredData; 50using OpenMetaverse.StructuredData;
51using Amib.Threading;
49 52
50namespace OpenSim.Framework 53namespace OpenSim.Framework
51{ 54{
52 /// <summary> 55 /// <summary>
56 /// The method used by Util.FireAndForget for asynchronously firing events
57 /// </summary>
58 public enum FireAndForgetMethod
59 {
60 UnsafeQueueUserWorkItem,
61 QueueUserWorkItem,
62 BeginInvoke,
63 SmartThreadPool,
64 Thread,
65 }
66
67 /// <summary>
53 /// Miscellaneous utility functions 68 /// Miscellaneous utility functions
54 /// </summary> 69 /// </summary>
55 public class Util 70 public class Util
56 { 71 {
72 private static SmartThreadPool m_ThreadPool = null;
73
57 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 74 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
58 75
59 private static uint nextXferID = 5000; 76 private static uint nextXferID = 5000;
@@ -69,7 +86,9 @@ namespace OpenSim.Framework
69 86
70 public static readonly Regex UUIDPattern 87 public static readonly Regex UUIDPattern
71 = new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"); 88 = new Regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$");
72 89
90 public static FireAndForgetMethod FireAndForgetMethod = FireAndForgetMethod.SmartThreadPool;
91
73 /// <summary> 92 /// <summary>
74 /// Linear interpolates B<->C using percent A 93 /// Linear interpolates B<->C using percent A
75 /// </summary> 94 /// </summary>
@@ -1269,24 +1288,78 @@ namespace OpenSim.Framework
1269 1288
1270 #region FireAndForget Threading Pattern 1289 #region FireAndForget Threading Pattern
1271 1290
1272 public static void FireAndForget(System.Threading.WaitCallback callback) 1291 /// <summary>
1292 /// Created to work around a limitation in Mono with nested delegates
1293 /// </summary>
1294 private class FireAndForgetWrapper
1273 { 1295 {
1274 callback.BeginInvoke(null, EndFireAndForget, callback); 1296 public void FireAndForget(System.Threading.WaitCallback callback)
1297 {
1298 callback.BeginInvoke(null, EndFireAndForget, callback);
1299 }
1300
1301 public void FireAndForget(System.Threading.WaitCallback callback, object obj)
1302 {
1303 callback.BeginInvoke(obj, EndFireAndForget, callback);
1304 }
1305
1306 private static void EndFireAndForget(IAsyncResult ar)
1307 {
1308 System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState;
1309
1310 try { callback.EndInvoke(ar); }
1311 catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); }
1312
1313 ar.AsyncWaitHandle.Close();
1314 }
1275 } 1315 }
1276 1316
1277 public static void FireAndForget(System.Threading.WaitCallback callback, object obj) 1317 public static void FireAndForget(System.Threading.WaitCallback callback)
1278 { 1318 {
1279 callback.BeginInvoke(obj, EndFireAndForget, callback); 1319 FireAndForget(callback, null);
1280 } 1320 }
1281 1321
1282 private static void EndFireAndForget(IAsyncResult ar) 1322 public static void SetMaxThreads(int maxThreads)
1283 { 1323 {
1284 System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState; 1324 if (m_ThreadPool != null)
1325 return;
1326
1327 STPStartInfo startInfo = new STPStartInfo();
1328 startInfo.IdleTimeout = 2000; // 2 seconds
1329 startInfo.MaxWorkerThreads = maxThreads;
1330 startInfo.MinWorkerThreads = 2;
1331 startInfo.StackSize = 524288;
1332 startInfo.ThreadPriority = ThreadPriority.Normal;
1285 1333
1286 try { callback.EndInvoke(ar); } 1334 startInfo.StartSuspended = false;
1287 catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); } 1335
1336 m_ThreadPool = new SmartThreadPool(startInfo);
1337 }
1288 1338
1289 ar.AsyncWaitHandle.Close(); 1339 public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
1340 {
1341 switch (FireAndForgetMethod)
1342 {
1343 case FireAndForgetMethod.UnsafeQueueUserWorkItem:
1344 System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, obj);
1345 break;
1346 case FireAndForgetMethod.QueueUserWorkItem:
1347 System.Threading.ThreadPool.QueueUserWorkItem(callback, obj);
1348 break;
1349 case FireAndForgetMethod.BeginInvoke:
1350 FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>();
1351 wrapper.FireAndForget(callback, obj);
1352 break;
1353 case FireAndForgetMethod.SmartThreadPool:
1354 m_ThreadPool.QueueWorkItem(delegate(object o) { callback(o); return null; }, obj);
1355 break;
1356 case FireAndForgetMethod.Thread:
1357 System.Threading.Thread thread = new System.Threading.Thread(delegate(object o) { callback(o); });
1358 thread.Start(obj);
1359 break;
1360 default:
1361 throw new NotImplementedException();
1362 }
1290 } 1363 }
1291 1364
1292 #endregion FireAndForget Threading Pattern 1365 #endregion FireAndForget Threading Pattern