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.cs213
1 files changed, 155 insertions, 58 deletions
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 9f05666..2065a46 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -31,6 +31,7 @@ using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode] 31using System.Diagnostics; //for [DebuggerNonUserCode]
32using System.Globalization; 32using System.Globalization;
33using System.IO; 33using System.IO;
34using System.Linq;
34using System.Reflection; 35using System.Reflection;
35using System.Security; 36using System.Security;
36using System.Security.Policy; 37using System.Security.Policy;
@@ -107,6 +108,24 @@ namespace OpenSim.Region.ScriptEngine.XEngine
107 private IXmlRpcRouter m_XmlRpcRouter; 108 private IXmlRpcRouter m_XmlRpcRouter;
108 private int m_EventLimit; 109 private int m_EventLimit;
109 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
110 private string m_ScriptEnginesPath = null; 129 private string m_ScriptEnginesPath = null;
111 130
112 private ExpiringCache<UUID, bool> m_runFlags = new ExpiringCache<UUID, bool>(); 131 private ExpiringCache<UUID, bool> m_runFlags = new ExpiringCache<UUID, bool>();
@@ -218,6 +237,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
218 } 237 }
219 } 238 }
220 239
240 private ScriptEngineConsoleCommands m_consoleCommands;
241
221 public string ScriptEngineName 242 public string ScriptEngineName
222 { 243 {
223 get { return "XEngine"; } 244 get { return "XEngine"; }
@@ -316,6 +337,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
316 m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); 337 m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30);
317 m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); 338 m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false);
318 m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; 339 m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000;
340 m_WaitForEventCompletionOnScriptStop
341 = m_ScriptConfig.GetInt("WaitForEventCompletionOnScriptStop", m_WaitForEventCompletionOnScriptStop);
342
319 m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); 343 m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines");
320 344
321 m_Prio = ThreadPriority.BelowNormal; 345 m_Prio = ThreadPriority.BelowNormal;
@@ -364,48 +388,59 @@ namespace OpenSim.Region.ScriptEngine.XEngine
364 OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved; 388 OnObjectRemoved += m_XmlRpcRouter.ObjectRemoved;
365 } 389 }
366 390
391 m_consoleCommands = new ScriptEngineConsoleCommands(this);
392 m_consoleCommands.RegisterCommands();
393
367 MainConsole.Instance.Commands.AddCommand( 394 MainConsole.Instance.Commands.AddCommand(
368 "Scripts", false, "xengine status", "xengine status", "Show status information", 395 "Scripts", false, "xengine status", "xengine status", "Show status information",
369 "Show status information on the script engine.", 396 "Show status information on the script engine.",
370 HandleShowStatus); 397 HandleShowStatus);
371 398
372 MainConsole.Instance.Commands.AddCommand( 399 MainConsole.Instance.Commands.AddCommand(
373 "Scripts", false, "scripts show", "scripts show [<script-item-uuid>]", "Show script information", 400 "Scripts", false, "scripts show", "scripts show [<script-item-uuid>+]", "Show script information",
374 "Show information on all scripts known to the script engine." 401 "Show information on all scripts known to the script engine.\n"
375 + "If a <script-item-uuid> is given then only information on that script will be shown.", 402 + "If one or more <script-item-uuid>s are given then only information on that script will be shown.",
376 HandleShowScripts); 403 HandleShowScripts);
377 404
378 MainConsole.Instance.Commands.AddCommand( 405 MainConsole.Instance.Commands.AddCommand(
379 "Scripts", false, "show scripts", "show scripts [<script-item-uuid>]", "Show script information", 406 "Scripts", false, "show scripts", "show scripts [<script-item-uuid>+]", "Show script information",
380 "Synonym for scripts show command", HandleShowScripts); 407 "Synonym for scripts show command", HandleShowScripts);
381 408
382 MainConsole.Instance.Commands.AddCommand( 409 MainConsole.Instance.Commands.AddCommand(
383 "Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>]", "Suspends all running scripts", 410 "Scripts", false, "scripts suspend", "scripts suspend [<script-item-uuid>+]", "Suspends all running scripts",
384 "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a" 411 "Suspends all currently running scripts. This only suspends event delivery, it will not suspend a"
385 + " script that is currently processing an event.\n" 412 + " script that is currently processing an event.\n"
386 + "Suspended scripts will continue to accumulate events but won't process them.\n" 413 + "Suspended scripts will continue to accumulate events but won't process them.\n"
387 + "If a <script-item-uuid> is given then only that script will be suspended. Otherwise, all suitable scripts are suspended.", 414 + "If one or more <script-item-uuid>s are given then only that script will be suspended. Otherwise, all suitable scripts are suspended.",
388 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript)); 415 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleSuspendScript));
389 416
390 MainConsole.Instance.Commands.AddCommand( 417 MainConsole.Instance.Commands.AddCommand(
391 "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>]", "Resumes all suspended scripts", 418 "Scripts", false, "scripts resume", "scripts resume [<script-item-uuid>+]", "Resumes all suspended scripts",
392 "Resumes all currently suspended scripts.\n" 419 "Resumes all currently suspended scripts.\n"
393 + "Resumed scripts will process all events accumulated whilst suspended." 420 + "Resumed scripts will process all events accumulated whilst suspended.\n"
394 + "If a <script-item-uuid> is given then only that script will be resumed. Otherwise, all suitable scripts are resumed.", 421 + "If one or more <script-item-uuid>s are given then only that script will be resumed. Otherwise, all suitable scripts are resumed.",
395 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript)); 422 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleResumeScript));
396 423
397 MainConsole.Instance.Commands.AddCommand( 424 MainConsole.Instance.Commands.AddCommand(
398 "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>]", "Stops all running scripts", 425 "Scripts", false, "scripts stop", "scripts stop [<script-item-uuid>+]", "Stops all running scripts",
399 "Stops all running scripts." 426 "Stops all running scripts.\n"
400 + "If a <script-item-uuid> is given then only that script will be stopped. Otherwise, all suitable scripts are stopped.", 427 + "If one or more <script-item-uuid>s are given then only that script will be stopped. Otherwise, all suitable scripts are stopped.",
401 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript)); 428 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStopScript));
402 429
403 MainConsole.Instance.Commands.AddCommand( 430 MainConsole.Instance.Commands.AddCommand(
404 "Scripts", false, "scripts start", "scripts start [<script-item-uuid>]", "Starts all stopped scripts", 431 "Scripts", false, "scripts start", "scripts start [<script-item-uuid>+]", "Starts all stopped scripts",
405 "Starts all stopped scripts." 432 "Starts all stopped scripts.\n"
406 + "If a <script-item-uuid> is given then only that script will be started. Otherwise, all suitable scripts are started.", 433 + "If one or more <script-item-uuid>s are given then only that script will be started. Otherwise, all suitable scripts are started.",
407 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript)); 434 (module, cmdparams) => HandleScriptsAction(cmdparams, HandleStartScript));
408 435
436 MainConsole.Instance.Commands.AddCommand(
437 "Scripts", false, "debug scripts log", "debug scripts log <item-id> <log-level>", "Extra debug logging for a script",
438 "Activates or deactivates extra debug logging for the given script.\n"
439 + "Level == 0, deactivate extra debug logging.\n"
440 + "Level >= 1, log state changes.\n"
441 + "Level >= 2, log event invocations.\n",
442 HandleDebugScriptLogCommand);
443
409// MainConsole.Instance.Commands.AddCommand( 444// MainConsole.Instance.Commands.AddCommand(
410// "Debug", false, "debug xengine", "debug xengine [<level>]", 445// "Debug", false, "debug xengine", "debug xengine [<level>]",
411// "Turn on detailed xengine debugging.", 446// "Turn on detailed xengine debugging.",
@@ -414,6 +449,41 @@ namespace OpenSim.Region.ScriptEngine.XEngine
414// HandleDebugLevelCommand); 449// HandleDebugLevelCommand);
415 } 450 }
416 451
452 private void HandleDebugScriptLogCommand(string module, string[] args)
453 {
454 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
455 return;
456
457 if (args.Length != 5)
458 {
459 MainConsole.Instance.Output("Usage: debug script log <item-id> <log-level>");
460 return;
461 }
462
463 UUID itemId;
464
465 if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, args[3], out itemId))
466 return;
467
468 int newLevel;
469
470 if (!ConsoleUtil.TryParseConsoleInt(MainConsole.Instance, args[4], out newLevel))
471 return;
472
473 IScriptInstance si;
474
475 lock (m_Scripts)
476 {
477 // XXX: We can't give the user feedback on a bad item id because this may apply to a different script
478 // engine
479 if (!m_Scripts.TryGetValue(itemId, out si))
480 return;
481 }
482
483 si.DebugLevel = newLevel;
484 MainConsole.Instance.OutputFormat("Set debug level of {0} {1} to {2}", si.ScriptName, si.ItemID, newLevel);
485 }
486
417 /// <summary> 487 /// <summary>
418 /// Change debug level 488 /// Change debug level
419 /// </summary> 489 /// </summary>
@@ -445,9 +515,21 @@ namespace OpenSim.Region.ScriptEngine.XEngine
445 /// </summary> 515 /// </summary>
446 /// <param name="cmdparams"></param> 516 /// <param name="cmdparams"></param>
447 /// <param name="instance"></param> 517 /// <param name="instance"></param>
448 /// <returns>true if we're okay to proceed, false if not.</returns> 518 /// <param name="comparer">Basis on which to sort output. Can be null if no sort needs to take place</param>
449 private void HandleScriptsAction(string[] cmdparams, Action<IScriptInstance> action) 519 private void HandleScriptsAction(string[] cmdparams, Action<IScriptInstance> action)
450 { 520 {
521 HandleScriptsAction<object>(cmdparams, action, null);
522 }
523
524 /// <summary>
525 /// Parse the raw item id into a script instance from the command params if it's present.
526 /// </summary>
527 /// <param name="cmdparams"></param>
528 /// <param name="instance"></param>
529 /// <param name="keySelector">Basis on which to sort output. Can be null if no sort needs to take place</param>
530 private void HandleScriptsAction<TKey>(
531 string[] cmdparams, Action<IScriptInstance> action, Func<IScriptInstance, TKey> keySelector)
532 {
451 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) 533 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
452 return; 534 return;
453 535
@@ -458,35 +540,42 @@ namespace OpenSim.Region.ScriptEngine.XEngine
458 540
459 if (cmdparams.Length == 2) 541 if (cmdparams.Length == 2)
460 { 542 {
461 foreach (IScriptInstance instance in m_Scripts.Values) 543 IEnumerable<IScriptInstance> scripts = m_Scripts.Values;
544
545 if (keySelector != null)
546 scripts = scripts.OrderBy<IScriptInstance, TKey>(keySelector);
547
548 foreach (IScriptInstance instance in scripts)
462 action(instance); 549 action(instance);
463 550
464 return; 551 return;
465 } 552 }
466 553
467 rawItemId = cmdparams[2]; 554 for (int i = 2; i < cmdparams.Length; i++)
468
469 if (!UUID.TryParse(rawItemId, out itemId))
470 {
471 MainConsole.Instance.OutputFormat("Error - {0} is not a valid UUID", rawItemId);
472 return;
473 }
474
475 if (itemId != UUID.Zero)
476 { 555 {
477 IScriptInstance instance = GetInstance(itemId); 556 rawItemId = cmdparams[i];
478 if (instance == null) 557
558 if (!UUID.TryParse(rawItemId, out itemId))
479 { 559 {
480 // Commented out for now since this will cause false reports on simulators with more than 560 MainConsole.Instance.OutputFormat("ERROR: {0} is not a valid UUID", rawItemId);
481 // one scene where the current command line set region is 'root' (which causes commands to 561 continue;
482 // go to both regions... (sigh)
483// MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId);
484 return;
485 } 562 }
486 else 563
564 if (itemId != UUID.Zero)
487 { 565 {
488 action(instance); 566 IScriptInstance instance = GetInstance(itemId);
489 return; 567 if (instance == null)
568 {
569 // Commented out for now since this will cause false reports on simulators with more than
570 // one scene where the current command line set region is 'root' (which causes commands to
571 // go to both regions... (sigh)
572 // MainConsole.Instance.OutputFormat("Error - No item found with id {0}", itemId);
573 continue;
574 }
575 else
576 {
577 action(instance);
578 }
490 } 579 }
491 } 580 }
492 } 581 }
@@ -505,9 +594,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
505 StringBuilder sb = new StringBuilder(); 594 StringBuilder sb = new StringBuilder();
506 sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName); 595 sb.AppendFormat("Status of XEngine instance for {0}\n", m_Scene.RegionInfo.RegionName);
507 596
597 long scriptsLoaded, eventsQueued = 0, eventsProcessed = 0;
598
508 lock (m_Scripts) 599 lock (m_Scripts)
509 sb.AppendFormat("Scripts loaded : {0}\n", m_Scripts.Count); 600 {
601 scriptsLoaded = m_Scripts.Count;
510 602
603 foreach (IScriptInstance si in m_Scripts.Values)
604 {
605 eventsQueued += si.EventsQueued;
606 eventsProcessed += si.EventsProcessed;
607 }
608 }
609
610 sb.AppendFormat("Scripts loaded : {0}\n", scriptsLoaded);
511 sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count); 611 sb.AppendFormat("Unique scripts : {0}\n", m_uniqueScripts.Count);
512 sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count); 612 sb.AppendFormat("Scripts waiting for load : {0}\n", m_CompileQueue.Count);
513 sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads); 613 sb.AppendFormat("Max threads : {0}\n", m_ThreadPool.MaxThreads);
@@ -516,6 +616,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
516 sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads); 616 sb.AppendFormat("In use threads : {0}\n", m_ThreadPool.InUseThreads);
517 sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks); 617 sb.AppendFormat("Work items waiting : {0}\n", m_ThreadPool.WaitingCallbacks);
518// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); 618// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count);
619 sb.AppendFormat("Events queued : {0}\n", eventsQueued);
620 sb.AppendFormat("Events processed : {0}\n", eventsProcessed);
519 621
520 SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this); 622 SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this);
521 sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0); 623 sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0);
@@ -546,7 +648,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
546 } 648 }
547 } 649 }
548 650
549 HandleScriptsAction(cmdparams, HandleShowScript); 651 HandleScriptsAction<long>(cmdparams, HandleShowScript, si => si.EventsProcessed);
550 } 652 }
551 653
552 private void HandleShowScript(IScriptInstance instance) 654 private void HandleShowScript(IScriptInstance instance)
@@ -576,11 +678,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
576 678
577 sb.AppendFormat("Script name : {0}\n", instance.ScriptName); 679 sb.AppendFormat("Script name : {0}\n", instance.ScriptName);
578 sb.AppendFormat("Status : {0}\n", status); 680 sb.AppendFormat("Status : {0}\n", status);
579 681 sb.AppendFormat("Queued events : {0}\n", instance.EventsQueued);
580 lock (eq) 682 sb.AppendFormat("Processed events : {0}\n", instance.EventsProcessed);
581 sb.AppendFormat("Queued events : {0}\n", eq.Count);
582
583 sb.AppendFormat("Item UUID : {0}\n", instance.ItemID); 683 sb.AppendFormat("Item UUID : {0}\n", instance.ItemID);
684 sb.AppendFormat("Asset UUID : {0}\n", instance.AssetID);
584 sb.AppendFormat("Containing part name: {0}\n", instance.PrimName); 685 sb.AppendFormat("Containing part name: {0}\n", instance.PrimName);
585 sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID); 686 sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID);
586 sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition); 687 sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition);
@@ -1089,8 +1190,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1089 1190
1090 string assembly = ""; 1191 string assembly = "";
1091 1192
1092 CultureInfo USCulture = new CultureInfo("en-US"); 1193 Culture.SetCurrentCulture();
1093 Thread.CurrentThread.CurrentCulture = USCulture;
1094 1194
1095 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap; 1195 Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap;
1096 1196
@@ -1256,12 +1356,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1256 m_DomainScripts[appDomain].Add(itemID); 1356 m_DomainScripts[appDomain].Add(itemID);
1257 1357
1258 instance = new ScriptInstance(this, part, 1358 instance = new ScriptInstance(this, part,
1259 itemID, assetID, assembly, 1359 item,
1260 m_AppDomains[appDomain], 1360 startParam, postOnRez,
1261 part.ParentGroup.RootPart.Name, 1361 m_MaxScriptQueue);
1262 item.Name, startParam, postOnRez,
1263 stateSource, m_MaxScriptQueue);
1264 1362
1363 instance.Load(m_AppDomains[appDomain], assembly, stateSource);
1265// m_log.DebugFormat( 1364// m_log.DebugFormat(
1266// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 1365// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1267// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 1366// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
@@ -1347,9 +1446,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1347 lockScriptsForWrite(false); 1446 lockScriptsForWrite(false);
1348 instance.ClearQueue(); 1447 instance.ClearQueue();
1349 1448
1350 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1449 instance.Stop(m_WaitForEventCompletionOnScriptStop);
1351 // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort.
1352 instance.Stop(1000);
1353 1450
1354// bool objectRemoved = false; 1451// bool objectRemoved = false;
1355 1452
@@ -1485,6 +1582,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1485 startInfo.StartSuspended = true; 1582 startInfo.StartSuspended = true;
1486 1583
1487 m_ThreadPool = new SmartThreadPool(startInfo); 1584 m_ThreadPool = new SmartThreadPool(startInfo);
1585 m_ThreadPool.Name = "XEngine";
1488 } 1586 }
1489 1587
1490 // 1588 //
@@ -1504,8 +1602,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1504 /// <returns></returns> 1602 /// <returns></returns>
1505 private object ProcessEventHandler(object parms) 1603 private object ProcessEventHandler(object parms)
1506 { 1604 {
1507 CultureInfo USCulture = new CultureInfo("en-US"); 1605 Culture.SetCurrentCulture();
1508 Thread.CurrentThread.CurrentCulture = USCulture;
1509 1606
1510 IScriptInstance instance = (ScriptInstance) parms; 1607 IScriptInstance instance = (ScriptInstance) parms;
1511 1608
@@ -1693,7 +1790,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1693 { 1790 {
1694 IScriptInstance instance = GetInstance(itemID); 1791 IScriptInstance instance = GetInstance(itemID);
1695 if (instance != null) 1792 if (instance != null)
1696 instance.ResetScript(); 1793 instance.ResetScript(m_WaitForEventCompletionOnScriptStop);
1697 } 1794 }
1698 1795
1699 public void StartScript(UUID itemID) 1796 public void StartScript(UUID itemID)
@@ -1708,14 +1805,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1708 public void StopScript(UUID itemID) 1805 public void StopScript(UUID itemID)
1709 { 1806 {
1710 IScriptInstance instance = GetInstance(itemID); 1807 IScriptInstance instance = GetInstance(itemID);
1808
1711 if (instance != null) 1809 if (instance != null)
1712 { 1810 {
1713 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1811 instance.Stop(m_WaitForEventCompletionOnScriptStop);
1714 // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort.
1715 instance.Stop(1000);
1716 } 1812 }
1717 else 1813 else
1718 { 1814 {
1815// m_log.DebugFormat("[XENGINE]: Could not find script with ID {0} to stop in {1}", itemID, World.Name);
1719 m_runFlags.AddOrUpdate(itemID, false, 240); 1816 m_runFlags.AddOrUpdate(itemID, false, 240);
1720 } 1817 }
1721 } 1818 }