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.cs88
1 files changed, 73 insertions, 15 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 05ba890..494e0b6 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -108,6 +108,24 @@ namespace OpenSim.Region.ScriptEngine.XEngine
108 private IXmlRpcRouter m_XmlRpcRouter; 108 private IXmlRpcRouter m_XmlRpcRouter;
109 private int m_EventLimit; 109 private int m_EventLimit;
110 private bool m_KillTimedOutScripts; 110 private bool m_KillTimedOutScripts;
111
112 /// <summary>
113 /// Number of milliseconds we will wait for a script event to complete on script stop before we forcibly abort
114 /// its thread.
115 /// </summary>
116 /// <remarks>
117 /// It appears that if a script thread is aborted whilst it is holding ReaderWriterLockSlim (possibly the write
118 /// lock) then the lock is not properly released. This causes mono 2.6, 2.10 and possibly
119 /// later to crash, sometimes with symptoms such as a leap to 100% script usage and a vm thead dump showing
120 /// all threads waiting on release of ReaderWriterLockSlim write thread which none of the threads listed
121 /// actually hold.
122 ///
123 /// Pausing for event completion reduces the risk of this happening. However, it may be that aborting threads
124 /// is not a mono issue per se but rather a risky activity in itself in an AppDomain that is not immediately
125 /// shutting down.
126 /// </remarks>
127 private int m_WaitForEventCompletionOnScriptStop = 1000;
128
111 private string m_ScriptEnginesPath = null; 129 private string m_ScriptEnginesPath = null;
112 130
113 private ExpiringCache<UUID, bool> m_runFlags = new ExpiringCache<UUID, bool>(); 131 private ExpiringCache<UUID, bool> m_runFlags = new ExpiringCache<UUID, bool>();
@@ -317,6 +335,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
317 m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); 335 m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30);
318 m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); 336 m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false);
319 m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; 337 m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000;
338 m_WaitForEventCompletionOnScriptStop
339 = m_ScriptConfig.GetInt("WaitForEventCompletionOnScriptStop", m_WaitForEventCompletionOnScriptStop);
340
320 m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); 341 m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines");
321 342
322 m_Prio = ThreadPriority.BelowNormal; 343 m_Prio = ThreadPriority.BelowNormal;
@@ -372,7 +393,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
372 393
373 MainConsole.Instance.Commands.AddCommand( 394 MainConsole.Instance.Commands.AddCommand(
374 "Scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information", 395 "Scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information",
375 "Show information on all scripts known to the script engine." 396 "Show information on all scripts known to the script engine.\n"
376 + "If a <script-item-uuid> is given then only information on that script will be shown.", 397 + "If a <script-item-uuid> is given then only information on that script will be shown.",
377 HandleShowScripts); 398 HandleShowScripts);
378 399
@@ -391,22 +412,30 @@ namespace OpenSim.Region.ScriptEngine.XEngine
391 MainConsole.Instance.Commands.AddCommand( 412 MainConsole.Instance.Commands.AddCommand(
392 "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts", 413 "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts",
393 "Resumes all currently suspended scripts.\n" 414 "Resumes all currently suspended scripts.\n"
394 + "Resumed scripts will process all events accumulated whilst suspended." 415 + "Resumed scripts will process all events accumulated whilst suspended.\n"
395 + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", 416 + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.",
396 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); 417 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript));
397 418
398 MainConsole.Instance.Commands.AddCommand( 419 MainConsole.Instance.Commands.AddCommand(
399 "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts", 420 "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts",
400 "Stops all running scripts." 421 "Stops all running scripts.\n"
401 + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", 422 + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.",
402 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); 423 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript));
403 424
404 MainConsole.Instance.Commands.AddCommand( 425 MainConsole.Instance.Commands.AddCommand(
405 "Scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts", 426 "Scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts",
406 "Starts all stopped scripts." 427 "Starts all stopped scripts.\n"
407 + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.", 428 + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.",
408 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); 429 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript));
409 430
431 MainConsole.Instance.Commands.AddCommand(
432 "Scripts", false, "debug script log", "debug scripts log <item-id> <log-level>", "Extra debug logging for a script",
433 "Activates or deactivates extra debug logging for the given script.\n"
434 + "Level == 0, deactivate extra debug logging.\n"
435 + "Level >= 1, log state changes.\n"
436 + "Level >= 2, log event invocations.\n",
437 HandleDebugScriptLogCommand);
438
410// MainConsole.Instance.Commands.AddCommand( 439// MainConsole.Instance.Commands.AddCommand(
411// "Debug", false, "debug xengine", "debug xengine [<level>]", 440// "Debug", false, "debug xengine", "debug xengine [<level>]",
412// "Turn on detailed xengine debugging.", 441// "Turn on detailed xengine debugging.",
@@ -415,6 +444,41 @@ namespace OpenSim.Region.ScriptEngine.XEngine
415// HandleDebugLevelCommand); 444// HandleDebugLevelCommand);
416 } 445 }
417 446
447 private void HandleDebugScriptLogCommand(string module, string[] args)
448 {
449 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
450 return;
451
452 if (args.Length != 5)
453 {
454 MainConsole.Instance.Output("Usage: debug script log <item-id> <log-level>");
455 return;
456 }
457
458 UUID itemId;
459
460 if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, args[3], out itemId))
461 return;
462
463 int newLevel;
464
465 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out newLevel))
466 return;
467
468 IScriptInstance si;
469
470 lock (m_Scripts)
471 {
472 // XXX: We can't give the user feedback on a bad item id because this may apply to a different script
473 // engine
474 if (!m_Scripts.TryGetValue(itemId, out si))
475 return;
476 }
477
478 si.DebugLevel = newLevel;
479 MainConsole.Instance.OutputFormat("Set debug level of {0} {1} to {2}", si.ScriptName, si.ItemID, newLevel);
480 }
481
418 /// <summary> 482 /// <summary>
419 /// Change debug level 483 /// Change debug level
420 /// </summary> 484 /// </summary>
@@ -486,7 +550,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
486 550
487 if (!UUID.TryParse(rawItemId, out itemId)) 551 if (!UUID.TryParse(rawItemId, out itemId))
488 { 552 {
489 MainConsole.Instance.OutputFormat("Error - {0} is not a valid UUID", rawItemId); 553 MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId);
490 return; 554 return;
491 } 555 }
492 556
@@ -610,6 +674,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
610 sb.AppendFormat("Queued events : {0}\n", instance.EventsQueued); 674 sb.AppendFormat("Queued events : {0}\n", instance.EventsQueued);
611 sb.AppendFormat("Processed events : {0}\n", instance.EventsProcessed); 675 sb.AppendFormat("Processed events : {0}\n", instance.EventsProcessed);
612 sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); 676 sb.AppendFormat("Item UUID : {0}\n", instance.ItemID);
677 sb.AppendFormat("Asset UUID : {0}\n", instance.AssetID);
613 sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); 678 sb.AppendFormat("Containing part name: {0}\n", instance.PrimName);
614 sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID); 679 sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID);
615 sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition); 680 sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition);
@@ -1375,9 +1440,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1375 lockScriptsForWrite(false); 1440 lockScriptsForWrite(false);
1376 instance.ClearQueue(); 1441 instance.ClearQueue();
1377 1442
1378 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1443 instance.Stop(m_WaitForEventCompletionOnScriptStop);
1379 // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort.
1380 instance.Stop(1000);
1381 1444
1382// bool objectRemoved = false; 1445// bool objectRemoved = false;
1383 1446
@@ -1735,16 +1798,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1735 public void StopScript(UUID itemID) 1798 public void StopScript(UUID itemID)
1736 { 1799 {
1737 IScriptInstance instance = GetInstance(itemID); 1800 IScriptInstance instance = GetInstance(itemID);
1801
1738 if (instance != null) 1802 if (instance != null)
1739 { 1803 instance.Stop(m_WaitForEventCompletionOnScriptStop);
1740 // Give the script some time to finish processing its last event. Simply aborting the script thread can
1741 // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort.
1742 instance.Stop(1000);
1743 }
1744 else 1804 else
1745 {
1746 m_runFlags.AddOrUpdate(itemID, false, 240); 1805 m_runFlags.AddOrUpdate(itemID, false, 240);
1747 }
1748 } 1806 }
1749 1807
1750 public DetectParams GetDetectParams(UUID itemID, int idx) 1808 public DetectParams GetDetectParams(UUID itemID, int idx)