Browse Source

let scripts dataserver do async code actions

UbitUmarov 3 years ago
parent
commit
144d4a6326

+ 68 - 8
OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Dataserver.cs

@@ -28,14 +28,19 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Threading;
 using OpenMetaverse;
+using Amib.Threading;
 using OpenSim.Region.ScriptEngine.Shared;
 using OpenSim.Region.ScriptEngine.Shared.Api;
+using Action = System.Action;
 
 namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
 {
     public class Dataserver
     {
+        private SmartThreadPool m_ThreadPool;
+
         public AsyncCommandManager m_CmdManager;
 
         public int DataserverRequestsCount
@@ -47,12 +52,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
             }
         }
 
-        private Dictionary<string, DataserverRequest> DataserverRequests =
-                new Dictionary<string, DataserverRequest>();
+        private Dictionary<string, DataserverRequest> DataserverRequests =  new Dictionary<string, DataserverRequest>();
 
         public Dataserver(AsyncCommandManager CmdManager)
         {
             m_CmdManager = CmdManager;
+
+            STPStartInfo startInfo = new STPStartInfo();
+            startInfo.ThreadPoolName = "ScriptV";
+            startInfo.IdleTimeout = 1000;
+            startInfo.MaxWorkerThreads = 4;
+            startInfo.MinWorkerThreads = 0;
+            startInfo.ThreadPriority = ThreadPriority.Normal;
+            startInfo.StartSuspended = true;
+
+            m_ThreadPool = new SmartThreadPool(startInfo);
+            m_ThreadPool.Start();
         }
 
         private class DataserverRequest
@@ -64,10 +79,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
             public string handle;
 
             public DateTime startTime;
+            public Action<string> action;
         }
 
         public UUID RegisterRequest(uint localID, UUID itemID,
-                                      string identifier)
+                                      string identifier, Action<string> action = null)
         {
             lock (DataserverRequests)
             {
@@ -83,13 +99,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
                 ds.handle = identifier;
 
                 ds.startTime = DateTime.Now;
+                ds.action = action;
 
                 DataserverRequests[identifier] = ds;
+                if(action != null)
+                    m_ThreadPool.QueueWorkItem((WorkItemCallback)ProcessActions, (object)identifier);
 
                 return ds.ID;
             }
         }
 
+        public object ProcessActions(object st)
+        {
+            string id = st as string;
+            if(string.IsNullOrEmpty(id))
+                return null;
+
+            DataserverRequest ds = null;
+            lock (DataserverRequests)
+            {
+                if (!DataserverRequests.TryGetValue(id, out ds))
+                    return null;
+            }
+
+            if (ds == null || ds.action == null)
+                return null;
+            try
+            {
+                ds.action.Invoke(ds.handle);
+            }
+            catch { }
+
+            ds.action = null;
+            lock (DataserverRequests)
+            {
+                if (DataserverRequests.TryGetValue(id, out ds))
+                    DataserverRequests.Remove(id);
+            }
+
+            return null;
+        }
+
         public void DataserverReply(string identifier, string reply)
         {
             DataserverRequest ds;
@@ -114,10 +164,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
         {
             lock (DataserverRequests)
             {
-                foreach (DataserverRequest ds in new List<DataserverRequest>(DataserverRequests.Values))
+                List<string> toremove = new List<string>(DataserverRequests.Count);
+                foreach (DataserverRequest ds in DataserverRequests.Values)
                 {
                     if (ds.itemID == itemID)
-                        DataserverRequests.Remove(ds.handle);
+                        toremove.Add(ds.handle);
+                }
+                foreach (string s in toremove)
+                {
+                    DataserverRequests.Remove(s);
                 }
             }
         }
@@ -126,10 +181,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
         {
             lock (DataserverRequests)
             {
-                foreach (DataserverRequest ds in new List<DataserverRequest>(DataserverRequests.Values))
+                List<string> toremove = new List<string>(DataserverRequests.Count);
+                foreach (DataserverRequest ds in DataserverRequests.Values)
+                {
+                    if (ds.startTime > DateTime.Now.AddSeconds(30) && ds.action == null)
+                        toremove.Add(ds.handle);
+                }
+                foreach (string s in toremove)
                 {
-                    if (ds.startTime > DateTime.Now.AddSeconds(30))
-                        DataserverRequests.Remove(ds.handle);
+                    DataserverRequests.Remove(s);
                 }
             }
         }

+ 2 - 1
prebuild.xml

@@ -2244,11 +2244,12 @@
       <Reference name="OpenSim.Region.CoreModules"/>
       <Reference name="OpenSim.Region.PhysicsModules.SharedBase"/>
       <Reference name="OpenSim.Services.Interfaces"/>
-	  <Reference name="OpenSim.Services.Connectors"/>
+      <Reference name="OpenSim.Services.Connectors"/>
       <Reference name="OpenSim.Region.ScriptEngine.Shared"/>
       <Reference name="OpenSim.Region.ScriptEngine.Shared.Api.Runtime"/>
       <Reference name="Nini" path="../../../../../../bin/"/>
       <Reference name="log4net" path="../../../../../../bin/"/>
+      <Reference name="SmartThreadPool"/>
 
       <Files>
         <Match pattern="*.cs" recurse="true">