From 32ccd5bb40447ea4d96f1181cf73edff3645a55a Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Wed, 21 Oct 2009 23:03:18 -0700 Subject: * 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 --- OpenSim/Framework/Communications/RestClient.cs | 2 +- OpenSim/Framework/Parallel.cs | 6 +-- OpenSim/Framework/Util.cs | 70 +++++++++++++++++++------- 3 files changed, 55 insertions(+), 23 deletions(-) (limited to 'OpenSim/Framework') 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 /// In case, we are invoked asynchroneously this object will keep track of the state /// AsyncResult ar = new AsyncResult(callback, state); - ThreadPool.UnsafeQueueUserWorkItem(RequestHelper, ar); + Util.FireAndForget(RequestHelper, ar); return ar; } 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 for (int i = 0; i < threadCount; i++) { - ThreadPool.UnsafeQueueUserWorkItem( + Util.FireAndForget( delegate(object o) { int threadIndex = (int)o; @@ -122,7 +122,7 @@ namespace OpenSim.Framework for (int i = 0; i < threadCount; i++) { - ThreadPool.UnsafeQueueUserWorkItem( + Util.FireAndForget( delegate(object o) { int threadIndex = (int)o; @@ -178,7 +178,7 @@ namespace OpenSim.Framework for (int i = 0; i < threadCount; i++) { - ThreadPool.UnsafeQueueUserWorkItem( + Util.FireAndForget( delegate(object o) { 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; namespace OpenSim.Framework { /// + /// The method used by Util.FireAndForget for asynchronously firing events + /// + public enum FireAndForgetMethod + { + UnsafeQueueUserWorkItem, + QueueUserWorkItem, + BeginInvoke, + SmartThreadPool, + Thread, + } + + /// /// Miscellaneous utility functions /// public class Util @@ -70,7 +82,9 @@ namespace OpenSim.Framework public static readonly Regex UUIDPattern = 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}$"); - + + public static FireAndForgetMethod FireAndForgetMethod = FireAndForgetMethod.UnsafeQueueUserWorkItem; + /// /// Linear interpolates B<->C using percent A /// @@ -1273,7 +1287,7 @@ namespace OpenSim.Framework /// /// Created to work around a limitation in Mono with nested delegates /// - /*private class FireAndForgetWrapper + private class FireAndForgetWrapper { public void FireAndForget(System.Threading.WaitCallback callback) { @@ -1284,32 +1298,50 @@ namespace OpenSim.Framework { callback.BeginInvoke(obj, EndFireAndForget, callback); } - }*/ + + private static void EndFireAndForget(IAsyncResult ar) + { + System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState; + + try { callback.EndInvoke(ar); } + catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); } + + ar.AsyncWaitHandle.Close(); + } + } public static void FireAndForget(System.Threading.WaitCallback callback) { - //FireAndForgetWrapper wrapper = Singleton.GetInstance(); - //wrapper.FireAndForget(callback); - System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, null); + FireAndForget(callback, null); } public static void FireAndForget(System.Threading.WaitCallback callback, object obj) { - //FireAndForgetWrapper wrapper = Singleton.GetInstance(); - //wrapper.FireAndForget(callback, obj); - System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, obj); + switch (FireAndForgetMethod) + { + case FireAndForgetMethod.UnsafeQueueUserWorkItem: + System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, obj); + break; + case FireAndForgetMethod.QueueUserWorkItem: + System.Threading.ThreadPool.QueueUserWorkItem(callback, obj); + break; + case FireAndForgetMethod.BeginInvoke: + FireAndForgetWrapper wrapper = Singleton.GetInstance(); + wrapper.FireAndForget(callback, obj); + break; + case FireAndForgetMethod.SmartThreadPool: + Amib.Threading.SmartThreadPool stp = Singleton.GetInstance(); + stp.QueueWorkItem(delegate(object o) { callback(o); return null; }, obj); + break; + case FireAndForgetMethod.Thread: + System.Threading.Thread thread = new System.Threading.Thread(delegate(object o) { callback(o); }); + thread.Start(obj); + break; + default: + throw new NotImplementedException(); + } } - /*private static void EndFireAndForget(IAsyncResult ar) - { - System.Threading.WaitCallback callback = (System.Threading.WaitCallback)ar.AsyncState; - - try { callback.EndInvoke(ar); } - catch (Exception ex) { m_log.Error("[UTIL]: Asynchronous method threw an exception: " + ex.Message, ex); } - - ar.AsyncWaitHandle.Close(); - }*/ - #endregion FireAndForget Threading Pattern } } -- cgit v1.1