Remove parallel loading from XEngine, but retain the new design where

all scripts are loaded from the same thread, rather than launching a
new one for each script. This is only marginally slower, but avoids the
race condition that led to script engine failure.
0.6.8-post-fixes
Melanie 2009-11-03 20:23:50 +00:00
parent 865d3f4b09
commit 00130841db
1 changed files with 19 additions and 8 deletions

View File

@ -51,7 +51,6 @@ using OpenSim.Region.ScriptEngine.Shared.Instance;
using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Interfaces;
using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>; using ScriptCompileQueue = OpenSim.Framework.LocklessQueue<object[]>;
using Parallel = OpenSim.Framework.Parallel;
namespace OpenSim.Region.ScriptEngine.XEngine namespace OpenSim.Region.ScriptEngine.XEngine
{ {
@ -494,7 +493,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine
if (m_CurrentCompile == null) if (m_CurrentCompile == null)
{ {
m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null); // NOTE: Although we use a lockless queue, the lock here
// is required. It ensures that there are never two
// compile threads running, which, due to a race
// conndition, might otherwise happen
//
lock (m_CompileQueue)
{
if (m_CurrentCompile == null)
m_CurrentCompile = m_ThreadPool.QueueWorkItem(DoOnRezScriptQueue, null);
}
} }
} }
} }
@ -514,16 +522,19 @@ namespace OpenSim.Region.ScriptEngine.XEngine
} }
} }
List<object[]> compiles = new List<object[]>();
object[] o; object[] o;
while (m_CompileQueue.Dequeue(out o)) while (m_CompileQueue.Dequeue(out o))
DoOnRezScript(o);
// NOTE: Despite having a lockless queue, this lock is required
// to make sure there is never no compile thread while there
// are still scripts to compile. This could otherwise happen
// due to a race condition
//
lock (m_CompileQueue)
{ {
compiles.Add(o); m_CurrentCompile = null;
} }
Parallel.For(0, compiles.Count, delegate(int i) { DoOnRezScript(compiles[i]); });
m_CurrentCompile = null;
m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount, m_Scene.EventManager.TriggerEmptyScriptCompileQueue(m_ScriptFailCount,
m_ScriptErrorMessage); m_ScriptErrorMessage);
m_ScriptFailCount = 0; m_ScriptFailCount = 0;