diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 4a40a27e14..cf4e2b1cef 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -3142,7 +3142,7 @@ namespace OpenSim.Framework case FireAndForgetMethod.SmartThreadPool: if (m_ThreadPool == null) InitThreadPool(2, 15); - threadInfo.WorkItem = m_ThreadPool.QueueWorkItem((cb, o) => {cb(o); cb = null;}, realCallback, obj); + threadInfo.WorkItem = m_ThreadPool.QueueWorkItem(realCallback, obj); break; case FireAndForgetMethod.Thread: Thread thread = new Thread(delegate(object o) { realCallback(o); realCallback = null;}); diff --git a/ThirdParty/SmartThreadPool/WorkItem.cs b/ThirdParty/SmartThreadPool/WorkItem.cs index 141f4b1bab..7df3f580e2 100644 --- a/ThirdParty/SmartThreadPool/WorkItem.cs +++ b/ThirdParty/SmartThreadPool/WorkItem.cs @@ -54,7 +54,8 @@ namespace Amib.Threading.Internal /// /// Callback delegate for the callback. /// - private readonly WorkItemCallback _callback; + private WorkItemCallback _callback; + private WaitCallback _callbackNoResult; /// /// State with which to call the callback delegate. @@ -196,11 +197,7 @@ namespace Amib.Threading.Internal /// /// We assume that the WorkItem object is created within the thread /// that meant to run the callback - public WorkItem( - IWorkItemsGroup workItemsGroup, - WorkItemInfo workItemInfo, - WorkItemCallback callback, - object state) + public WorkItem(IWorkItemsGroup workItemsGroup, WorkItemInfo workItemInfo, WorkItemCallback callback, object state) { _workItemsGroup = workItemsGroup; _workItemInfo = workItemInfo; @@ -208,13 +205,34 @@ namespace Amib.Threading.Internal if (_workItemInfo.UseCallerCallContext && !ExecutionContext.IsFlowSuppressed()) { ExecutionContext ec = ExecutionContext.Capture(); - if(ec != null) - _callerContext = ec.CreateCopy(); + if (ec != null) + _callerContext = ec.CreateCopy(); ec.Dispose(); ec = null; } _callback = callback; + _callbackNoResult = null; + _state = state; + _workItemResult = new WorkItemResult(this); + Initialize(); + } + + public WorkItem(IWorkItemsGroup workItemsGroup, WorkItemInfo workItemInfo, WaitCallback callback, object state) + { + _workItemsGroup = workItemsGroup; + _workItemInfo = workItemInfo; + + if (_workItemInfo.UseCallerCallContext && !ExecutionContext.IsFlowSuppressed()) + { + ExecutionContext ec = ExecutionContext.Capture(); + if (ec != null) + _callerContext = ec.CreateCopy(); + ec.Dispose(); + ec = null; + } + + _callbackNoResult = callback; _state = state; _workItemResult = new WorkItemResult(this); Initialize(); @@ -358,16 +376,33 @@ namespace Amib.Threading.Internal { try { - if(_callerContext == null) - result = _callback(_state); + if(_callbackNoResult == null) + { + if(_callerContext == null) + result = _callback(_state); + else + { + ContextCallback _ccb = new ContextCallback( o => + { + result =_callback(o); + }); + + ExecutionContext.Run(_callerContext, _ccb, _state); + } + } else { - ContextCallback _ccb = new ContextCallback( o => + if (_callerContext == null) + _callbackNoResult(_state); + else { - result =_callback(o); - }); + ContextCallback _ccb = new ContextCallback(o => + { + _callbackNoResult(o); + }); - ExecutionContext.Run(_callerContext, _ccb, _state); + ExecutionContext.Run(_callerContext, _ccb, _state); + } } } catch (Exception e) @@ -977,6 +1012,8 @@ namespace Amib.Threading.Internal _state = null; } } + _callback = null; + _callbackNoResult = null; } } } diff --git a/ThirdParty/SmartThreadPool/WorkItemFactory.cs b/ThirdParty/SmartThreadPool/WorkItemFactory.cs index 6983a2a2e4..4bcf5efd84 100644 --- a/ThirdParty/SmartThreadPool/WorkItemFactory.cs +++ b/ThirdParty/SmartThreadPool/WorkItemFactory.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; namespace Amib.Threading.Internal { @@ -6,6 +7,44 @@ namespace Amib.Threading.Internal public class WorkItemFactory { + + public static WorkItem CreateWorkItem(IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, WorkItemInfo workItemInfo, + WaitCallback callback, object state) + { + ValidateCallback(callback); + ValidateCallback(workItemInfo.PostExecuteWorkItemCallback); + + WorkItem workItem = new WorkItem( + workItemsGroup, + new WorkItemInfo(workItemInfo), + callback, + state); + + return workItem; + } + + public static WorkItem CreateWorkItem(IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, + WaitCallback callback, object state) + { + ValidateCallback(callback); + + WorkItemInfo workItemInfo = new WorkItemInfo() + { + UseCallerCallContext = wigStartInfo.UseCallerCallContext, + PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback, + CallToPostExecute = wigStartInfo.CallToPostExecute, + DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects, + WorkItemPriority = wigStartInfo.WorkItemPriority + }; + + WorkItem workItem = new WorkItem( + workItemsGroup, + workItemInfo, + callback, + state); + return workItem; + } + /// /// Create a new work item /// @@ -13,10 +52,7 @@ namespace Amib.Threading.Internal /// Work item group start information /// A callback to execute /// Returns a work item - public static WorkItem CreateWorkItem( - IWorkItemsGroup workItemsGroup, - WIGStartInfo wigStartInfo, - WorkItemCallback callback) + public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, WorkItemCallback callback) { return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null); } @@ -29,11 +65,8 @@ namespace Amib.Threading.Internal /// A callback to execute /// The priority of the work item /// Returns a work item - public static WorkItem CreateWorkItem( - IWorkItemsGroup workItemsGroup, - WIGStartInfo wigStartInfo, - WorkItemCallback callback, - WorkItemPriority workItemPriority) + public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, + WorkItemCallback callback, WorkItemPriority workItemPriority) { return CreateWorkItem(workItemsGroup, wigStartInfo, callback, null, workItemPriority); } @@ -46,11 +79,8 @@ namespace Amib.Threading.Internal /// Work item info /// A callback to execute /// Returns a work item - public static WorkItem CreateWorkItem( - IWorkItemsGroup workItemsGroup, - WIGStartInfo wigStartInfo, - WorkItemInfo workItemInfo, - WorkItemCallback callback) + public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, + WorkItemInfo workItemInfo, WorkItemCallback callback) { return CreateWorkItem( workItemsGroup, @@ -70,20 +100,19 @@ namespace Amib.Threading.Internal /// The context object of the work item. Used for passing arguments to the work item. /// /// Returns a work item - public static WorkItem CreateWorkItem( - IWorkItemsGroup workItemsGroup, - WIGStartInfo wigStartInfo, - WorkItemCallback callback, - object state) + public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, + WorkItemCallback callback, object state) { ValidateCallback(callback); - WorkItemInfo workItemInfo = new WorkItemInfo(); - workItemInfo.UseCallerCallContext = wigStartInfo.UseCallerCallContext; - workItemInfo.PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback; - workItemInfo.CallToPostExecute = wigStartInfo.CallToPostExecute; - workItemInfo.DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects; - workItemInfo.WorkItemPriority = wigStartInfo.WorkItemPriority; + WorkItemInfo workItemInfo = new WorkItemInfo() + { + UseCallerCallContext = wigStartInfo.UseCallerCallContext, + PostExecuteWorkItemCallback = wigStartInfo.PostExecuteWorkItemCallback, + CallToPostExecute = wigStartInfo.CallToPostExecute, + DisposeOfStateObjects = wigStartInfo.DisposeOfStateObjects, + WorkItemPriority = wigStartInfo.WorkItemPriority + }; WorkItem workItem = new WorkItem( workItemsGroup, @@ -140,12 +169,8 @@ namespace Amib.Threading.Internal /// The context object of the work item. Used for passing arguments to the work item. /// /// Returns a work item - public static WorkItem CreateWorkItem( - IWorkItemsGroup workItemsGroup, - WIGStartInfo wigStartInfo, - WorkItemInfo workItemInfo, - WorkItemCallback callback, - object state) + public static WorkItem CreateWorkItem( IWorkItemsGroup workItemsGroup, WIGStartInfo wigStartInfo, WorkItemInfo workItemInfo, + WorkItemCallback callback, object state) { ValidateCallback(callback); ValidateCallback(workItemInfo.PostExecuteWorkItemCallback); diff --git a/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs b/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs index 27fae5e813..7e277f1c1d 100644 --- a/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs +++ b/ThirdParty/SmartThreadPool/WorkItemsGroupBase.cs @@ -87,6 +87,35 @@ namespace Amib.Threading.Internal #region QueueWorkItem + public IWorkItemResult QueueWorkItem(WaitCallback callback) + { + WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, null); + Enqueue(workItem); + return workItem.GetWorkItemResult(); + } + + public IWorkItemResult QueueWorkItem(WaitCallback callback, object state) + { + WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state); + Enqueue(workItem); + return workItem.GetWorkItemResult(); + } + + public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WaitCallback callback) + { + PreQueueWorkItem(); + WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, null); + Enqueue(workItem); + return workItem.GetWorkItemResult(); + } + + public IWorkItemResult QueueWorkItem(WorkItemInfo workItemInfo, WaitCallback callback, object state) + { + PreQueueWorkItem(); + WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, workItemInfo, callback, state); + Enqueue(workItem); + return workItem.GetWorkItemResult(); + } /// /// Queue a work item /// @@ -187,9 +216,7 @@ namespace Amib.Threading.Internal /// A delegate to call after the callback completion /// /// Returns a work item result - public IWorkItemResult QueueWorkItem( - WorkItemCallback callback, - object state, + public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback) { PreQueueWorkItem(); @@ -210,10 +237,7 @@ namespace Amib.Threading.Internal /// /// The work item priority /// Returns a work item result - public IWorkItemResult QueueWorkItem( - WorkItemCallback callback, - object state, - PostExecuteWorkItemCallback postExecuteWorkItemCallback, + public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state, PostExecuteWorkItemCallback postExecuteWorkItemCallback, WorkItemPriority workItemPriority) { PreQueueWorkItem(); @@ -234,11 +258,8 @@ namespace Amib.Threading.Internal /// /// Indicates on which cases to call to the post execute callback /// Returns a work item result - public IWorkItemResult QueueWorkItem( - WorkItemCallback callback, - object state, - PostExecuteWorkItemCallback postExecuteWorkItemCallback, - CallToPostExecute callToPostExecute) + public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state, + PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute) { PreQueueWorkItem(); WorkItem workItem = WorkItemFactory.CreateWorkItem(this, WIGStartInfo, callback, state, postExecuteWorkItemCallback, callToPostExecute); @@ -259,11 +280,8 @@ namespace Amib.Threading.Internal /// Indicates on which cases to call to the post execute callback /// The work item priority /// Returns a work item result - public IWorkItemResult QueueWorkItem( - WorkItemCallback callback, - object state, - PostExecuteWorkItemCallback postExecuteWorkItemCallback, - CallToPostExecute callToPostExecute, + public IWorkItemResult QueueWorkItem( WorkItemCallback callback, object state, + PostExecuteWorkItemCallback postExecuteWorkItemCallback, CallToPostExecute callToPostExecute, WorkItemPriority workItemPriority) { PreQueueWorkItem();