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.0.7.4.1
parent
d6dd3c42d1
commit
12cebb12d5
|
@ -546,7 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
public bool Stop(int timeout)
|
public bool Stop(int timeout)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[SCRIPT INSTANCE]: Stopping script {0} {1} with timeout {2}", ScriptName, ItemID, timeout);
|
// "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}",
|
||||||
|
// ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks);
|
||||||
|
|
||||||
IScriptWorkItem workItem;
|
IScriptWorkItem workItem;
|
||||||
|
|
||||||
|
@ -575,7 +576,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the current event to complete.
|
// Wait for the current event to complete.
|
||||||
if (workItem.Wait(new TimeSpan((long)timeout * 100000)))
|
if (!m_InSelfDelete && workItem.Wait(new TimeSpan((long)timeout * 100000)))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -592,7 +593,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
// forcibly abort the work item (this aborts the underlying thread).
|
// forcibly abort the work item (this aborts the underlying thread).
|
||||||
if (!m_InSelfDelete)
|
if (!m_InSelfDelete)
|
||||||
{
|
{
|
||||||
// m_log.ErrorFormat("[SCRIPT INSTANCE]: Aborting script {0} {1}", ScriptName, ItemID);
|
// m_log.ErrorFormat(
|
||||||
|
// "[SCRIPT INSTANCE]: Aborting script {0} {1} in prim {2} {3} {4} {5}",
|
||||||
|
// ScriptName, ItemID, PrimName, ObjectID, m_InSelfDelete, DateTime.Now.Ticks);
|
||||||
|
|
||||||
workItem.Abort();
|
workItem.Abort();
|
||||||
}
|
}
|
||||||
|
@ -706,6 +709,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public object EventProcessor()
|
public object EventProcessor()
|
||||||
{
|
{
|
||||||
|
// We check here as the thread stopping this instance from running may itself hold the m_Script lock.
|
||||||
|
if (!Running)
|
||||||
|
return 0;
|
||||||
|
|
||||||
lock (m_Script)
|
lock (m_Script)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
|
// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
|
||||||
|
|
|
@ -1118,7 +1118,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.ClearQueue();
|
instance.ClearQueue();
|
||||||
instance.Stop(0);
|
|
||||||
|
// Give the script some time to finish processing its last event. Simply aborting the script thread can
|
||||||
|
// cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort.
|
||||||
|
instance.Stop(1000);
|
||||||
|
|
||||||
// bool objectRemoved = false;
|
// bool objectRemoved = false;
|
||||||
|
|
||||||
lock (m_PrimObjects)
|
lock (m_PrimObjects)
|
||||||
|
|
Loading…
Reference in New Issue