aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/XEngine/XEngine.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs116
1 files changed, 96 insertions, 20 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index c68f03f..7712076 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -49,7 +49,10 @@ using OpenSim.Region.ScriptEngine.Shared;
49using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 49using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
50using OpenSim.Region.ScriptEngine.Shared.CodeTools; 50using OpenSim.Region.ScriptEngine.Shared.CodeTools;
51using OpenSim.Region.ScriptEngine.Shared.Instance; 51using OpenSim.Region.ScriptEngine.Shared.Instance;
52using OpenSim.Region.ScriptEngine.Shared.Api;
53using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
52using OpenSim.Region.ScriptEngine.Interfaces; 54using OpenSim.Region.ScriptEngine.Interfaces;
55using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer;
53 56
54using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; 57using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>;
55 58
@@ -173,12 +176,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine
173 get { return m_ConfigSource; } 176 get { return m_ConfigSource; }
174 } 177 }
175 178
179 /// <summary>
180 /// Event fired after the script engine has finished removing a script.
181 /// </summary>
176 public event ScriptRemoved OnScriptRemoved; 182 public event ScriptRemoved OnScriptRemoved;
183
184 /// <summary>
185 /// Event fired after the script engine has finished removing a script from an object.
186 /// </summary>
177 public event ObjectRemoved OnObjectRemoved; 187 public event ObjectRemoved OnObjectRemoved;
178 188
179 //
180 // IRegionModule functions
181 //
182 public void Initialise(IConfigSource configSource) 189 public void Initialise(IConfigSource configSource)
183 { 190 {
184 if (configSource.Configs["XEngine"] == null) 191 if (configSource.Configs["XEngine"] == null)
@@ -274,22 +281,22 @@ namespace OpenSim.Region.ScriptEngine.XEngine
274 } 281 }
275 282
276 MainConsole.Instance.Commands.AddCommand( 283 MainConsole.Instance.Commands.AddCommand(
277 "scripts", false, "xengine status", "xengine status", "Show status information", 284 "Scripts", false, "xengine status", "xengine status", "Show status information",
278 "Show status information on the script engine.", 285 "Show status information on the script engine.",
279 HandleShowStatus); 286 HandleShowStatus);
280 287
281 MainConsole.Instance.Commands.AddCommand( 288 MainConsole.Instance.Commands.AddCommand(
282 "scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information", 289 "Scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information",
283 "Show information on all scripts known to the script engine." 290 "Show information on all scripts known to the script engine."
284 + "If a <script-item-uuid> is given then only information on that script will be shown.", 291 + "If a <script-item-uuid> is given then only information on that script will be shown.",
285 HandleShowScripts); 292 HandleShowScripts);
286 293
287 MainConsole.Instance.Commands.AddCommand( 294 MainConsole.Instance.Commands.AddCommand(
288 "scripts", false, "show scripts", "show scripts [<script-item-uuid>]", "Show script information", 295 "Scripts", false, "show scripts", "show scripts [<script-item-uuid>]", "Show script information",
289 "Synonym for scripts show command", HandleShowScripts); 296 "Synonym for scripts show command", HandleShowScripts);
290 297
291 MainConsole.Instance.Commands.AddCommand( 298 MainConsole.Instance.Commands.AddCommand(
292 "scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts", 299 "Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts",
293 "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" 300 "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a"
294 + " script that is currently processing an event.\n" 301 + " script that is currently processing an event.\n"
295 + "Suspended scripts will continue to accumulate events but won't process them.\n" 302 + "Suspended scripts will continue to accumulate events but won't process them.\n"
@@ -297,20 +304,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
297 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); 304 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript));
298 305
299 MainConsole.Instance.Commands.AddCommand( 306 MainConsole.Instance.Commands.AddCommand(
300 "scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts", 307 "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts",
301 "Resumes all currently suspended scripts.\n" 308 "Resumes all currently suspended scripts.\n"
302 + "Resumed scripts will process all events accumulated whilst suspended." 309 + "Resumed scripts will process all events accumulated whilst suspended."
303 + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", 310 + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.",
304 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); 311 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript));
305 312
306 MainConsole.Instance.Commands.AddCommand( 313 MainConsole.Instance.Commands.AddCommand(
307 "scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts", 314 "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts",
308 "Stops all running scripts." 315 "Stops all running scripts."
309 + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", 316 + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.",
310 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); 317 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript));
311 318
312 MainConsole.Instance.Commands.AddCommand( 319 MainConsole.Instance.Commands.AddCommand(
313 "scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts", 320 "Scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts",
314 "Starts all stopped scripts." 321 "Starts all stopped scripts."
315 + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.", 322 + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.",
316 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); 323 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript));
@@ -373,6 +380,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
373 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) 380 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
374 return; 381 return;
375 382
383 MainConsole.Instance.OutputFormat(GetStatusReport());
384 }
385
386 public string GetStatusReport()
387 {
376 StringBuilder sb = new StringBuilder(); 388 StringBuilder sb = new StringBuilder();
377 sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName); 389 sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName);
378 390
@@ -381,12 +393,26 @@ namespace OpenSim.Region.ScriptEngine.XEngine
381 393
382 sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); 394 sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count);
383 sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); 395 sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count);
396 sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads);
397 sb.AppendFormat("Min threads : {0}\n", m_ThreadPool.MinThreads);
384 sb.AppendFormat("Allocated threads : {0}\n", m_ThreadPool.ActiveThreads); 398 sb.AppendFormat("Allocated threads : {0}\n", m_ThreadPool.ActiveThreads);
385 sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads); 399 sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads);
386 sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks); 400 sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks);
387// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); 401// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count);
388 402
389 MainConsole.Instance.OutputFormat(sb.ToString()); 403 SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this);
404 sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0);
405
406 Dataserver ds = AsyncCommandManager.GetDataserverPlugin(this);
407 sb.AppendFormat("Dataserver requests : {0}\n", ds != null ? ds.DataserverRequestsCount : 0);
408
409 Timer t = AsyncCommandManager.GetTimerPlugin(this);
410 sb.AppendFormat("Timers : {0}\n", t != null ? t.TimersCount : 0);
411
412 Listener l = AsyncCommandManager.GetListenerPlugin(this);
413 sb.AppendFormat("Listeners : {0}\n", l != null ? l.ListenerCount : 0);
414
415 return sb.ToString();
390 } 416 }
391 417
392 public void HandleShowScripts(string module, string[] cmdparams) 418 public void HandleShowScripts(string module, string[] cmdparams)
@@ -973,7 +999,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
973 lock (m_Scripts) 999 lock (m_Scripts)
974 { 1000 {
975 // Create the object record 1001 // Create the object record
976
977 if ((!m_Scripts.ContainsKey(itemID)) || 1002 if ((!m_Scripts.ContainsKey(itemID)) ||
978 (m_Scripts[itemID].AssetID != assetID)) 1003 (m_Scripts[itemID].AssetID != assetID))
979 { 1004 {
@@ -1063,7 +1088,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1063 1088
1064 if (!m_PrimObjects[localID].Contains(itemID)) 1089 if (!m_PrimObjects[localID].Contains(itemID))
1065 m_PrimObjects[localID].Add(itemID); 1090 m_PrimObjects[localID].Add(itemID);
1066
1067 } 1091 }
1068 1092
1069 if (!m_Assemblies.ContainsKey(assetID)) 1093 if (!m_Assemblies.ContainsKey(assetID))
@@ -1102,7 +1126,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1102 } 1126 }
1103 1127
1104 instance.ClearQueue(); 1128 instance.ClearQueue();
1105 instance.Stop(0); 1129
1130 // Give the script some time to finish processing its last event. Simply aborting the script thread can
1131 // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort.
1132 instance.Stop(1000);
1133
1106// bool objectRemoved = false; 1134// bool objectRemoved = false;
1107 1135
1108 lock (m_PrimObjects) 1136 lock (m_PrimObjects)
@@ -1133,14 +1161,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1133 UnloadAppDomain(instance.AppDomain); 1161 UnloadAppDomain(instance.AppDomain);
1134 } 1162 }
1135 1163
1136 instance = null;
1137
1138 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1164 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1139 if (handlerObjectRemoved != null) 1165 if (handlerObjectRemoved != null)
1140 { 1166 handlerObjectRemoved(instance.ObjectID);
1141 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1142 handlerObjectRemoved(part.UUID);
1143 }
1144 1167
1145 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1168 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1146 if (handlerScriptRemoved != null) 1169 if (handlerScriptRemoved != null)
@@ -1872,6 +1895,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1872 } 1895 }
1873 } 1896 }
1874 1897
1898 public Dictionary<uint, float> GetObjectScriptsExecutionTimes()
1899 {
1900 long tickNow = Util.EnvironmentTickCount();
1901 Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
1902
1903 lock (m_Scripts)
1904 {
1905 foreach (IScriptInstance si in m_Scripts.Values)
1906 {
1907 if (!topScripts.ContainsKey(si.LocalID))
1908 topScripts[si.RootLocalID] = 0;
1909
1910// long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
1911// float framesElapsed = ticksElapsed / (18.1818 * TimeSpan.TicksPerMillisecond);
1912
1913 // Execution time of the script adjusted by it's measurement period to make scripts started at
1914 // different times comparable.
1915// float adjustedExecutionTime
1916// = (float)si.MeasurementPeriodExecutionTime
1917// / ((float)(tickNow - si.MeasurementPeriodTickStart) / ScriptInstance.MaxMeasurementPeriod)
1918// / TimeSpan.TicksPerMillisecond;
1919
1920 long ticksElapsed = tickNow - si.MeasurementPeriodTickStart;
1921
1922 // Avoid divide by zerp
1923 if (ticksElapsed == 0)
1924 ticksElapsed = 1;
1925
1926 // Scale execution time to the ideal 55 fps frame time for these reasons.
1927 //
1928 // 1) XEngine does not execute scripts per frame, unlike other script engines. Hence, there is no
1929 // 'script execution time per frame', which is the original purpose of this value.
1930 //
1931 // 2) Giving the raw execution times is misleading since scripts start at different times, making
1932 // it impossible to compare scripts.
1933 //
1934 // 3) Scaling the raw execution time to the time that the script has been running is better but
1935 // is still misleading since a script that has just been rezzed may appear to have been running
1936 // for much longer.
1937 //
1938 // 4) Hence, we scale execution time to an idealised frame time (55 fps). This is also not perfect
1939 // since the figure does not represent actual execution time and very hard running scripts will
1940 // never exceed 18ms (though this is a very high number for script execution so is a warning sign).
1941 float adjustedExecutionTime
1942 = ((float)si.MeasurementPeriodExecutionTime / ticksElapsed) * 18.1818f;
1943
1944 topScripts[si.RootLocalID] += adjustedExecutionTime;
1945 }
1946 }
1947
1948 return topScripts;
1949 }
1950
1875 public void SuspendScript(UUID itemID) 1951 public void SuspendScript(UUID itemID)
1876 { 1952 {
1877// m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID); 1953// m_log.DebugFormat("[XEngine]: Received request to suspend script with ID {0}", itemID);