diff options
author | Justin Clark-Casey (justincc) | 2012-03-15 00:06:52 +0000 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-03-19 21:29:24 +0000 |
commit | 9ecbcb787c426aa0093355609651ead7eb14b4f1 (patch) | |
tree | 112e410d7576becae22cbc1bc38b85a8ffe9d27b | |
parent | refactor: rename ScriptInstance.m_CurrentResult to m_CurrentWorkItem to make ... (diff) | |
download | opensim-SC_OLD-9ecbcb787c426aa0093355609651ead7eb14b4f1.zip opensim-SC_OLD-9ecbcb787c426aa0093355609651ead7eb14b4f1.tar.gz opensim-SC_OLD-9ecbcb787c426aa0093355609651ead7eb14b4f1.tar.bz2 opensim-SC_OLD-9ecbcb787c426aa0093355609651ead7eb14b4f1.tar.xz |
Alleviate an issue where calling Thread.Abort() on script WorkItems can fail to release locks, resulting in a crippled simulator.
This seems to be a particular problem with ReaderWriterLockSlim, though other locks can be affected as well.
It has been seen to happen when llDie() is called in a linkset running more than one script.
Alleviation here means supplying a ScriptInstance.Stop() timeout of 1000ms rather than 0ms, to give events a chance to complete.
Also, we check the IsRunning status at the top of the ScriptInstance.EventProcessor() so that another event doesn't start in the mean time.
Ultimately, a better solution may have to be found since a long-running event would still exceed the timeout and be aborted.
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 13 | ||||
-rw-r--r-- | OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 6 |
2 files changed, 15 insertions, 4 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index b840730..6a9cd72 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | |||
@@ -546,7 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
546 | public bool Stop(int timeout) | 546 | public bool Stop(int timeout) |
547 | { | 547 | { |
548 | // m_log.DebugFormat( | 548 | // m_log.DebugFormat( |
549 | // "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout); | 549 | // "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}", |
550 | // ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks); | ||
550 | 551 | ||
551 | IScriptWorkItem workItem; | 552 | IScriptWorkItem workItem; |
552 | 553 | ||
@@ -575,7 +576,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
575 | } | 576 | } |
576 | 577 | ||
577 | // Wait for the current event to complete. | 578 | // Wait for the current event to complete. |
578 | if (workItem.Wait(new TimeSpan((long)timeout * 100000))) | 579 | if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000))) |
579 | { | 580 | { |
580 | return true; | 581 | return true; |
581 | } | 582 | } |
@@ -592,7 +593,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
592 | // forcibly abort the work item (this aborts the underlying thread). | 593 | // forcibly abort the work item (this aborts the underlying thread). |
593 | if (!m_InSelfDelete) | 594 | if (!m_InSelfDelete) |
594 | { | 595 | { |
595 | // m_log.ErrorFormat("[SCRIPT INSTANCE]: Aborting script {0} {1}", ScriptName, ItemID); | 596 | // m_log.ErrorFormat( |
597 | // "[SCRIPT INSTANCE]: Aborting script {0} {1} in prim {2} {3} {4} {5}", | ||
598 | // ScriptName, ItemID, PrimName, ObjectID, m_InSelfDelete, DateTime.Now.Ticks); | ||
596 | 599 | ||
597 | workItem.Abort(); | 600 | workItem.Abort(); |
598 | } | 601 | } |
@@ -706,6 +709,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance | |||
706 | /// <returns></returns> | 709 | /// <returns></returns> |
707 | public object EventProcessor() | 710 | public object EventProcessor() |
708 | { | 711 | { |
712 | // We check here as the thread stopping this instance from running may itself hold the m_Script lock. | ||
713 | if (!Running) | ||
714 | return 0; | ||
715 | |||
709 | lock (m_Script) | 716 | lock (m_Script) |
710 | { | 717 | { |
711 | // m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); | 718 | // m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); |
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 1a9131e..5095037 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | |||
@@ -1118,7 +1118,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine | |||
1118 | } | 1118 | } |
1119 | 1119 | ||
1120 | instance.ClearQueue(); | 1120 | instance.ClearQueue(); |
1121 | instance.Stop(0); | 1121 | |
1122 | // Give the script some time to finish processing its last event. Simply aborting the script thread can | ||
1123 | // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort. | ||
1124 | instance.Stop(1000); | ||
1125 | |||
1122 | // bool objectRemoved = false; | 1126 | // bool objectRemoved = false; |
1123 | 1127 | ||
1124 | lock (m_PrimObjects) | 1128 | lock (m_PrimObjects) |