This GetScriptErrors() change allows initial XEngine to run in background
thread. It should block only for the case of being called by CapsUpdateTaskInventoryScriptAsset().avinationmerge
parent
1636f535ba
commit
68a4f897b4
|
@ -290,7 +290,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_items.LockItemsForWrite(false);
|
m_items.LockItemsForWrite(false);
|
||||||
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
|
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
|
||||||
m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
|
m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
|
||||||
StoreScriptErrors(item.ItemID, GetScriptErrors(item.ItemID));
|
StoreScriptErrors(item.ItemID, null);
|
||||||
m_part.ParentGroup.AddActiveScriptCount(1);
|
m_part.ParentGroup.AddActiveScriptCount(1);
|
||||||
m_part.ScheduleFullUpdate();
|
m_part.ScheduleFullUpdate();
|
||||||
return;
|
return;
|
||||||
|
@ -319,7 +319,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
string script = Utils.BytesToString(asset.Data);
|
string script = Utils.BytesToString(asset.Data);
|
||||||
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
|
m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
|
||||||
m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
|
m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
|
||||||
StoreScriptErrors(item.ItemID, GetScriptErrors(item.ItemID));
|
StoreScriptErrors(item.ItemID, null);
|
||||||
m_part.ParentGroup.AddActiveScriptCount(1);
|
m_part.ParentGroup.AddActiveScriptCount(1);
|
||||||
m_part.ScheduleFullUpdate();
|
m_part.ScheduleFullUpdate();
|
||||||
}
|
}
|
||||||
|
@ -388,11 +388,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start a script which is in this prim's inventory.
|
/// Start a script which is in this prim's inventory.
|
||||||
|
/// Some processing may occur in the background, but this routine returns asap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="itemId">
|
/// <param name="itemId">
|
||||||
/// A <see cref="UUID"/>
|
/// A <see cref="UUID"/>
|
||||||
/// </param>
|
/// </param>
|
||||||
public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
|
public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
|
||||||
|
{
|
||||||
|
lock (m_scriptErrors)
|
||||||
|
{
|
||||||
|
// Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
|
||||||
|
m_scriptErrors.Remove(itemId);
|
||||||
|
}
|
||||||
|
CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
|
||||||
{
|
{
|
||||||
m_items.LockItemsForRead(true);
|
m_items.LockItemsForRead(true);
|
||||||
if (m_items.ContainsKey(itemId))
|
if (m_items.ContainsKey(itemId))
|
||||||
|
@ -425,25 +436,38 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start a script which is in this prim's inventory and return any compilation error messages.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="itemId">
|
||||||
|
/// A <see cref="UUID"/>
|
||||||
|
/// </param>
|
||||||
public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
|
public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
|
||||||
{
|
{
|
||||||
ArrayList errors;
|
ArrayList errors;
|
||||||
|
|
||||||
|
// Indicate to CreateScriptInstanceInternal() we want it to
|
||||||
|
// post any compilation/loading error messages
|
||||||
lock (m_scriptErrors)
|
lock (m_scriptErrors)
|
||||||
{
|
{
|
||||||
m_scriptErrors.Remove(itemId);
|
m_scriptErrors[itemId] = null;
|
||||||
}
|
}
|
||||||
CreateScriptInstance(itemId, startParam, postOnRez, engine, stateSource);
|
|
||||||
|
// Perform compilation/loading
|
||||||
|
CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
|
||||||
|
|
||||||
|
// Wait for and retrieve any errors
|
||||||
lock (m_scriptErrors)
|
lock (m_scriptErrors)
|
||||||
{
|
{
|
||||||
while (!m_scriptErrors.TryGetValue(itemId, out errors))
|
while ((errors = m_scriptErrors[itemId]) == null)
|
||||||
{
|
{
|
||||||
if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
|
if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
|
||||||
{
|
{
|
||||||
m_log.ErrorFormat(
|
m_log.ErrorFormat(
|
||||||
"[PRIM INVENTORY]: " +
|
"[PRIM INVENTORY]: " +
|
||||||
"timedout waiting for script {0} errors", itemId);
|
"timedout waiting for script {0} errors", itemId);
|
||||||
if (!m_scriptErrors.TryGetValue(itemId, out errors))
|
errors = m_scriptErrors[itemId];
|
||||||
|
if (errors == null)
|
||||||
{
|
{
|
||||||
errors = new ArrayList(1);
|
errors = new ArrayList(1);
|
||||||
errors.Add("timedout waiting for errors");
|
errors.Add("timedout waiting for errors");
|
||||||
|
@ -455,14 +479,49 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
return errors;
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Signal to CreateScriptInstanceEr() that compilation/loading is complete
|
||||||
private void StoreScriptErrors(UUID itemId, ArrayList errors)
|
private void StoreScriptErrors(UUID itemId, ArrayList errors)
|
||||||
{
|
{
|
||||||
|
lock (m_scriptErrors)
|
||||||
|
{
|
||||||
|
// If compilation/loading initiated via CreateScriptInstance(),
|
||||||
|
// it does not want the errors, so just get out
|
||||||
|
if (!m_scriptErrors.ContainsKey(itemId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initiated via CreateScriptInstanceEr(), if we know what the
|
||||||
|
// errors are, save them and wake CreateScriptInstanceEr().
|
||||||
|
if (errors != null)
|
||||||
|
{
|
||||||
|
m_scriptErrors[itemId] = errors;
|
||||||
|
System.Threading.Monitor.PulseAll(m_scriptErrors);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initiated via CreateScriptInstanceEr() but we don't know what
|
||||||
|
// the errors are yet, so retrieve them from the script engine.
|
||||||
|
// This may involve some waiting internal to GetScriptErrors().
|
||||||
|
errors = GetScriptErrors(itemId);
|
||||||
|
|
||||||
|
// Get a default non-null value to indicate success.
|
||||||
|
if (errors == null)
|
||||||
|
{
|
||||||
|
errors = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Post to CreateScriptInstanceEr() and wake it up
|
||||||
lock (m_scriptErrors)
|
lock (m_scriptErrors)
|
||||||
{
|
{
|
||||||
m_scriptErrors[itemId] = errors;
|
m_scriptErrors[itemId] = errors;
|
||||||
System.Threading.Monitor.PulseAll(m_scriptErrors);
|
System.Threading.Monitor.PulseAll(m_scriptErrors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Like StoreScriptErrors(), but just posts a single string message
|
||||||
private void StoreScriptError(UUID itemId, string message)
|
private void StoreScriptError(UUID itemId, string message)
|
||||||
{
|
{
|
||||||
ArrayList errors = new ArrayList(1);
|
ArrayList errors = new ArrayList(1);
|
||||||
|
|
Loading…
Reference in New Issue