Yengine: try fix changing scripts running state if the have long events
parent
3b63699b9d
commit
7f55db72d2
|
@ -1544,6 +1544,29 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
WakeUpOne();
|
||||
}
|
||||
|
||||
public void QueueToYield(XMRInstance inst)
|
||||
{
|
||||
if (inst.m_IState != XMRInstState.ONYIELDQ)
|
||||
throw new Exception("bad state");
|
||||
|
||||
lock (m_YieldQueue)
|
||||
m_YieldQueue.InsertTail(inst);
|
||||
|
||||
WakeUpOne();
|
||||
}
|
||||
|
||||
public void RemoveFromSleep(XMRInstance inst)
|
||||
{
|
||||
lock (m_SleepQueue)
|
||||
{
|
||||
if (inst.m_IState != XMRInstState.ONSLEEPQ)
|
||||
return;
|
||||
|
||||
m_SleepQueue.Remove(inst);
|
||||
inst.m_IState = XMRInstState.REMDFROMSLPQ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A script may be sleeping, in which case we wake it.
|
||||
*/
|
||||
|
|
|
@ -363,8 +363,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
lock(m_QueueLock)
|
||||
{
|
||||
m_Running = value;
|
||||
if(!value)
|
||||
if(value)
|
||||
{
|
||||
if (m_IState == XMRInstState.SUSPENDED && m_SuspendCount == 0)
|
||||
{
|
||||
if(eventCode != ScriptEventCode.None)
|
||||
{
|
||||
m_IState = XMRInstState.ONYIELDQ;
|
||||
m_Engine.QueueToYield(this);
|
||||
}
|
||||
else if ((m_EventQueue != null) && (m_EventQueue.First != null))
|
||||
{
|
||||
m_IState = XMRInstState.ONSTARTQ;
|
||||
m_Engine.QueueToStart(this);
|
||||
}
|
||||
else
|
||||
m_IState = XMRInstState.IDLE;
|
||||
}
|
||||
else if(m_SuspendCount != 0)
|
||||
m_IState = XMRInstState.IDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_IState == XMRInstState.ONSLEEPQ)
|
||||
{
|
||||
m_Engine.RemoveFromSleep(this);
|
||||
m_IState = XMRInstState.SUSPENDED;
|
||||
}
|
||||
EmptyEventQueues();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,8 +82,19 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
// Not running means we ignore any incoming events.
|
||||
// But queue if still constructing because m_Running is not yet valid.
|
||||
|
||||
if(!m_Running && !construct)
|
||||
{
|
||||
if(m_IState == XMRInstState.SUSPENDED)
|
||||
{
|
||||
if(evc == ScriptEventCode.state_entry && m_EventQueue.Count == 0)
|
||||
{
|
||||
LinkedListNode<EventParams> llns = new LinkedListNode<EventParams>(evt);
|
||||
m_EventQueue.AddFirst(llns);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_minEventDelay != 0)
|
||||
{
|
||||
|
@ -256,7 +267,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
m_RunOnePhase = "lock m_RunLock";
|
||||
if(!Monitor.TryEnter(m_RunLock))
|
||||
{
|
||||
m_SleepUntil = now.AddMilliseconds(3);
|
||||
m_SleepUntil = now.AddMilliseconds(15);
|
||||
m_RunOnePhase = "return was locked";
|
||||
return XMRInstState.ONSLEEPQ;
|
||||
}
|
||||
|
@ -273,6 +284,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
return XMRInstState.DISPOSED;
|
||||
}
|
||||
|
||||
if(!m_Running)
|
||||
{
|
||||
m_RunOnePhase = "return is not running";
|
||||
return XMRInstState.SUSPENDED;
|
||||
}
|
||||
|
||||
// Do some more of the last event if it didn't finish.
|
||||
if(this.eventCode != ScriptEventCode.None)
|
||||
{
|
||||
|
@ -325,10 +342,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
if(m_EventQueue.First != null)
|
||||
{
|
||||
evt = m_EventQueue.First.Value;
|
||||
evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt.EventName);
|
||||
if (m_DetachQuantum > 0)
|
||||
{
|
||||
evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
|
||||
evt.EventName);
|
||||
if(evc != ScriptEventCode.attach)
|
||||
{
|
||||
// This is the case where the attach event
|
||||
|
@ -343,8 +359,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
}
|
||||
}
|
||||
m_EventQueue.RemoveFirst();
|
||||
evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
|
||||
evt.EventName);
|
||||
if((int)evc >= 0)
|
||||
m_EventCounts[(int)evc]--;
|
||||
}
|
||||
|
@ -735,6 +749,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
case XMRInstState.RESETTING:
|
||||
return;
|
||||
|
||||
case XMRInstState.SUSPENDED:
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("bad state");
|
||||
}
|
||||
|
@ -745,16 +762,20 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
CheckRunLockInvariants(true);
|
||||
|
||||
// No other thread should have transitioned it from RESETTING.
|
||||
if (m_IState != XMRInstState.SUSPENDED)
|
||||
{
|
||||
if (m_IState != XMRInstState.RESETTING)
|
||||
throw new Exception("bad state");
|
||||
|
||||
// Mark it idle now so it can get queued to process new stuff.
|
||||
m_IState = XMRInstState.IDLE;
|
||||
}
|
||||
|
||||
// Reset everything and queue up default's start_entry() event.
|
||||
ClearQueue();
|
||||
ResetLocked("external Reset");
|
||||
|
||||
// Mark it idle now so it can get queued to process new stuff.
|
||||
|
||||
CheckRunLockInvariants(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,6 +166,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
if(inst == null)
|
||||
break;
|
||||
if (inst.m_IState == XMRInstState.SUSPENDED)
|
||||
continue;
|
||||
if (inst.m_IState != XMRInstState.ONSTARTQ)
|
||||
throw new Exception("bad state");
|
||||
RunInstance(inst, tid);
|
||||
|
@ -187,6 +189,8 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
|||
|
||||
if(inst != null)
|
||||
{
|
||||
if (inst.m_IState == XMRInstState.SUSPENDED)
|
||||
continue;
|
||||
if (inst.m_IState != XMRInstState.ONYIELDQ)
|
||||
throw new Exception("bad state");
|
||||
RunInstance(inst, tid);
|
||||
|
|
Loading…
Reference in New Issue