From: Christopher Yeoh <yeohc@au1.ibm.com>
This changeset fixes a race condition where a script (XEngine run) can startup before a reference is added to it in all of the required places in the XEngine class. The effect of this is that a script can sometimes on startup miss script events. For example a script which starts up and initialises itself from a notecard may never receive the dataserver event containing the notecard information. The patch isn't as clean as I'd like - I've split the constructor of ScriptInstance up so it does everything it did before except call Startup and post events like state_entry and on_rez. An Init function has been added which is called after the ScriptInstance object has been added to the necessary data structures in XEngine. Happy to rework it if someone suggests a better way of doing it.0.6.3-post-fixes
parent
a3ac702941
commit
ce1e1854b1
|
@ -73,6 +73,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
|
||||||
|
|
||||||
void RemoveState();
|
void RemoveState();
|
||||||
|
|
||||||
|
void Init();
|
||||||
void Start();
|
void Start();
|
||||||
bool Stop(int timeout);
|
bool Stop(int timeout);
|
||||||
void SetState(string state);
|
void SetState(string state);
|
||||||
|
|
|
@ -88,6 +88,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
private double m_minEventDelay = 0;
|
private double m_minEventDelay = 0;
|
||||||
private long m_eventDelayTicks = 0;
|
private long m_eventDelayTicks = 0;
|
||||||
private long m_nextEventTimeTicks = 0;
|
private long m_nextEventTimeTicks = 0;
|
||||||
|
private bool m_startOnInit = true;
|
||||||
|
private StateSource m_stateSource;
|
||||||
|
private bool m_postOnRez;
|
||||||
|
private bool m_startedFromSavedState = false;
|
||||||
|
|
||||||
//private ISponsor m_ScriptSponsor;
|
//private ISponsor m_ScriptSponsor;
|
||||||
private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
|
private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
|
||||||
|
@ -224,6 +228,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
m_Assembly = assembly;
|
m_Assembly = assembly;
|
||||||
m_StartParam = startParam;
|
m_StartParam = startParam;
|
||||||
m_MaxScriptQueue = maxScriptQueue;
|
m_MaxScriptQueue = maxScriptQueue;
|
||||||
|
m_stateSource = stateSource;
|
||||||
|
m_postOnRez = postOnRez;
|
||||||
|
|
||||||
if (part != null && part.TaskInventory.ContainsKey(m_ItemID))
|
if (part != null && part.TaskInventory.ContainsKey(m_ItemID))
|
||||||
{
|
{
|
||||||
|
@ -313,10 +319,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
if (m_RunEvents && (!m_ShuttingDown))
|
if (m_RunEvents && (!m_ShuttingDown))
|
||||||
{
|
{
|
||||||
m_RunEvents = false;
|
m_RunEvents = false;
|
||||||
Start();
|
}
|
||||||
if (postOnRez)
|
else
|
||||||
PostEvent(new EventParams("on_rez",
|
{
|
||||||
new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0]));
|
m_RunEvents = false;
|
||||||
|
m_startOnInit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we get new rez events on sim restart, too
|
// we get new rez events on sim restart, too
|
||||||
|
@ -325,42 +332,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
|
|
||||||
// We loaded state, don't force a re-save
|
// We loaded state, don't force a re-save
|
||||||
m_SaveState = false;
|
m_SaveState = false;
|
||||||
|
m_startedFromSavedState = true;
|
||||||
|
|
||||||
if (stateSource == StateSource.NewRez)
|
|
||||||
{
|
|
||||||
// m_Engine.Log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script");
|
|
||||||
PostEvent(new EventParams("changed",
|
|
||||||
new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0]));
|
|
||||||
}
|
|
||||||
else if (stateSource == StateSource.PrimCrossing)
|
|
||||||
{
|
|
||||||
// CHANGED_REGION
|
|
||||||
PostEvent(new EventParams("changed",
|
|
||||||
new Object[] {new LSL_Types.LSLInteger(512)}, new DetectParams[0]));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_Engine.Log.Error("[Script] Unable to load script state: Memory limit exceeded");
|
m_Engine.Log.Error("[Script] Unable to load script state: Memory limit exceeded");
|
||||||
Start();
|
|
||||||
PostEvent(new EventParams("state_entry",
|
|
||||||
new Object[0], new DetectParams[0]));
|
|
||||||
if (postOnRez)
|
|
||||||
PostEvent(new EventParams("on_rez",
|
|
||||||
new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0]));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_Engine.Log.ErrorFormat("[Script] Unable to load script state from xml: {0}\n"+e.ToString(), xml);
|
m_Engine.Log.ErrorFormat("[Script] Unable to load script state from xml: {0}\n"+e.ToString(), xml);
|
||||||
Start();
|
|
||||||
PostEvent(new EventParams("state_entry",
|
|
||||||
new Object[0], new DetectParams[0]));
|
|
||||||
if (postOnRez)
|
|
||||||
PostEvent(new EventParams("on_rez",
|
|
||||||
new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -371,13 +354,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
presence.ControllingClient.SendAgentAlertMessage("Compile successful", false);
|
presence.ControllingClient.SendAgentAlertMessage("Compile successful", false);
|
||||||
|
|
||||||
// m_Engine.Log.ErrorFormat("[Script] Unable to load script state, file not found");
|
// m_Engine.Log.ErrorFormat("[Script] Unable to load script state, file not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Init()
|
||||||
|
{
|
||||||
|
if (!m_startOnInit) return;
|
||||||
|
|
||||||
|
if (m_startedFromSavedState)
|
||||||
|
{
|
||||||
|
Start();
|
||||||
|
if (m_postOnRez)
|
||||||
|
{
|
||||||
|
PostEvent(new EventParams("on_rez",
|
||||||
|
new Object[] {new LSL_Types.LSLInteger(m_StartParam)}, new DetectParams[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_stateSource == StateSource.NewRez)
|
||||||
|
{
|
||||||
|
// m_Engine.Log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script");
|
||||||
|
PostEvent(new EventParams("changed",
|
||||||
|
new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0]));
|
||||||
|
}
|
||||||
|
else if (m_stateSource == StateSource.PrimCrossing)
|
||||||
|
{
|
||||||
|
// CHANGED_REGION
|
||||||
|
PostEvent(new EventParams("changed",
|
||||||
|
new Object[] {new LSL_Types.LSLInteger(512)}, new DetectParams[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Start();
|
Start();
|
||||||
PostEvent(new EventParams("state_entry",
|
PostEvent(new EventParams("state_entry",
|
||||||
new Object[0], new DetectParams[0]));
|
new Object[0], new DetectParams[0]));
|
||||||
|
if (m_postOnRez)
|
||||||
if (postOnRez)
|
{
|
||||||
PostEvent(new EventParams("on_rez",
|
PostEvent(new EventParams("on_rez",
|
||||||
new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0]));
|
new Object[] {new LSL_Types.LSLInteger(m_StartParam)}, new DetectParams[0]));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -544,6 +544,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
|
|
||||||
lock (m_Scripts)
|
lock (m_Scripts)
|
||||||
{
|
{
|
||||||
|
ScriptInstance instance = null;
|
||||||
// Create the object record
|
// Create the object record
|
||||||
|
|
||||||
if ((!m_Scripts.ContainsKey(itemID)) ||
|
if ((!m_Scripts.ContainsKey(itemID)) ||
|
||||||
|
@ -596,14 +597,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
}
|
}
|
||||||
m_DomainScripts[appDomain].Add(itemID);
|
m_DomainScripts[appDomain].Add(itemID);
|
||||||
|
|
||||||
ScriptInstance instance =
|
instance = new ScriptInstance(this, part,
|
||||||
new ScriptInstance(this, part,
|
itemID, assetID, assembly,
|
||||||
itemID, assetID, assembly,
|
m_AppDomains[appDomain],
|
||||||
m_AppDomains[appDomain],
|
part.ParentGroup.RootPart.Name,
|
||||||
part.ParentGroup.RootPart.Name,
|
item.Name, startParam, postOnRez,
|
||||||
item.Name, startParam, postOnRez,
|
stateSource, m_MaxScriptQueue);
|
||||||
stateSource, m_MaxScriptQueue);
|
|
||||||
|
|
||||||
m_log.DebugFormat("[XEngine] Loaded script {0}.{1}",
|
m_log.DebugFormat("[XEngine] Loaded script {0}.{1}",
|
||||||
part.ParentGroup.RootPart.Name, item.Name);
|
part.ParentGroup.RootPart.Name, item.Name);
|
||||||
|
|
||||||
|
@ -625,6 +625,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
|
|
||||||
if (!m_Assemblies.ContainsKey(assetID))
|
if (!m_Assemblies.ContainsKey(assetID))
|
||||||
m_Assemblies[assetID] = assembly;
|
m_Assemblies[assetID] = assembly;
|
||||||
|
|
||||||
|
if (instance!=null)
|
||||||
|
instance.Init();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue