Yengine: try fix changing scripts running state if the have long events
parent
3b63699b9d
commit
7f55db72d2
|
@ -1535,15 +1535,38 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
*/
|
*/
|
||||||
public void QueueToStart(XMRInstance inst)
|
public void QueueToStart(XMRInstance inst)
|
||||||
{
|
{
|
||||||
if(inst.m_IState != XMRInstState.ONSTARTQ)
|
if (inst.m_IState != XMRInstState.ONSTARTQ)
|
||||||
throw new Exception("bad state");
|
throw new Exception("bad state");
|
||||||
|
|
||||||
lock(m_StartQueue)
|
lock (m_StartQueue)
|
||||||
m_StartQueue.InsertTail(inst);
|
m_StartQueue.InsertTail(inst);
|
||||||
|
|
||||||
WakeUpOne();
|
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.
|
* @brief A script may be sleeping, in which case we wake it.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -363,8 +363,33 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
lock(m_QueueLock)
|
lock(m_QueueLock)
|
||||||
{
|
{
|
||||||
m_Running = value;
|
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();
|
EmptyEventQueues();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,10 +80,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
!m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state
|
!m_HaveEventHandlers[(int)evc]) // don't bother if we don't have such a handler in any state
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Not running means we ignore any incoming events.
|
// Not running means we ignore any incoming events.
|
||||||
// But queue if still constructing because m_Running is not yet valid.
|
// But queue if still constructing because m_Running is not yet valid.
|
||||||
|
|
||||||
if(!m_Running && !construct)
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(m_minEventDelay != 0)
|
if(m_minEventDelay != 0)
|
||||||
{
|
{
|
||||||
|
@ -250,13 +261,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
return XMRInstState.SUSPENDED;
|
return XMRInstState.SUSPENDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we aren't being migrated in or out and prevent that
|
// Make sure we aren't being migrated in or out and prevent that
|
||||||
// whilst we are in here. If migration has it locked, don't call
|
// whilst we are in here. If migration has it locked, don't call
|
||||||
// back right away, delay a bit so we don't get in infinite loop.
|
// back right away, delay a bit so we don't get in infinite loop.
|
||||||
m_RunOnePhase = "lock m_RunLock";
|
m_RunOnePhase = "lock m_RunLock";
|
||||||
if(!Monitor.TryEnter(m_RunLock))
|
if(!Monitor.TryEnter(m_RunLock))
|
||||||
{
|
{
|
||||||
m_SleepUntil = now.AddMilliseconds(3);
|
m_SleepUntil = now.AddMilliseconds(15);
|
||||||
m_RunOnePhase = "return was locked";
|
m_RunOnePhase = "return was locked";
|
||||||
return XMRInstState.ONSLEEPQ;
|
return XMRInstState.ONSLEEPQ;
|
||||||
}
|
}
|
||||||
|
@ -273,6 +284,12 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
return XMRInstState.DISPOSED;
|
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.
|
// Do some more of the last event if it didn't finish.
|
||||||
if(this.eventCode != ScriptEventCode.None)
|
if(this.eventCode != ScriptEventCode.None)
|
||||||
{
|
{
|
||||||
|
@ -325,10 +342,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
if(m_EventQueue.First != null)
|
if(m_EventQueue.First != null)
|
||||||
{
|
{
|
||||||
evt = m_EventQueue.First.Value;
|
evt = m_EventQueue.First.Value;
|
||||||
if(m_DetachQuantum > 0)
|
evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt.EventName);
|
||||||
|
if (m_DetachQuantum > 0)
|
||||||
{
|
{
|
||||||
evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
|
|
||||||
evt.EventName);
|
|
||||||
if(evc != ScriptEventCode.attach)
|
if(evc != ScriptEventCode.attach)
|
||||||
{
|
{
|
||||||
// This is the case where the attach event
|
// This is the case where the attach event
|
||||||
|
@ -343,8 +359,6 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_EventQueue.RemoveFirst();
|
m_EventQueue.RemoveFirst();
|
||||||
evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode),
|
|
||||||
evt.EventName);
|
|
||||||
if((int)evc >= 0)
|
if((int)evc >= 0)
|
||||||
m_EventCounts[(int)evc]--;
|
m_EventCounts[(int)evc]--;
|
||||||
}
|
}
|
||||||
|
@ -730,11 +744,14 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
case XMRInstState.DISPOSED:
|
case XMRInstState.DISPOSED:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Some other thread is already resetting it, let it finish.
|
// Some other thread is already resetting it, let it finish.
|
||||||
|
|
||||||
case XMRInstState.RESETTING:
|
case XMRInstState.RESETTING:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case XMRInstState.SUSPENDED:
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Exception("bad state");
|
throw new Exception("bad state");
|
||||||
}
|
}
|
||||||
|
@ -744,17 +761,21 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
{
|
{
|
||||||
CheckRunLockInvariants(true);
|
CheckRunLockInvariants(true);
|
||||||
|
|
||||||
// No other thread should have transitioned it from RESETTING.
|
// No other thread should have transitioned it from RESETTING.
|
||||||
if(m_IState != XMRInstState.RESETTING)
|
if (m_IState != XMRInstState.SUSPENDED)
|
||||||
throw new Exception("bad state");
|
{
|
||||||
|
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;
|
||||||
m_IState = XMRInstState.IDLE;
|
}
|
||||||
|
|
||||||
// Reset everything and queue up default's start_entry() event.
|
// Reset everything and queue up default's start_entry() event.
|
||||||
ClearQueue();
|
ClearQueue();
|
||||||
ResetLocked("external Reset");
|
ResetLocked("external Reset");
|
||||||
|
|
||||||
|
// Mark it idle now so it can get queued to process new stuff.
|
||||||
|
|
||||||
CheckRunLockInvariants(true);
|
CheckRunLockInvariants(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,7 +166,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
|
|
||||||
if(inst == null)
|
if(inst == null)
|
||||||
break;
|
break;
|
||||||
if(inst.m_IState != XMRInstState.ONSTARTQ)
|
if (inst.m_IState == XMRInstState.SUSPENDED)
|
||||||
|
continue;
|
||||||
|
if (inst.m_IState != XMRInstState.ONSTARTQ)
|
||||||
throw new Exception("bad state");
|
throw new Exception("bad state");
|
||||||
RunInstance(inst, tid);
|
RunInstance(inst, tid);
|
||||||
if(m_SuspendScriptThreadFlag || m_Exiting)
|
if(m_SuspendScriptThreadFlag || m_Exiting)
|
||||||
|
@ -187,7 +189,9 @@ namespace OpenSim.Region.ScriptEngine.Yengine
|
||||||
|
|
||||||
if(inst != null)
|
if(inst != null)
|
||||||
{
|
{
|
||||||
if(inst.m_IState != XMRInstState.ONYIELDQ)
|
if (inst.m_IState == XMRInstState.SUSPENDED)
|
||||||
|
continue;
|
||||||
|
if (inst.m_IState != XMRInstState.ONYIELDQ)
|
||||||
throw new Exception("bad state");
|
throw new Exception("bad state");
|
||||||
RunInstance(inst, tid);
|
RunInstance(inst, tid);
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in New Issue