Pārlūkot izejas kodu

smartthreadpool: suport callback delegates with no return value (WaitCallBack), use it on our fireandforget (other places later)

UbitUmarov 3 gadi atpakaļ
vecāks
revīzija
b61df051db

+ 1 - 1
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;});

+ 51 - 14
ThirdParty/SmartThreadPool/WorkItem.cs

@@ -54,7 +54,8 @@ namespace Amib.Threading.Internal
         /// <summary>
         /// Callback delegate for the callback.
         /// </summary>
-        private readonly WorkItemCallback _callback;
+        private WorkItemCallback _callback;
+        private WaitCallback _callbackNoResult;
 
         /// <summary>
         /// 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;
         }
     }
 }

+ 56 - 31
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;
+        }
+
         /// <summary>
         /// Create a new work item
         /// </summary>
@@ -13,10 +52,7 @@ namespace Amib.Threading.Internal
         /// <param name="wigStartInfo">Work item group start information</param>
         /// <param name="callback">A callback to execute</param>
         /// <returns>Returns a work item</returns>
-        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
         /// <param name="callback">A callback to execute</param>
         /// <param name="workItemPriority">The priority of the work item</param>
         /// <returns>Returns a work item</returns>
-        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
         /// <param name="workItemInfo">Work item info</param>
         /// <param name="callback">A callback to execute</param>
         /// <returns>Returns a work item</returns>
-        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. 
         /// </param>
         /// <returns>Returns a work item</returns>
-        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. 
         /// </param>
         /// <returns>Returns a work item</returns>
-        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);

+ 35 - 17
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();
+        }
         /// <summary>
         /// Queue a work item
         /// </summary>
@@ -187,9 +216,7 @@ namespace Amib.Threading.Internal
         /// A delegate to call after the callback completion
         /// </param>
         /// <returns>Returns a work item result</returns>
-        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
         /// </param>
         /// <param name="workItemPriority">The work item priority</param>
         /// <returns>Returns a work item result</returns>
-        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
         /// </param>
         /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
         /// <returns>Returns a work item result</returns>
-        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
         /// <param name="callToPostExecute">Indicates on which cases to call to the post execute callback</param>
         /// <param name="workItemPriority">The work item priority</param>
         /// <returns>Returns a work item result</returns>
-        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();