aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJohn Hurliman2009-10-21 23:03:18 -0700
committerJohn Hurliman2009-10-21 23:03:18 -0700
commit32ccd5bb40447ea4d96f1181cf73edff3645a55a (patch)
tree65a6f75985e9aef1a9641c098332823d10afb748
parent* Change the OnQueueEmpty signature to send the flags of the queues that are ... (diff)
downloadopensim-SC-32ccd5bb40447ea4d96f1181cf73edff3645a55a.zip
opensim-SC-32ccd5bb40447ea4d96f1181cf73edff3645a55a.tar.gz
opensim-SC-32ccd5bb40447ea4d96f1181cf73edff3645a55a.tar.bz2
opensim-SC-32ccd5bb40447ea4d96f1181cf73edff3645a55a.tar.xz
* Changed the misc. methods calling ThreadPool.UnsafeQueueUserWorkItem() to Util.FireAndForget()
* Changed Util.FireAndForget() to use any of five different methods set with async_call_method in the [Startup] section of OpenSim.ini. Look at the example config for possible values
-rw-r--r--OpenSim/Framework/Communications/RestClient.cs2
-rw-r--r--OpenSim/Framework/Parallel.cs6
-rw-r--r--OpenSim/Framework/Util.cs70
-rw-r--r--OpenSim/Grid/MessagingServer.Modules/MessageService.cs3
-rw-r--r--OpenSim/Region/Application/OpenSim.cs9
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs6
-rw-r--r--OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs8
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs2
-rw-r--r--bin/OpenSim.ini.example9
9 files changed, 79 insertions, 36 deletions
diff --git a/OpenSim/Framework/Communications/RestClient.cs b/OpenSim/Framework/Communications/RestClient.cs
index 317b3a0..97b3b60 100644
--- a/OpenSim/Framework/Communications/RestClient.cs
+++ b/OpenSim/Framework/Communications/RestClient.cs
@@ -403,7 +403,7 @@ namespace OpenSim.Framework.Communications
403 /// In case, we are invoked asynchroneously this object will keep track of the state 403 /// In case, we are invoked asynchroneously this object will keep track of the state
404 /// </summary> 404 /// </summary>
405 AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state); 405 AsyncResult<Stream> ar = new AsyncResult<Stream>(callback, state);
406 ThreadPool.UnsafeQueueUserWorkItem(RequestHelper, ar); 406 Util.FireAndForget(RequestHelper, ar);
407 return ar; 407 return ar;
408 } 408 }
409 409
diff --git a/OpenSim/Framework/Parallel.cs b/OpenSim/Framework/Parallel.cs
index ab2e108..70eecdc 100644
--- a/OpenSim/Framework/Parallel.cs
+++ b/OpenSim/Framework/Parallel.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Framework
66 66
67 for (int i = 0; i < threadCount; i++) 67 for (int i = 0; i < threadCount; i++)
68 { 68 {
69 ThreadPool.UnsafeQueueUserWorkItem( 69 Util.FireAndForget(
70 delegate(object o) 70 delegate(object o)
71 { 71 {
72 int threadIndex = (int)o; 72 int threadIndex = (int)o;
@@ -122,7 +122,7 @@ namespace OpenSim.Framework
122 122
123 for (int i = 0; i < threadCount; i++) 123 for (int i = 0; i < threadCount; i++)
124 { 124 {
125 ThreadPool.UnsafeQueueUserWorkItem( 125 Util.FireAndForget(
126 delegate(object o) 126 delegate(object o)
127 { 127 {
128 int threadIndex = (int)o; 128 int threadIndex = (int)o;
@@ -178,7 +178,7 @@ namespace OpenSim.Framework
178 178
179 for (int i = 0; i < threadCount; i++) 179 for (int i = 0; i < threadCount; i++)
180 { 180 {
181 ThreadPool.UnsafeQueueUserWorkItem( 181 Util.FireAndForget(
182 delegate(object o) 182 delegate(object o)
183 { 183 {
184 int threadIndex = (int)o; 184 int threadIndex = (int)o;
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index d5ae3b7..02f6d12 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -51,6 +51,18 @@ using OpenMetaverse.StructuredData;
51namespace OpenSim.Framework 51namespace OpenSim.Framework
52{ 52{
53 /// <summary> 53 /// <summary>
54 /// The method used by Util.FireAndForget for asynchronously firing events
55 /// </summary>
56 public enum FireAndForgetMethod
57 {
58 UnsafeQueueUserWorkItem,
59 QueueUserWorkItem,
60 BeginInvoke,
61 SmartThreadPool,
62 Thread,
63 }
64
65 /// <summary>
54 /// Miscellaneous utility functions 66 /// Miscellaneous utility functions
55 /// </summary> 67 /// </summary>
56 public class Util 68 public class Util
@@ -70,7 +82,9 @@ namespace OpenSim.Framework
70 82
71 public static readonly Regex UUIDPattern 83 public static readonly Regex UUIDPattern
72 = 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}$"); 84 = 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}$");
73 85
86 public static FireAndForgetMethod FireAndForgetMethod = FireAndForgetMethod.UnsafeQueueUserWorkItem;
87
74 /// <summary> 88 /// <summary>
75 /// Linear interpolates B<->C using percent A 89 /// Linear interpolates B<->C using percent A
76 /// </summary> 90 /// </summary>
@@ -1273,7 +1287,7 @@ namespace OpenSim.Framework
1273 /// <summary> 1287 /// <summary>
1274 /// Created to work around a limitation in Mono with nested delegates 1288 /// Created to work around a limitation in Mono with nested delegates
1275 /// </summary> 1289 /// </summary>
1276 /*private class FireAndForgetWrapper 1290 private class FireAndForgetWrapper
1277 { 1291 {
1278 public void FireAndForget(System.Threading.WaitCallback callback) 1292 public void FireAndForget(System.Threading.WaitCallback callback)
1279 { 1293 {
@@ -1284,32 +1298,50 @@ namespace OpenSim.Framework
1284 { 1298 {
1285 callback.BeginInvoke(obj, EndFireAndForget, callback); 1299 callback.BeginInvoke(obj, EndFireAndForget, callback);
1286 } 1300 }
1287 }*/ 1301
1302 private static void EndFireAndForget(IAsyncResult ar)
1303 {
1304 System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState;
1305
1306 try { callback.EndInvoke(ar); }
1307 catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); }
1308
1309 ar.AsyncWaitHandle.Close();
1310 }
1311 }
1288 1312
1289 public static void FireAndForget(System.Threading.WaitCallback callback) 1313 public static void FireAndForget(System.Threading.WaitCallback callback)
1290 { 1314 {
1291 //FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>(); 1315 FireAndForget(callback, null);
1292 //wrapper.FireAndForget(callback);
1293 System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, null);
1294 } 1316 }
1295 1317
1296 public static void FireAndForget(System.Threading.WaitCallback callback, object obj) 1318 public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
1297 { 1319 {
1298 //FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>(); 1320 switch (FireAndForgetMethod)
1299 //wrapper.FireAndForget(callback, obj); 1321 {
1300 System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, obj); 1322 case FireAndForgetMethod.UnsafeQueueUserWorkItem:
1323 System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, obj);
1324 break;
1325 case FireAndForgetMethod.QueueUserWorkItem:
1326 System.Threading.ThreadPool.QueueUserWorkItem(callback, obj);
1327 break;
1328 case FireAndForgetMethod.BeginInvoke:
1329 FireAndForgetWrapper wrapper = Singleton.GetInstance<FireAndForgetWrapper>();
1330 wrapper.FireAndForget(callback, obj);
1331 break;
1332 case FireAndForgetMethod.SmartThreadPool:
1333 Amib.Threading.SmartThreadPool stp = Singleton.GetInstance<Amib.Threading.SmartThreadPool>();
1334 stp.QueueWorkItem(delegate(object o) { callback(o); return null; }, obj);
1335 break;
1336 case FireAndForgetMethod.Thread:
1337 System.Threading.Thread thread = new System.Threading.Thread(delegate(object o) { callback(o); });
1338 thread.Start(obj);
1339 break;
1340 default:
1341 throw new NotImplementedException();
1342 }
1301 } 1343 }
1302 1344
1303 /*private static void EndFireAndForget(IAsyncResult ar)
1304 {
1305 System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState;
1306
1307 try { callback.EndInvoke(ar); }
1308 catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); }
1309
1310 ar.AsyncWaitHandle.Close();
1311 }*/
1312
1313 #endregion FireAndForget Threading Pattern 1345 #endregion FireAndForget Threading Pattern
1314 } 1346 }
1315} 1347}
diff --git a/OpenSim/Grid/MessagingServer.Modules/MessageService.cs b/OpenSim/Grid/MessagingServer.Modules/MessageService.cs
index 49f0fa8..8ad1e9c 100644
--- a/OpenSim/Grid/MessagingServer.Modules/MessageService.cs
+++ b/OpenSim/Grid/MessagingServer.Modules/MessageService.cs
@@ -148,8 +148,7 @@ namespace OpenSim.Grid.MessagingServer.Modules
148 friendlistupdater.presence2 = receiver; 148 friendlistupdater.presence2 = receiver;
149 friendlistupdater.OnGetRegionData += m_regionModule.GetRegionInfo; 149 friendlistupdater.OnGetRegionData += m_regionModule.GetRegionInfo;
150 friendlistupdater.OnDone += PresenceUpdateDone; 150 friendlistupdater.OnDone += PresenceUpdateDone;
151 WaitCallback cb = new WaitCallback(friendlistupdater.go); 151 Util.FireAndForget(friendlistupdater.go);
152 ThreadPool.UnsafeQueueUserWorkItem(cb, null);
153 } 152 }
154 else 153 else
155 { 154 {
diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs
index 143dd2a..5be1816 100644
--- a/OpenSim/Region/Application/OpenSim.cs
+++ b/OpenSim/Region/Application/OpenSim.cs
@@ -90,10 +90,17 @@ namespace OpenSim
90 appender.File = fileName; 90 appender.File = fileName;
91 appender.ActivateOptions(); 91 appender.ActivateOptions();
92 } 92 }
93 m_log.InfoFormat("[LOGGING] Logging started to file {0}", appender.File); 93 m_log.InfoFormat("[LOGGING]: Logging started to file {0}", appender.File);
94 } 94 }
95 } 95 }
96
97 string asyncCallMethodStr = startupConfig.GetString("async_call_method", String.Empty);
98 FireAndForgetMethod asyncCallMethod;
99 if (!String.IsNullOrEmpty(asyncCallMethodStr) && Utils.EnumTryParse<FireAndForgetMethod>(asyncCallMethodStr, out asyncCallMethod))
100 Util.FireAndForgetMethod = asyncCallMethod;
96 } 101 }
102
103 m_log.Info("[OPENSIM MAIN]: Using async_call_method " + Util.FireAndForgetMethod);
97 } 104 }
98 105
99 /// <summary> 106 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 432fee7..0ba76ec 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -791,7 +791,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
791 /// <param name="map">heightmap</param> 791 /// <param name="map">heightmap</param>
792 public virtual void SendLayerData(float[] map) 792 public virtual void SendLayerData(float[] map)
793 { 793 {
794 ThreadPool.UnsafeQueueUserWorkItem(DoSendLayerData, map); 794 Util.FireAndForget(DoSendLayerData, map);
795 } 795 }
796 796
797 /// <summary> 797 /// <summary>
@@ -931,7 +931,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
931 /// <param name="windSpeeds">16x16 array of wind speeds</param> 931 /// <param name="windSpeeds">16x16 array of wind speeds</param>
932 public virtual void SendWindData(Vector2[] windSpeeds) 932 public virtual void SendWindData(Vector2[] windSpeeds)
933 { 933 {
934 ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(DoSendWindData), (object)windSpeeds); 934 Util.FireAndForget(DoSendWindData, windSpeeds);
935 } 935 }
936 936
937 /// <summary> 937 /// <summary>
@@ -940,7 +940,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
940 /// <param name="windSpeeds">16x16 array of cloud densities</param> 940 /// <param name="windSpeeds">16x16 array of cloud densities</param>
941 public virtual void SendCloudData(float[] cloudDensity) 941 public virtual void SendCloudData(float[] cloudDensity)
942 { 942 {
943 ThreadPool.UnsafeQueueUserWorkItem(new WaitCallback(DoSendCloudData), (object)cloudDensity); 943 Util.FireAndForget(DoSendCloudData, cloudDensity);
944 } 944 }
945 945
946 /// <summary> 946 /// <summary>
diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
index cbdca16..c6af806 100644
--- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
+++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs
@@ -302,12 +302,8 @@ namespace Flotsam.RegionModules.AssetCache
302 302
303 } 303 }
304 304
305 ThreadPool.UnsafeQueueUserWorkItem( 305 Util.FireAndForget(
306 delegate 306 delegate { WriteFileCache(filename, asset); });
307 {
308 WriteFileCache(filename, asset);
309 }, null
310 );
311 } 307 }
312 } 308 }
313 catch (Exception e) 309 catch (Exception e)
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 1260584..4e40084 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -1095,7 +1095,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
1095 // The reason is so we don't cause the thread to freeze waiting 1095 // The reason is so we don't cause the thread to freeze waiting
1096 // for the 1 second it costs to start a thread manually. 1096 // for the 1 second it costs to start a thread manually.
1097 if (!threadrunning) 1097 if (!threadrunning)
1098 ThreadPool.UnsafeQueueUserWorkItem(this.StartThread, null); 1098 Util.FireAndForget(this.StartThread);
1099 1099
1100 lock (m_rootAgents) 1100 lock (m_rootAgents)
1101 { 1101 {
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 2d56f4e..35b08f9 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -31,6 +31,15 @@
31 31
32 ; To run a script every few minutes, set the script filename here 32 ; To run a script every few minutes, set the script filename here
33 ; timer_Script = "filename" 33 ; timer_Script = "filename"
34
35 ; ##
36 ; ## SYSTEM
37 ; ##
38
39 ; Sets the method that OpenSim will use to fire asynchronous
40 ; events. Valid values are UnsafeQueueUserWorkItem,
41 ; QueueUserWorkItem, BeginInvoke, SmartThreadPool, and Thread
42 async_call_method = UnsafeQueueUserWorkItem
34 43
35 ; ## 44 ; ##
36 ; ## CLIENTS 45 ; ## CLIENTS