Lock around EventQueue manipulation in ScriptInstance.SetState() as queues are not thread-safe structures.
This should also make it less likely that an event will be erroneously posted during a state change by precluding a race condition with a thread calling ScriptInstance.PostEvent()inv-download
parent
b4b13510e8
commit
7410924de0
|
@ -619,25 +619,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
if (state == State)
|
if (state == State)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Remove all queued events, remembering the last timer event
|
|
||||||
EventParams lastTimerEv = null;
|
EventParams lastTimerEv = null;
|
||||||
while (EventQueue.Count > 0)
|
|
||||||
|
lock (EventQueue)
|
||||||
{
|
{
|
||||||
EventParams tempv = (EventParams)EventQueue.Dequeue();
|
// Remove all queued events, remembering the last timer event
|
||||||
if (tempv.EventName == "timer") lastTimerEv = tempv;
|
while (EventQueue.Count > 0)
|
||||||
|
{
|
||||||
|
EventParams tempv = (EventParams)EventQueue.Dequeue();
|
||||||
|
if (tempv.EventName == "timer") lastTimerEv = tempv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post events
|
||||||
|
PostEvent(new EventParams("state_exit", new Object[0],
|
||||||
|
new DetectParams[0]));
|
||||||
|
PostEvent(new EventParams("state", new Object[] { state },
|
||||||
|
new DetectParams[0]));
|
||||||
|
PostEvent(new EventParams("state_entry", new Object[0],
|
||||||
|
new DetectParams[0]));
|
||||||
|
|
||||||
|
// Requeue the timer event after the state changing events
|
||||||
|
if (lastTimerEv != null) EventQueue.Enqueue(lastTimerEv);
|
||||||
|
|
||||||
|
// This will stop events from being queued and processed
|
||||||
|
// until the new state is started
|
||||||
|
m_StateChangeInProgress = true;
|
||||||
}
|
}
|
||||||
// Post events
|
|
||||||
PostEvent(new EventParams("state_exit", new Object[0],
|
|
||||||
new DetectParams[0]));
|
|
||||||
PostEvent(new EventParams("state", new Object[] { state },
|
|
||||||
new DetectParams[0]));
|
|
||||||
PostEvent(new EventParams("state_entry", new Object[0],
|
|
||||||
new DetectParams[0]));
|
|
||||||
// Requeue the timer event after the state changing events
|
|
||||||
if (lastTimerEv != null) EventQueue.Enqueue(lastTimerEv);
|
|
||||||
// This will stop events from being queued and processed
|
|
||||||
// until the new state is started
|
|
||||||
m_StateChangeInProgress = true;
|
|
||||||
|
|
||||||
throw new EventAbortException();
|
throw new EventAbortException();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue