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,13 +619,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
if (state == State)
|
||||
return;
|
||||
|
||||
// Remove all queued events, remembering the last timer event
|
||||
EventParams lastTimerEv = null;
|
||||
|
||||
lock (EventQueue)
|
||||
{
|
||||
// Remove all queued events, remembering the last timer event
|
||||
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]));
|
||||
|
@ -633,11 +637,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue