aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs6
-rw-r--r--bin/OpenSim.ini.example12
6 files changed, 98 insertions, 21 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs
index fb20f40..7da2769 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/EventQueueManager.cs
@@ -99,6 +99,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
99 /// </summary> 99 /// </summary>
100 internal int numberOfThreads; 100 internal int numberOfThreads;
101 101
102 internal static int EventExecutionMaxQueueSize;
103
102 /// <summary> 104 /// <summary>
103 /// Maximum time one function can use for execution before we perform a thread kill. 105 /// Maximum time one function can use for execution before we perform a thread kill.
104 /// </summary> 106 /// </summary>
@@ -208,6 +210,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
208 maxFunctionExecutionTimems = m_ScriptEngine.ScriptConfigSource.GetInt("MaxEventExecutionTimeMs", 5000); 210 maxFunctionExecutionTimems = m_ScriptEngine.ScriptConfigSource.GetInt("MaxEventExecutionTimeMs", 5000);
209 EnforceMaxExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("EnforceMaxEventExecutionTime", false); 211 EnforceMaxExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("EnforceMaxEventExecutionTime", false);
210 KillScriptOnMaxFunctionExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("DeactivateScriptOnTimeout", false); 212 KillScriptOnMaxFunctionExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("DeactivateScriptOnTimeout", false);
213 EventExecutionMaxQueueSize = m_ScriptEngine.ScriptConfigSource.GetInt("EventExecutionMaxQueueSize", 300);
211 214
212 // Now refresh config in all threads 215 // Now refresh config in all threads
213 lock (eventQueueThreadsLock) 216 lock (eventQueueThreadsLock)
@@ -362,6 +365,13 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
362 { 365 {
363 lock (queueLock) 366 lock (queueLock)
364 { 367 {
368 if (eventQueue.Count >= EventExecutionMaxQueueSize)
369 {
370 m_ScriptEngine.Log.Error(m_ScriptEngine.ScriptEngineName, "ERROR: Event execution queue item count is at " + eventQueue.Count + ". Config variable \"EventExecutionMaxQueueSize\" is set to " + EventExecutionMaxQueueSize + ", so ignoring new event.");
371 m_ScriptEngine.Log.Error(m_ScriptEngine.ScriptEngineName, "Event ignored: localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName);
372 return;
373 }
374
365 // Create a structure and add data 375 // Create a structure and add data
366 QueueItemStruct QIS = new QueueItemStruct(); 376 QueueItemStruct QIS = new QueueItemStruct();
367 QIS.localID = localID; 377 QIS.localID = localID;
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs
index dc98637..fc2fda9 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/MaintenanceThread.cs
@@ -38,19 +38,20 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
38 /// <summary> 38 /// <summary>
39 /// Maintenance thread. Enforcing max execution time for example. 39 /// Maintenance thread. Enforcing max execution time for example.
40 /// </summary> 40 /// </summary>
41 public static Thread MaintenanceThreadThread; 41 public Thread MaintenanceThreadThread;
42 42
43 /// <summary> 43 /// <summary>
44 /// Starts maintenance thread 44 /// Starts maintenance thread
45 /// </summary> 45 /// </summary>
46 private void StartMaintenanceThread() 46 private void StartMaintenanceThread()
47 { 47 {
48 StopMaintenanceThread(); 48 if (MaintenanceThreadThread == null)
49 49 {
50 MaintenanceThreadThread = new Thread(MaintenanceLoop); 50 MaintenanceThreadThread = new Thread(MaintenanceLoop);
51 MaintenanceThreadThread.Name = "ScriptMaintenanceThread"; 51 MaintenanceThreadThread.Name = "ScriptMaintenanceThread";
52 MaintenanceThreadThread.IsBackground = true; 52 MaintenanceThreadThread.IsBackground = true;
53 MaintenanceThreadThread.Start(); 53 MaintenanceThreadThread.Start();
54 }
54 } 55 }
55 56
56 /// <summary> 57 /// <summary>
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
index ea8ae1f..0b58da0 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptEngine.cs
@@ -92,23 +92,26 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
92 m_log = logger; 92 m_log = logger;
93 ConfigSource = config; 93 ConfigSource = config;
94 Log.Verbose(ScriptEngineName, "ScriptEngine initializing"); 94 Log.Verbose(ScriptEngineName, "ScriptEngine initializing");
95 Log.Verbose(ScriptEngineName, "Reading configuration from config section \"" + ScriptEngineName + "\"");
96 95
97 // Make sure we have config 96 // Make sure we have config
98 if (ConfigSource.Configs[ScriptEngineName] == null) 97 if (ConfigSource.Configs[ScriptEngineName] == null)
99 ConfigSource.AddConfig(ScriptEngineName); 98 ConfigSource.AddConfig(ScriptEngineName);
100 ScriptConfigSource = ConfigSource.Configs[ScriptEngineName]; 99 ScriptConfigSource = ConfigSource.Configs[ScriptEngineName];
101 100
101
102 //m_logger.Status(ScriptEngineName, "InitializeEngine"); 102 //m_logger.Status(ScriptEngineName, "InitializeEngine");
103 103
104 // Create all objects we'll be using 104 // Create all objects we'll be using
105 m_EventQueueManager = new EventQueueManager(this); 105 m_EventQueueManager = new EventQueueManager(this);
106 m_EventManager = new EventManager(this, HookUpToServer); 106 m_EventManager = new EventManager(this, HookUpToServer);
107 // We need to start it
108 newScriptManager.Start();
107 m_ScriptManager = newScriptManager; 109 m_ScriptManager = newScriptManager;
108 m_AppDomainManager = new AppDomainManager(this); 110 m_AppDomainManager = new AppDomainManager(this);
109 m_ASYNCLSLCommandManager = new AsyncLSLCommandManager(this); 111 m_ASYNCLSLCommandManager = new AsyncLSLCommandManager(this);
110 m_MaintenanceThread = new MaintenanceThread(this); 112 m_MaintenanceThread = new MaintenanceThread(this);
111 113
114 Log.Verbose(ScriptEngineName, "Reading configuration from config section \"" + ScriptEngineName + "\"");
112 ReadConfig(); 115 ReadConfig();
113 116
114 117
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
index 22cffff..53ef217 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
@@ -62,9 +62,11 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
62 #region Declares 62 #region Declares
63 63
64 private Thread scriptLoadUnloadThread; 64 private Thread scriptLoadUnloadThread;
65 private static Thread staticScriptLoadUnloadThread;
65 private int scriptLoadUnloadThread_IdleSleepms; 66 private int scriptLoadUnloadThread_IdleSleepms;
66 private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); 67 private Queue<LUStruct> LUQueue = new Queue<LUStruct>();
67 68 private static bool PrivateThread;
69 private int LoadUnloadMaxQueueSize;
68 70
69 // Load/Unload structure 71 // Load/Unload structure
70 private struct LUStruct 72 private struct LUStruct
@@ -98,6 +100,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
98 public void ReadConfig() 100 public void ReadConfig()
99 { 101 {
100 scriptLoadUnloadThread_IdleSleepms = m_scriptEngine.ScriptConfigSource.GetInt("ScriptLoadUnloadLoopms", 30); 102 scriptLoadUnloadThread_IdleSleepms = m_scriptEngine.ScriptConfigSource.GetInt("ScriptLoadUnloadLoopms", 30);
103 PrivateThread = m_scriptEngine.ScriptConfigSource.GetBoolean("PrivateScriptLoadUnloadThread", false);
104 LoadUnloadMaxQueueSize = m_scriptEngine.ScriptConfigSource.GetInt("LoadUnloadMaxQueueSize", 100);
101 } 105 }
102 106
103 #region Object init/shutdown 107 #region Object init/shutdown
@@ -107,14 +111,52 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
107 public ScriptManager(ScriptEngineBase.ScriptEngine scriptEngine) 111 public ScriptManager(ScriptEngineBase.ScriptEngine scriptEngine)
108 { 112 {
109 m_scriptEngine = scriptEngine; 113 m_scriptEngine = scriptEngine;
110 // We should not read config during startup as ScriptEngine may not have config object yet 114 }
115 public void Start()
116 {
117 ReadConfig();
111 118
112 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 119 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
113 scriptLoadUnloadThread = new Thread(ScriptLoadUnloadThreadLoop); 120
114 scriptLoadUnloadThread.Name = "ScriptLoadUnloadThread"; 121 //
115 scriptLoadUnloadThread.IsBackground = true; 122 // CREATE THREAD
116 scriptLoadUnloadThread.Priority = ThreadPriority.BelowNormal; 123 // Private or shared
117 scriptLoadUnloadThread.Start(); 124 //
125 if (PrivateThread)
126 {
127 // Assign one thread per region
128 scriptLoadUnloadThread = StartScriptLoadUnloadThread();
129 }
130 else
131 {
132 // Shared thread - make sure one exist, then assign it to the private
133 if (staticScriptLoadUnloadThread == null)
134 {
135 staticScriptLoadUnloadThread = StartScriptLoadUnloadThread();
136 }
137 scriptLoadUnloadThread = staticScriptLoadUnloadThread;
138 }
139 }
140
141 private static int privateThreadCount = 0;
142 private Thread StartScriptLoadUnloadThread()
143 {
144 Thread t = new Thread(ScriptLoadUnloadThreadLoop);
145 string name = "ScriptLoadUnloadThread:";
146 if (PrivateThread)
147 {
148 name += "Private:" + privateThreadCount;
149 privateThreadCount++;
150 }
151 else
152 {
153 name += "Shared";
154 }
155 t.Name = name;
156 t.IsBackground = true;
157 t.Priority = ThreadPriority.Normal;
158 t.Start();
159 return t;
118 } 160 }
119 161
120 ~ScriptManager() 162 ~ScriptManager()
@@ -122,6 +164,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
122 // Abort load/unload thread 164 // Abort load/unload thread
123 try 165 try
124 { 166 {
167 PleaseShutdown = true;
168 Thread.Sleep(100);
125 if (scriptLoadUnloadThread != null) 169 if (scriptLoadUnloadThread != null)
126 { 170 {
127 if (scriptLoadUnloadThread.IsAlive == true) 171 if (scriptLoadUnloadThread.IsAlive == true)
@@ -148,6 +192,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
148 { 192 {
149 if (LUQueue.Count == 0) 193 if (LUQueue.Count == 0)
150 Thread.Sleep(scriptLoadUnloadThread_IdleSleepms); 194 Thread.Sleep(scriptLoadUnloadThread_IdleSleepms);
195 if (PleaseShutdown)
196 return;
151 if (LUQueue.Count > 0) 197 if (LUQueue.Count > 0)
152 { 198 {
153 LUStruct item = LUQueue.Dequeue(); 199 LUStruct item = LUQueue.Dequeue();
@@ -185,7 +231,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
185 231
186 #endregion 232 #endregion
187 233
188 234
189 235
190 #region Start/Stop/Reset script 236 #region Start/Stop/Reset script
191 237
@@ -198,6 +244,12 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
198 /// <param name="localID"></param> 244 /// <param name="localID"></param>
199 public void StartScript(uint localID, LLUUID itemID, string Script) 245 public void StartScript(uint localID, LLUUID itemID, string Script)
200 { 246 {
247 if (LUQueue.Count >= LoadUnloadMaxQueueSize)
248 {
249 m_scriptEngine.Log.Error(m_scriptEngine.ScriptEngineName, "ERROR: Load/unload queue item count is at " + LUQueue.Count + ". Config variable \"LoadUnloadMaxQueueSize\" is set to " + LoadUnloadMaxQueueSize + ", so ignoring new script.");
250 return;
251 }
252
201 LUStruct ls = new LUStruct(); 253 LUStruct ls = new LUStruct();
202 ls.localID = localID; 254 ls.localID = localID;
203 ls.itemID = itemID; 255 ls.itemID = itemID;
@@ -224,9 +276,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
224 //private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler(); 276 //private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler();
225 277
226 public abstract void _StartScript(uint localID, LLUUID itemID, string Script); 278 public abstract void _StartScript(uint localID, LLUUID itemID, string Script);
227
228 public abstract void _StopScript(uint localID, LLUUID itemID); 279 public abstract void _StopScript(uint localID, LLUUID itemID);
229 280
230 281
231 #endregion 282 #endregion
232 283
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
index f6c9e30..821b2d4 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/DotNetEngine/ScriptManager.cs
@@ -86,7 +86,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
86 86
87 CompiledScript.Source = Script; 87 CompiledScript.Source = Script;
88 // Add it to our script memstruct 88 // Add it to our script memstruct
89 SetScript(localID, itemID, CompiledScript); 89 m_scriptEngine.m_ScriptManager.SetScript(localID, itemID, CompiledScript);
90 90
91 // We need to give (untrusted) assembly a private instance of BuiltIns 91 // We need to give (untrusted) assembly a private instance of BuiltIns
92 // this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed. 92 // this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed.
@@ -144,9 +144,9 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
144 // Get AppDomain 144 // Get AppDomain
145 AppDomain ad = LSLBC.Exec.GetAppDomain(); 145 AppDomain ad = LSLBC.Exec.GetAppDomain();
146 // Tell script not to accept new requests 146 // Tell script not to accept new requests
147 GetScript(localID, itemID).Exec.StopScript(); 147 m_scriptEngine.m_ScriptManager.GetScript(localID, itemID).Exec.StopScript();
148 // Remove from internal structure 148 // Remove from internal structure
149 RemoveScript(localID, itemID); 149 m_scriptEngine.m_ScriptManager.RemoveScript(localID, itemID);
150 // Tell AppDomain that we have stopped script 150 // Tell AppDomain that we have stopped script
151 m_scriptEngine.m_AppDomainManager.StopScript(ad); 151 m_scriptEngine.m_AppDomainManager.StopScript(ad);
152 } 152 }
diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example
index 9b9a139..495f4ce 100644
--- a/bin/OpenSim.ini.example
+++ b/bin/OpenSim.ini.example
@@ -195,6 +195,18 @@ ScriptsPerAppDomain=1
195; But once active it will process all in queue before sleeping again 195; But once active it will process all in queue before sleeping again
196ScriptLoadUnloadLoopms=30 196ScriptLoadUnloadLoopms=30
197 197
198; Loading and unloading of scripts is queued and processed by a separate thread.
199; This thread can either be shared among all regions, or private (one thread per region)
200PrivateScriptLoadUnloadThread=false
201
202; Maximum number of items in load/unload queue before we start rejecting loads
203; Note that we will only be rejecting load. Unloads will still be able to queue.
204LoadUnloadMaxQueueSize=100
205
206; Maximum number of (LSL) events that can be queued before new events are ignored.
207EventExecutionMaxQueueSize=300
208
209
198; Async LL command sleep 210; Async LL command sleep
199; If no async LL commands are waiting, how long should thread sleep before checking again 211; If no async LL commands are waiting, how long should thread sleep before checking again
200; Async LL commands are LSL-commands that causes an event to be fired back with result 212; Async LL commands are LSL-commands that causes an event to be fired back with result