From b2c893a7be120b7ce04e019856e43523723182d4 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 23 Jan 2013 02:28:27 +0000 Subject: [PATCH] If ScriptStopStrategy hasn't been set to co-op in [XEngine] config, then continue to generate C# that is functionality identical to historical generation This is to eliminate disruption until co-op termination has been well-tested. In non co-op mode, XEngine will continue to load DLLs of the existing Script class and the new XEngineScript class. Moving to co-op mode still requires existing script DLL deletion to force recompilation, either manually or by setting DeleteScriptsOnStartup = true for one run. This change also means that scripts which fail to initialize do not still show up as running scripts. --- .../ScriptEngine/Interfaces/IScriptEngine.cs | 8 ++++ .../ScriptEngine/Shared/CodeTools/Compiler.cs | 30 +++++++----- .../Shared/Instance/ScriptInstance.cs | 48 +++++++++++++++---- .../Instance/Tests/CoopTerminationTests.cs | 2 +- .../Region/ScriptEngine/XEngine/XEngine.cs | 26 +++++++--- prebuild.xml | 1 + 6 files changed, 88 insertions(+), 27 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs index 20dcac9855..b8fdd01d37 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs @@ -78,6 +78,14 @@ namespace OpenSim.Region.ScriptEngine.Interfaces string ScriptEngineName { get; } string ScriptEnginePath { get; } + /// + /// Return the name of the class that will be used for all running scripts. + /// + /// + /// Each class goes in its own assembly so we don't need to otherwise distinguish the class name. + /// + string ScriptClassName { get; } + /// /// Return the name of the base class that will be used for all running scripts. /// diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 8f6055624b..6e7e7c152a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -416,16 +416,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools case enumCompileType.cs: case enumCompileType.lsl: compileScript = CreateCSCompilerScript( - compileScript, m_scriptEngine.ScriptBaseClassName, m_scriptEngine.ScriptBaseClassParameters); + compileScript, + m_scriptEngine.ScriptClassName, + m_scriptEngine.ScriptBaseClassName, + m_scriptEngine.ScriptBaseClassParameters); break; case enumCompileType.vb: - compileScript = CreateVBCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); + compileScript = CreateVBCompilerScript( + compileScript, m_scriptEngine.ScriptClassName, m_scriptEngine.ScriptBaseClassName); break; // case enumCompileType.js: // compileScript = CreateJSCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); // break; case enumCompileType.yp: - compileScript = CreateYPCompilerScript(compileScript, m_scriptEngine.ScriptBaseClassName); + compileScript = CreateYPCompilerScript( + compileScript, m_scriptEngine.ScriptClassName,m_scriptEngine.ScriptBaseClassName); break; } @@ -457,7 +462,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // } private static string CreateCSCompilerScript( - string compileScript, string baseClassName, ParameterInfo[] constructorParameters) + string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters) { compileScript = string.Format( @"using OpenSim.Region.ScriptEngine.Shared; @@ -465,12 +470,13 @@ using System.Collections.Generic; namespace SecondLife {{ - public class Script : {0} + public class {0} : {1} {{ - public Script({1}) : base({2}) {{}} -{3} + public {0}({2}) : base({3}) {{}} +{4} }} }}", + className, baseClassName, constructorParameters != null ? string.Join(", ", Array.ConvertAll(constructorParameters, pi => pi.ToString())) @@ -483,28 +489,28 @@ namespace SecondLife return compileScript; } - private static string CreateYPCompilerScript(string compileScript, string baseClassName) + private static string CreateYPCompilerScript(string compileScript, string className, string baseClassName) { compileScript = String.Empty + "using OpenSim.Region.ScriptEngine.Shared.YieldProlog; " + "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\r\n" + String.Empty + "namespace SecondLife { " + - String.Empty + "public class Script : " + baseClassName + " { \r\n" + + String.Empty + "public class " + className + " : " + baseClassName + " { \r\n" + //@"public Script() { } " + @"static OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP YP=null; " + - @"public Script() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + + @"public " + className + "() { YP= new OpenSim.Region.ScriptEngine.Shared.YieldProlog.YP(); } " + compileScript + "} }\r\n"; return compileScript; } - private static string CreateVBCompilerScript(string compileScript, string baseClassName) + private static string CreateVBCompilerScript(string compileScript, string className, string baseClassName) { compileScript = String.Empty + "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + String.Empty + "NameSpace SecondLife:" + - String.Empty + "Public Class Script: Inherits " + baseClassName + + String.Empty + "Public Class " + className + ": Inherits " + baseClassName + "\r\nPublic Sub New()\r\nEnd Sub: " + compileScript + ":End Class :End Namespace\r\n"; diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index e6ec0e1867..4cfcb750a5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -251,7 +251,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance /// /// /// - public void Load(AppDomain dom, string assembly, StateSource stateSource) + /// false if load failed, true if suceeded + public bool Load(AppDomain dom, string assembly, StateSource stateSource) { m_Assembly = assembly; m_stateSource = stateSource; @@ -266,26 +267,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance try { + object[] constructorParams; + + Assembly scriptAssembly = dom.Load(Path.GetFileNameWithoutExtension(assembly)); + Type scriptType = scriptAssembly.GetType("SecondLife.XEngineScript"); + + if (scriptType != null) + { + constructorParams = new object[] { m_coopSleepHandle }; + } + else if (!m_coopTermination) + { + scriptType = scriptAssembly.GetType("SecondLife.Script"); + constructorParams = null; + } + else + { + m_log.ErrorFormat( + "[SCRIPT INSTANCE]: You must remove all existing script DLLs before using enabling co-op termination" + + ", either by setting DeleteScriptsOnStartup = true in [XEngine] for one run" + + " or by deleting all *.dll* files in the relevant bin/ScriptEngines// directory"); + + return false; + } + +// m_log.DebugFormat( +// "[SCRIPT INSTANCE]: Looking to load {0} from assembly {1} in {2}", +// scriptType.FullName, Path.GetFileNameWithoutExtension(assembly), Engine.World.Name); + if (dom != System.AppDomain.CurrentDomain) m_Script = (IScript)dom.CreateInstanceAndUnwrap( Path.GetFileNameWithoutExtension(assembly), - "SecondLife.Script", + scriptType.FullName, false, BindingFlags.Default, null, - new object[] { m_coopSleepHandle }, - null, + constructorParams, null, null); else m_Script - = (IScript)Assembly.Load(Path.GetFileNameWithoutExtension(assembly)).CreateInstance( - "SecondLife.Script", + = (IScript)scriptAssembly.CreateInstance( + scriptType.FullName, false, BindingFlags.Default, null, - new object[] { m_coopSleepHandle }, + constructorParams, null, null); @@ -298,6 +326,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance m_log.ErrorFormat( "[SCRIPT INSTANCE]: Error loading assembly {0}. Exception {1}{2}", assembly, e.Message, e.StackTrace); + + return false; } try @@ -318,7 +348,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance "[SCRIPT INSTANCE]: Error loading script instance from assembly {0}. Exception {1}{2}", assembly, e.Message, e.StackTrace); - return; + return false; } m_SaveState = true; @@ -390,6 +420,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance // presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); // } + + return true; } public void Init() diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs index bd882f9dec..52d75a0d31 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/Tests/CoopTerminationTests.cs @@ -245,7 +245,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance.Tests public void TestStopOnInfiniteJumpLoop() { TestHelpers.InMethod(); -// TestHelpers.EnableLogging(); + TestHelpers.EnableLogging(); string script = @"default diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index a1e54187f0..e860889cc5 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -46,13 +46,14 @@ using OpenSim.Framework; using OpenSim.Framework.Console; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Region.ScriptEngine.Shared.CodeTools; using OpenSim.Region.ScriptEngine.Shared.Instance; using OpenSim.Region.ScriptEngine.Shared.Api; using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; -using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Region.ScriptEngine.XEngine.ScriptBase; using Timer = OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; @@ -177,6 +178,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine get { return "XEngine"; } } + public string ScriptClassName { get; private set; } + public string ScriptBaseClassName { get; private set; } public ParameterInfo[] ScriptBaseClassParameters { get; private set; } @@ -238,9 +241,18 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_ScriptConfig = configSource.Configs["XEngine"]; m_ConfigSource = configSource; - ScriptBaseClassName = typeof(XEngineScriptBase).FullName; - ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters(); - ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) }; + if (m_ScriptConfig.GetString("ScriptStopStrategy", "abort") == "co-op") + { + ScriptClassName = "XEngineScript"; + ScriptBaseClassName = typeof(XEngineScriptBase).FullName; + ScriptBaseClassParameters = typeof(XEngineScriptBase).GetConstructor(new Type[] { typeof(WaitHandle) }).GetParameters(); + ScriptReferencedAssemblies = new string[] { Path.GetFileName(typeof(XEngineScriptBase).Assembly.Location) }; + } + else + { + ScriptClassName = "Script"; + ScriptBaseClassName = typeof(ScriptBaseClass).FullName; + } // Console.WriteLine("ASSEMBLY NAME: {0}", ScriptReferencedAssemblies[0]); } @@ -1122,7 +1134,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine } m_log.DebugFormat( - "[XEngine] Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", + "[XEngine]: Loading script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); @@ -1143,6 +1155,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine lock (m_AddingAssemblies) { m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap); + if (!m_AddingAssemblies.ContainsKey(assembly)) { m_AddingAssemblies[assembly] = 1; } else { @@ -1303,7 +1316,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine startParam, postOnRez, m_MaxScriptQueue); - instance.Load(m_AppDomains[appDomain], assembly, stateSource); + if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) + return false; // if (DebugLevel >= 1) // m_log.DebugFormat( diff --git a/prebuild.xml b/prebuild.xml index 935c857b82..1f2789c15e 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -2442,6 +2442,7 @@ +